blob: ec8c526c0aac96469fb0acb62ace1a7fae192923 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040099#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200116#ifdef __hpux
117#include <sys/mpctl.h>
118#endif
119
120#if defined(__DragonFly__) || \
121 defined(__OpenBSD__) || \
122 defined(__FreeBSD__) || \
123 defined(__NetBSD__) || \
124 defined(__APPLE__)
125#include <sys/sysctl.h>
126#endif
127
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100128#if defined(MS_WINDOWS)
129# define TERMSIZE_USE_CONIO
130#elif defined(HAVE_SYS_IOCTL_H)
131# include <sys/ioctl.h>
132# if defined(HAVE_TERMIOS_H)
133# include <termios.h>
134# endif
135# if defined(TIOCGWINSZ)
136# define TERMSIZE_USE_IOCTL
137# endif
138#endif /* MS_WINDOWS */
139
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000141/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#include <process.h>
146#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000147#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000148#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000149#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_EXECV 1
152#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_SYSTEM 1
154#define HAVE_CWAIT 1
155#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000156#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000157#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158/* Unix functions that the configure script doesn't check for */
159#define HAVE_EXECV 1
160#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000162#define HAVE_FORK1 1
163#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#define HAVE_GETEGID 1
165#define HAVE_GETEUID 1
166#define HAVE_GETGID 1
167#define HAVE_GETPPID 1
168#define HAVE_GETUID 1
169#define HAVE_KILL 1
170#define HAVE_OPENDIR 1
171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000177
Victor Stinnera2f7c002012-02-08 03:36:25 +0100178
Larry Hastings61272b72014-01-07 12:41:53 -0800179/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000180# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800181module os
Larry Hastings61272b72014-01-07 12:41:53 -0800182[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000183/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000187#if defined(__sgi)&&_COMPILER_VERSION>=700
188/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
189 (default) */
190extern char *ctermid_r(char *);
191#endif
192
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000193#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#endif
203#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(char *);
205extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int chdir(const char *);
208extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000211/*#ifdef HAVE_FCHMOD
212extern int fchmod(int, mode_t);
213#endif*/
214/*#ifdef HAVE_LCHMOD
215extern int lchmod(const char *, mode_t);
216#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chown(const char *, uid_t, gid_t);
218extern char *getcwd(char *, int);
219extern char *strerror(int);
220extern int link(const char *, const char *);
221extern int rename(const char *, const char *);
222extern int stat(const char *, struct stat *);
223extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000226#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#ifdef HAVE_UTIME_H
235#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000238#ifdef HAVE_SYS_UTIME_H
239#include <sys/utime.h>
240#define HAVE_UTIME_H /* pretend we do for the rest of this file */
241#endif /* HAVE_SYS_UTIME_H */
242
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_SYS_TIMES_H
244#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
247#ifdef HAVE_SYS_PARAM_H
248#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
251#ifdef HAVE_SYS_UTSNAME_H
252#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#define NAMLEN(dirent) strlen((dirent)->d_name)
258#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000259#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#include <direct.h>
261#define NAMLEN(dirent) strlen((dirent)->d_name)
262#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000265#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#endif
269#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#endif
272#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#endif
275#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000278#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280#endif
281#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000283#endif
284#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000287#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000288#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000289#endif
290#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000291#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000292#endif
293#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000294#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100296#ifndef IO_REPARSE_TAG_MOUNT_POINT
297#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
298#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000299#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000300#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000302#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000303#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000304#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
305#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000306static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000307#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000308#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311#if defined(PATH_MAX) && PATH_MAX > 1024
312#define MAXPATHLEN PATH_MAX
313#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#endif /* MAXPATHLEN */
317
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000318#ifdef UNION_WAIT
319/* Emulate some macros on systems that have a union instead of macros */
320
321#ifndef WIFEXITED
322#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
323#endif
324
325#ifndef WEXITSTATUS
326#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
327#endif
328
329#ifndef WTERMSIG
330#define WTERMSIG(u_wait) ((u_wait).w_termsig)
331#endif
332
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333#define WAIT_TYPE union wait
334#define WAIT_STATUS_INT(s) (s.w_status)
335
336#else /* !UNION_WAIT */
337#define WAIT_TYPE int
338#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000339#endif /* UNION_WAIT */
340
Greg Wardb48bc172000-03-01 21:51:56 +0000341/* Don't use the "_r" form if we don't need it (also, won't have a
342 prototype for it, at least on Solaris -- maybe others as well?). */
343#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
344#define USE_CTERMID_R
345#endif
346
Fred Drake699f3522000-06-29 21:12:41 +0000347/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000348#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000349#undef FSTAT
350#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200351#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000352# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700353# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200354# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800355# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000356#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT fstat
360# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#endif
362
Tim Peters11b23062003-04-23 02:39:17 +0000363#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#include <sys/mkdev.h>
365#else
366#if defined(MAJOR_IN_SYSMACROS)
367#include <sys/sysmacros.h>
368#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000369#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
370#include <sys/mkdev.h>
371#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#endif
Fred Drake699f3522000-06-29 21:12:41 +0000373
Victor Stinner6edddfa2013-11-24 19:22:57 +0100374#define DWORD_MAX 4294967295U
375
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200376#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100377#define INITFUNC PyInit_nt
378#define MODNAME "nt"
379#else
380#define INITFUNC PyInit_posix
381#define MODNAME "posix"
382#endif
383
384#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200385/* defined in fileutils.c */
386PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
387PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
388 ULONG, struct _Py_stat_struct *);
389#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390
391#ifdef MS_WINDOWS
392static int
393win32_warn_bytes_api()
394{
395 return PyErr_WarnEx(PyExc_DeprecationWarning,
396 "The Windows bytes API has been deprecated, "
397 "use Unicode filenames instead",
398 1);
399}
400#endif
401
402
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200403#ifndef MS_WINDOWS
404PyObject *
405_PyLong_FromUid(uid_t uid)
406{
407 if (uid == (uid_t)-1)
408 return PyLong_FromLong(-1);
409 return PyLong_FromUnsignedLong(uid);
410}
411
412PyObject *
413_PyLong_FromGid(gid_t gid)
414{
415 if (gid == (gid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(gid);
418}
419
420int
421_Py_Uid_Converter(PyObject *obj, void *p)
422{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700423 uid_t uid;
424 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200425 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200426 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427 unsigned long uresult;
428
429 index = PyNumber_Index(obj);
430 if (index == NULL) {
431 PyErr_Format(PyExc_TypeError,
432 "uid should be integer, not %.200s",
433 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 return 0;
435 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700436
437 /*
438 * Handling uid_t is complicated for two reasons:
439 * * Although uid_t is (always?) unsigned, it still
440 * accepts -1.
441 * * We don't know its size in advance--it may be
442 * bigger than an int, or it may be smaller than
443 * a long.
444 *
445 * So a bit of defensive programming is in order.
446 * Start with interpreting the value passed
447 * in as a signed long and see if it works.
448 */
449
450 result = PyLong_AsLongAndOverflow(index, &overflow);
451
452 if (!overflow) {
453 uid = (uid_t)result;
454
455 if (result == -1) {
456 if (PyErr_Occurred())
457 goto fail;
458 /* It's a legitimate -1, we're done. */
459 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200460 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700461
462 /* Any other negative number is disallowed. */
463 if (result < 0)
464 goto underflow;
465
466 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200467 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700468 (long)uid != result)
469 goto underflow;
470 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200471 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700472
473 if (overflow < 0)
474 goto underflow;
475
476 /*
477 * Okay, the value overflowed a signed long. If it
478 * fits in an *unsigned* long, it may still be okay,
479 * as uid_t may be unsigned long on this platform.
480 */
481 uresult = PyLong_AsUnsignedLong(index);
482 if (PyErr_Occurred()) {
483 if (PyErr_ExceptionMatches(PyExc_OverflowError))
484 goto overflow;
485 goto fail;
486 }
487
488 uid = (uid_t)uresult;
489
490 /*
491 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
492 * but this value would get interpreted as (uid_t)-1 by chown
493 * and its siblings. That's not what the user meant! So we
494 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100495 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700496 */
497 if (uid == (uid_t)-1)
498 goto overflow;
499
500 /* Ensure the value wasn't truncated. */
501 if (sizeof(uid_t) < sizeof(long) &&
502 (unsigned long)uid != uresult)
503 goto overflow;
504 /* fallthrough */
505
506success:
507 Py_DECREF(index);
508 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200509 return 1;
510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is less than minimum");
514 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200515
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700516overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518 "uid is greater than maximum");
519 /* fallthrough */
520
521fail:
522 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523 return 0;
524}
525
526int
527_Py_Gid_Converter(PyObject *obj, void *p)
528{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529 gid_t gid;
530 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200532 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533 unsigned long uresult;
534
535 index = PyNumber_Index(obj);
536 if (index == NULL) {
537 PyErr_Format(PyExc_TypeError,
538 "gid should be integer, not %.200s",
539 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 return 0;
541 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542
543 /*
544 * Handling gid_t is complicated for two reasons:
545 * * Although gid_t is (always?) unsigned, it still
546 * accepts -1.
547 * * We don't know its size in advance--it may be
548 * bigger than an int, or it may be smaller than
549 * a long.
550 *
551 * So a bit of defensive programming is in order.
552 * Start with interpreting the value passed
553 * in as a signed long and see if it works.
554 */
555
556 result = PyLong_AsLongAndOverflow(index, &overflow);
557
558 if (!overflow) {
559 gid = (gid_t)result;
560
561 if (result == -1) {
562 if (PyErr_Occurred())
563 goto fail;
564 /* It's a legitimate -1, we're done. */
565 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567
568 /* Any other negative number is disallowed. */
569 if (result < 0) {
570 goto underflow;
571 }
572
573 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575 (long)gid != result)
576 goto underflow;
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 if (overflow < 0)
581 goto underflow;
582
583 /*
584 * Okay, the value overflowed a signed long. If it
585 * fits in an *unsigned* long, it may still be okay,
586 * as gid_t may be unsigned long on this platform.
587 */
588 uresult = PyLong_AsUnsignedLong(index);
589 if (PyErr_Occurred()) {
590 if (PyErr_ExceptionMatches(PyExc_OverflowError))
591 goto overflow;
592 goto fail;
593 }
594
595 gid = (gid_t)uresult;
596
597 /*
598 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
599 * but this value would get interpreted as (gid_t)-1 by chown
600 * and its siblings. That's not what the user meant! So we
601 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100602 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 */
604 if (gid == (gid_t)-1)
605 goto overflow;
606
607 /* Ensure the value wasn't truncated. */
608 if (sizeof(gid_t) < sizeof(long) &&
609 (unsigned long)gid != uresult)
610 goto overflow;
611 /* fallthrough */
612
613success:
614 Py_DECREF(index);
615 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 return 1;
617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is less than minimum");
621 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625 "gid is greater than maximum");
626 /* fallthrough */
627
628fail:
629 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 return 0;
631}
632#endif /* MS_WINDOWS */
633
634
Gregory P. Smith702dada2015-01-28 16:07:52 -0800635#ifdef HAVE_LONG_LONG
636# define _PyLong_FromDev PyLong_FromLongLong
637#else
638# define _PyLong_FromDev PyLong_FromLong
639#endif
640
641
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200642#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
643static int
644_Py_Dev_Converter(PyObject *obj, void *p)
645{
646#ifdef HAVE_LONG_LONG
647 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
648#else
649 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
650#endif
651 if (PyErr_Occurred())
652 return 0;
653 return 1;
654}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800655#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200656
657
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400659/*
660 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
661 * without the int cast, the value gets interpreted as uint (4291925331),
662 * which doesn't play nicely with all the initializer lines in this file that
663 * look like this:
664 * int dir_fd = DEFAULT_DIR_FD;
665 */
666#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#else
668#define DEFAULT_DIR_FD (-100)
669#endif
670
671static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200672_fd_converter(PyObject *o, int *p, const char *allowed)
673{
674 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 long long_value;
676
677 PyObject *index = PyNumber_Index(o);
678 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200679 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "argument should be %s, not %.200s",
681 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682 return 0;
683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 long_value = PyLong_AsLongAndOverflow(index, &overflow);
686 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200687 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 return 0;
691 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200692 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700693 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700694 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 return 0;
696 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 *p = (int)long_value;
699 return 1;
700}
701
702static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200703dir_fd_converter(PyObject *o, void *p)
704{
705 if (o == Py_None) {
706 *(int *)p = DEFAULT_DIR_FD;
707 return 1;
708 }
709 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700710}
711
712
Larry Hastings9cf065c2012-06-22 16:30:09 -0700713/*
714 * A PyArg_ParseTuple "converter" function
715 * that handles filesystem paths in the manner
716 * preferred by the os module.
717 *
718 * path_converter accepts (Unicode) strings and their
719 * subclasses, and bytes and their subclasses. What
720 * it does with the argument depends on the platform:
721 *
722 * * On Windows, if we get a (Unicode) string we
723 * extract the wchar_t * and return it; if we get
724 * bytes we extract the char * and return that.
725 *
726 * * On all other platforms, strings are encoded
727 * to bytes using PyUnicode_FSConverter, then we
728 * extract the char * from the bytes object and
729 * return that.
730 *
731 * path_converter also optionally accepts signed
732 * integers (representing open file descriptors) instead
733 * of path strings.
734 *
735 * Input fields:
736 * path.nullable
737 * If nonzero, the path is permitted to be None.
738 * path.allow_fd
739 * If nonzero, the path is permitted to be a file handle
740 * (a signed int) instead of a string.
741 * path.function_name
742 * If non-NULL, path_converter will use that as the name
743 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700744 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700745 * path.argument_name
746 * If non-NULL, path_converter will use that as the name
747 * of the parameter in error messages.
748 * (If path.argument_name is NULL it uses "path".)
749 *
750 * Output fields:
751 * path.wide
752 * Points to the path if it was expressed as Unicode
753 * and was not encoded. (Only used on Windows.)
754 * path.narrow
755 * Points to the path if it was expressed as bytes,
756 * or it was Unicode and was encoded to bytes.
757 * path.fd
758 * Contains a file descriptor if path.accept_fd was true
759 * and the caller provided a signed integer instead of any
760 * sort of string.
761 *
762 * WARNING: if your "path" parameter is optional, and is
763 * unspecified, path_converter will never get called.
764 * So if you set allow_fd, you *MUST* initialize path.fd = -1
765 * yourself!
766 * path.length
767 * The length of the path in characters, if specified as
768 * a string.
769 * path.object
770 * The original object passed in.
771 * path.cleanup
772 * For internal use only. May point to a temporary object.
773 * (Pay no attention to the man behind the curtain.)
774 *
775 * At most one of path.wide or path.narrow will be non-NULL.
776 * If path was None and path.nullable was set,
777 * or if path was an integer and path.allow_fd was set,
778 * both path.wide and path.narrow will be NULL
779 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200780 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 * path_converter takes care to not write to the path_t
782 * unless it's successful. However it must reset the
783 * "cleanup" field each time it's called.
784 *
785 * Use as follows:
786 * path_t path;
787 * memset(&path, 0, sizeof(path));
788 * PyArg_ParseTuple(args, "O&", path_converter, &path);
789 * // ... use values from path ...
790 * path_cleanup(&path);
791 *
792 * (Note that if PyArg_Parse fails you don't need to call
793 * path_cleanup(). However it is safe to do so.)
794 */
795typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100796 const char *function_name;
797 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798 int nullable;
799 int allow_fd;
800 wchar_t *wide;
801 char *narrow;
802 int fd;
803 Py_ssize_t length;
804 PyObject *object;
805 PyObject *cleanup;
806} path_t;
807
Larry Hastings2f936352014-08-05 14:04:04 +1000808#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
809 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700810
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811static void
812path_cleanup(path_t *path) {
813 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200814 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815 }
816}
817
818static int
819path_converter(PyObject *o, void *p) {
820 path_t *path = (path_t *)p;
821 PyObject *unicode, *bytes;
822 Py_ssize_t length;
823 char *narrow;
824
825#define FORMAT_EXCEPTION(exc, fmt) \
826 PyErr_Format(exc, "%s%s" fmt, \
827 path->function_name ? path->function_name : "", \
828 path->function_name ? ": " : "", \
829 path->argument_name ? path->argument_name : "path")
830
831 /* Py_CLEANUP_SUPPORTED support */
832 if (o == NULL) {
833 path_cleanup(path);
834 return 1;
835 }
836
837 /* ensure it's always safe to call path_cleanup() */
838 path->cleanup = NULL;
839
840 if (o == Py_None) {
841 if (!path->nullable) {
842 FORMAT_EXCEPTION(PyExc_TypeError,
843 "can't specify None for %s argument");
844 return 0;
845 }
846 path->wide = NULL;
847 path->narrow = NULL;
848 path->length = 0;
849 path->object = o;
850 path->fd = -1;
851 return 1;
852 }
853
854 unicode = PyUnicode_FromObject(o);
855 if (unicode) {
856#ifdef MS_WINDOWS
857 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100858
859 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
860 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861 Py_DECREF(unicode);
862 return 0;
863 }
Victor Stinner59799a82013-11-13 14:17:30 +0100864 if (length > 32767) {
865 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 Py_DECREF(unicode);
867 return 0;
868 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300869 if (wcslen(wide) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300870 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300871 Py_DECREF(unicode);
872 return 0;
873 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700874
875 path->wide = wide;
876 path->narrow = NULL;
877 path->length = length;
878 path->object = o;
879 path->fd = -1;
880 path->cleanup = unicode;
881 return Py_CLEANUP_SUPPORTED;
882#else
883 int converted = PyUnicode_FSConverter(unicode, &bytes);
884 Py_DECREF(unicode);
885 if (!converted)
886 bytes = NULL;
887#endif
888 }
889 else {
890 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200891 if (PyObject_CheckBuffer(o))
892 bytes = PyBytes_FromObject(o);
893 else
894 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895 if (!bytes) {
896 PyErr_Clear();
897 if (path->allow_fd) {
898 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200899 int result = _fd_converter(o, &fd,
900 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 if (result) {
902 path->wide = NULL;
903 path->narrow = NULL;
904 path->length = 0;
905 path->object = o;
906 path->fd = fd;
907 return result;
908 }
909 }
910 }
911 }
912
913 if (!bytes) {
914 if (!PyErr_Occurred())
915 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
916 return 0;
917 }
918
919#ifdef MS_WINDOWS
920 if (win32_warn_bytes_api()) {
921 Py_DECREF(bytes);
922 return 0;
923 }
924#endif
925
926 length = PyBytes_GET_SIZE(bytes);
927#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100928 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
930 Py_DECREF(bytes);
931 return 0;
932 }
933#endif
934
935 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200936 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300937 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 Py_DECREF(bytes);
939 return 0;
940 }
941
942 path->wide = NULL;
943 path->narrow = narrow;
944 path->length = length;
945 path->object = o;
946 path->fd = -1;
947 path->cleanup = bytes;
948 return Py_CLEANUP_SUPPORTED;
949}
950
951static void
952argument_unavailable_error(char *function_name, char *argument_name) {
953 PyErr_Format(PyExc_NotImplementedError,
954 "%s%s%s unavailable on this platform",
955 (function_name != NULL) ? function_name : "",
956 (function_name != NULL) ? ": ": "",
957 argument_name);
958}
959
960static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200961dir_fd_unavailable(PyObject *o, void *p)
962{
963 int dir_fd;
964 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700965 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200966 if (dir_fd != DEFAULT_DIR_FD) {
967 argument_unavailable_error(NULL, "dir_fd");
968 return 0;
969 }
970 *(int *)p = dir_fd;
971 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972}
973
974static int
975fd_specified(char *function_name, int fd) {
976 if (fd == -1)
977 return 0;
978
979 argument_unavailable_error(function_name, "fd");
980 return 1;
981}
982
983static int
984follow_symlinks_specified(char *function_name, int follow_symlinks) {
985 if (follow_symlinks)
986 return 0;
987
988 argument_unavailable_error(function_name, "follow_symlinks");
989 return 1;
990}
991
992static int
993path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
994 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
995 PyErr_Format(PyExc_ValueError,
996 "%s: can't specify dir_fd without matching path",
997 function_name);
998 return 1;
999 }
1000 return 0;
1001}
1002
1003static int
1004dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1005 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1006 PyErr_Format(PyExc_ValueError,
1007 "%s: can't specify both dir_fd and fd",
1008 function_name);
1009 return 1;
1010 }
1011 return 0;
1012}
1013
1014static int
1015fd_and_follow_symlinks_invalid(char *function_name, int fd,
1016 int follow_symlinks) {
1017 if ((fd > 0) && (!follow_symlinks)) {
1018 PyErr_Format(PyExc_ValueError,
1019 "%s: cannot use fd and follow_symlinks together",
1020 function_name);
1021 return 1;
1022 }
1023 return 0;
1024}
1025
1026static int
1027dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1028 int follow_symlinks) {
1029 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1030 PyErr_Format(PyExc_ValueError,
1031 "%s: cannot use dir_fd and follow_symlinks together",
1032 function_name);
1033 return 1;
1034 }
1035 return 0;
1036}
1037
Larry Hastings2f936352014-08-05 14:04:04 +10001038#ifdef MS_WINDOWS
1039 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001040#else
Larry Hastings2f936352014-08-05 14:04:04 +10001041 typedef off_t Py_off_t;
1042#endif
1043
1044static int
1045Py_off_t_converter(PyObject *arg, void *addr)
1046{
1047#ifdef HAVE_LARGEFILE_SUPPORT
1048 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1049#else
1050 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001051#endif
1052 if (PyErr_Occurred())
1053 return 0;
1054 return 1;
1055}
Larry Hastings2f936352014-08-05 14:04:04 +10001056
1057static PyObject *
1058PyLong_FromPy_off_t(Py_off_t offset)
1059{
1060#ifdef HAVE_LARGEFILE_SUPPORT
1061 return PyLong_FromLongLong(offset);
1062#else
1063 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001064#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001065}
1066
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001067
Steve Dowerd81431f2015-03-06 14:47:02 -08001068#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1069/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1070 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001071 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001072#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001074#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001075#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001076#define _NO_CONSOLE_FILENO (intptr_t)-2
1077
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001078/* the special case of checking dup2. The target fd must be in a sensible range */
1079static int
1080_PyVerify_fd_dup2(int fd1, int fd2)
1081{
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 if (!_PyVerify_fd(fd1))
1083 return 0;
1084 if (fd2 == _NO_CONSOLE_FILENO)
1085 return 0;
1086 if ((unsigned)fd2 < _NHANDLE_)
1087 return 1;
1088 else
1089 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001090}
1091#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001092#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001093#endif
1094
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001095#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001096
1097static int
Brian Curtind25aef52011-06-13 15:16:04 -05001098win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001099{
1100 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1101 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1102 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001103
1104 if (0 == DeviceIoControl(
1105 reparse_point_handle,
1106 FSCTL_GET_REPARSE_POINT,
1107 NULL, 0, /* in buffer */
1108 target_buffer, sizeof(target_buffer),
1109 &n_bytes_returned,
1110 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001111 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112
1113 if (reparse_tag)
1114 *reparse_tag = rdb->ReparseTag;
1115
Brian Curtind25aef52011-06-13 15:16:04 -05001116 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001117}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001118
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001119#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001120
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001122#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001123/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001124** environ directly, we must obtain it with _NSGetEnviron(). See also
1125** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001126*/
1127#include <crt_externs.h>
1128static char **environ;
1129#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001131#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132
Barry Warsaw53699e91996-12-10 23:23:01 +00001133static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001134convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135{
Victor Stinner8c62be82010-05-06 00:08:46 +00001136 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001137#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001139#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001140 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001141#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001142
Victor Stinner8c62be82010-05-06 00:08:46 +00001143 d = PyDict_New();
1144 if (d == NULL)
1145 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001146#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001147 if (environ == NULL)
1148 environ = *_NSGetEnviron();
1149#endif
1150#ifdef MS_WINDOWS
1151 /* _wenviron must be initialized in this way if the program is started
1152 through main() instead of wmain(). */
1153 _wgetenv(L"");
1154 if (_wenviron == NULL)
1155 return d;
1156 /* This part ignores errors */
1157 for (e = _wenviron; *e != NULL; e++) {
1158 PyObject *k;
1159 PyObject *v;
1160 wchar_t *p = wcschr(*e, L'=');
1161 if (p == NULL)
1162 continue;
1163 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1164 if (k == NULL) {
1165 PyErr_Clear();
1166 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001167 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001168 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1169 if (v == NULL) {
1170 PyErr_Clear();
1171 Py_DECREF(k);
1172 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001173 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001174 if (PyDict_GetItem(d, k) == NULL) {
1175 if (PyDict_SetItem(d, k, v) != 0)
1176 PyErr_Clear();
1177 }
1178 Py_DECREF(k);
1179 Py_DECREF(v);
1180 }
1181#else
1182 if (environ == NULL)
1183 return d;
1184 /* This part ignores errors */
1185 for (e = environ; *e != NULL; e++) {
1186 PyObject *k;
1187 PyObject *v;
1188 char *p = strchr(*e, '=');
1189 if (p == NULL)
1190 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001191 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 if (k == NULL) {
1193 PyErr_Clear();
1194 continue;
1195 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001196 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 if (v == NULL) {
1198 PyErr_Clear();
1199 Py_DECREF(k);
1200 continue;
1201 }
1202 if (PyDict_GetItem(d, k) == NULL) {
1203 if (PyDict_SetItem(d, k, v) != 0)
1204 PyErr_Clear();
1205 }
1206 Py_DECREF(k);
1207 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001208 }
1209#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001210 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211}
1212
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213/* Set a POSIX-specific error from errno, and return NULL */
1214
Barry Warsawd58d7641998-07-23 16:14:40 +00001215static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001216posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001217{
Victor Stinner8c62be82010-05-06 00:08:46 +00001218 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219}
Mark Hammondef8b6542001-05-13 08:04:26 +00001220
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001221#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001222static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001223win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 /* XXX We should pass the function name along in the future.
1226 (winreg.c also wants to pass the function name.)
1227 This would however require an additional param to the
1228 Windows error object, which is non-trivial.
1229 */
1230 errno = GetLastError();
1231 if (filename)
1232 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1233 else
1234 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001235}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001238win32_error_object(char* function, PyObject* filename)
1239{
1240 /* XXX - see win32_error for comments on 'function' */
1241 errno = GetLastError();
1242 if (filename)
1243 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001244 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001245 errno,
1246 filename);
1247 else
1248 return PyErr_SetFromWindowsErr(errno);
1249}
1250
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001251#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252
Larry Hastings9cf065c2012-06-22 16:30:09 -07001253static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001254path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255{
1256#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001257 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1258 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001259#else
Victor Stinner292c8352012-10-30 02:17:38 +01001260 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261#endif
1262}
1263
Larry Hastings31826802013-10-19 00:09:25 -07001264
Larry Hastingsb0827312014-02-09 22:05:19 -08001265static PyObject *
1266path_error2(path_t *path, path_t *path2)
1267{
1268#ifdef MS_WINDOWS
1269 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1270 0, path->object, path2->object);
1271#else
1272 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1273 path->object, path2->object);
1274#endif
1275}
1276
1277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278/* POSIX generic methods */
1279
Larry Hastings2f936352014-08-05 14:04:04 +10001280static int
1281fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001282{
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001284 int *pointer = (int *)p;
1285 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001287 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001288 *pointer = fd;
1289 return 1;
1290}
1291
1292static PyObject *
1293posix_fildes_fd(int fd, int (*func)(int))
1294{
1295 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001296 int async_err = 0;
1297
Steve Dower8fc89802015-04-12 00:26:27 -04001298 if (!_PyVerify_fd(fd))
1299 return posix_error();
1300
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001301 do {
1302 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001303 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001304 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001305 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001306 Py_END_ALLOW_THREADS
1307 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1308 if (res != 0)
1309 return (!async_err) ? posix_error() : NULL;
1310 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001311}
Guido van Rossum21142a01999-01-08 21:05:37 +00001312
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001314#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315/* This is a reimplementation of the C library's chdir function,
1316 but one that produces Win32 errors instead of DOS error codes.
1317 chdir is essentially a wrapper around SetCurrentDirectory; however,
1318 it also needs to set "magic" environment variables indicating
1319 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001320static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321win32_chdir(LPCSTR path)
1322{
Victor Stinner75875072013-11-24 19:23:25 +01001323 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 int result;
1325 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326
Victor Stinner8c62be82010-05-06 00:08:46 +00001327 if(!SetCurrentDirectoryA(path))
1328 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001329 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 if (!result)
1331 return FALSE;
1332 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001333 than MAX_PATH-1 (not including the final null character). */
1334 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001335 if (strncmp(new_path, "\\\\", 2) == 0 ||
1336 strncmp(new_path, "//", 2) == 0)
1337 /* UNC path, nothing to do. */
1338 return TRUE;
1339 env[1] = new_path[0];
1340 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341}
1342
1343/* The Unicode version differs from the ANSI version
1344 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001345static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346win32_wchdir(LPCWSTR path)
1347{
Victor Stinner75875072013-11-24 19:23:25 +01001348 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 int result;
1350 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001351
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 if(!SetCurrentDirectoryW(path))
1353 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001354 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 if (!result)
1356 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001357 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001358 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 if (!new_path) {
1360 SetLastError(ERROR_OUTOFMEMORY);
1361 return FALSE;
1362 }
1363 result = GetCurrentDirectoryW(result, new_path);
1364 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001365 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 return FALSE;
1367 }
1368 }
1369 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1370 wcsncmp(new_path, L"//", 2) == 0)
1371 /* UNC path, nothing to do. */
1372 return TRUE;
1373 env[1] = new_path[0];
1374 result = SetEnvironmentVariableW(env, new_path);
1375 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001376 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378}
1379#endif
1380
Martin v. Löwis14694662006-02-03 12:54:16 +00001381#ifdef MS_WINDOWS
1382/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1383 - time stamps are restricted to second resolution
1384 - file modification times suffer from forth-and-back conversions between
1385 UTC and local time
1386 Therefore, we implement our own stat, based on the Win32 API directly.
1387*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001388#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001389#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001390
Guido van Rossumd8faa362007-04-27 19:54:29 +00001391static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001392attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001393{
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 HANDLE hFindFile;
1395 WIN32_FIND_DATAA FileData;
1396 hFindFile = FindFirstFileA(pszFile, &FileData);
1397 if (hFindFile == INVALID_HANDLE_VALUE)
1398 return FALSE;
1399 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001400 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001401 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001402 info->dwFileAttributes = FileData.dwFileAttributes;
1403 info->ftCreationTime = FileData.ftCreationTime;
1404 info->ftLastAccessTime = FileData.ftLastAccessTime;
1405 info->ftLastWriteTime = FileData.ftLastWriteTime;
1406 info->nFileSizeHigh = FileData.nFileSizeHigh;
1407 info->nFileSizeLow = FileData.nFileSizeLow;
1408/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001409 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1410 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001412}
1413
Victor Stinner6036e442015-03-08 01:58:04 +01001414static void
1415find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1416 BY_HANDLE_FILE_INFORMATION *info,
1417 ULONG *reparse_tag)
1418{
1419 memset(info, 0, sizeof(*info));
1420 info->dwFileAttributes = pFileData->dwFileAttributes;
1421 info->ftCreationTime = pFileData->ftCreationTime;
1422 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1423 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1424 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1425 info->nFileSizeLow = pFileData->nFileSizeLow;
1426/* info->nNumberOfLinks = 1; */
1427 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1428 *reparse_tag = pFileData->dwReserved0;
1429 else
1430 *reparse_tag = 0;
1431}
1432
Guido van Rossumd8faa362007-04-27 19:54:29 +00001433static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001434attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001435{
Victor Stinner8c62be82010-05-06 00:08:46 +00001436 HANDLE hFindFile;
1437 WIN32_FIND_DATAW FileData;
1438 hFindFile = FindFirstFileW(pszFile, &FileData);
1439 if (hFindFile == INVALID_HANDLE_VALUE)
1440 return FALSE;
1441 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001442 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001444}
1445
Brian Curtind25aef52011-06-13 15:16:04 -05001446static BOOL
1447get_target_path(HANDLE hdl, wchar_t **target_path)
1448{
1449 int buf_size, result_length;
1450 wchar_t *buf;
1451
1452 /* We have a good handle to the target, use it to determine
1453 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001454 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1455 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001456 if(!buf_size)
1457 return FALSE;
1458
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001459 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001460 if (!buf) {
1461 SetLastError(ERROR_OUTOFMEMORY);
1462 return FALSE;
1463 }
1464
Steve Dower2ea51c92015-03-20 21:49:12 -07001465 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001466 buf, buf_size, VOLUME_NAME_DOS);
1467
1468 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001469 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001470 return FALSE;
1471 }
1472
1473 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001474 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001475 return FALSE;
1476 }
1477
1478 buf[result_length] = 0;
1479
1480 *target_path = buf;
1481 return TRUE;
1482}
1483
1484static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001485win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001486 BOOL traverse);
1487static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001488win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001489 BOOL traverse)
1490{
Victor Stinner26de69d2011-06-17 15:15:38 +02001491 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001492 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001493 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001494 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001495 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001496 const char *dot;
1497
1498 hFile = CreateFileA(
1499 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001500 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001501 0, /* share mode */
1502 NULL, /* security attributes */
1503 OPEN_EXISTING,
1504 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001505 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1506 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001507 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001508 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1509 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 NULL);
1511
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001513 /* Either the target doesn't exist, or we don't have access to
1514 get a handle to it. If the former, we need to return an error.
1515 If the latter, we can use attributes_from_dir. */
1516 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 return -1;
1518 /* Could not get attributes on open file. Fall back to
1519 reading the directory. */
1520 if (!attributes_from_dir(path, &info, &reparse_tag))
1521 /* Very strange. This should not fail now */
1522 return -1;
1523 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1524 if (traverse) {
1525 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001526 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001527 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001528 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001530 } else {
1531 if (!GetFileInformationByHandle(hFile, &info)) {
1532 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001533 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 }
1535 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001536 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1537 return -1;
1538
1539 /* Close the outer open file handle now that we're about to
1540 reopen it with different flags. */
1541 if (!CloseHandle(hFile))
1542 return -1;
1543
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001545 /* In order to call GetFinalPathNameByHandle we need to open
1546 the file without the reparse handling flag set. */
1547 hFile2 = CreateFileA(
1548 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1549 NULL, OPEN_EXISTING,
1550 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1551 NULL);
1552 if (hFile2 == INVALID_HANDLE_VALUE)
1553 return -1;
1554
1555 if (!get_target_path(hFile2, &target_path))
1556 return -1;
1557
1558 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001559 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 return code;
1561 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001562 } else
1563 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001565 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001566
1567 /* Set S_IEXEC if it is an .exe, .bat, ... */
1568 dot = strrchr(path, '.');
1569 if (dot) {
1570 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1571 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1572 result->st_mode |= 0111;
1573 }
1574 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575}
1576
1577static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001578win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001579 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580{
1581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const wchar_t *dot;
1587
1588 hFile = CreateFileW(
1589 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001590 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591 0, /* share mode */
1592 NULL, /* security attributes */
1593 OPEN_EXISTING,
1594 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001595 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1596 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001597 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001598 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001599 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001600 NULL);
1601
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001602 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001603 /* Either the target doesn't exist, or we don't have access to
1604 get a handle to it. If the former, we need to return an error.
1605 If the latter, we can use attributes_from_dir. */
1606 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 return -1;
1608 /* Could not get attributes on open file. Fall back to
1609 reading the directory. */
1610 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1611 /* Very strange. This should not fail now */
1612 return -1;
1613 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1614 if (traverse) {
1615 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001617 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001619 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 } else {
1621 if (!GetFileInformationByHandle(hFile, &info)) {
1622 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001623 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 }
1625 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001626 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1627 return -1;
1628
1629 /* Close the outer open file handle now that we're about to
1630 reopen it with different flags. */
1631 if (!CloseHandle(hFile))
1632 return -1;
1633
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001634 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001635 /* In order to call GetFinalPathNameByHandle we need to open
1636 the file without the reparse handling flag set. */
1637 hFile2 = CreateFileW(
1638 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1639 NULL, OPEN_EXISTING,
1640 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1641 NULL);
1642 if (hFile2 == INVALID_HANDLE_VALUE)
1643 return -1;
1644
1645 if (!get_target_path(hFile2, &target_path))
1646 return -1;
1647
1648 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001649 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 return code;
1651 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001652 } else
1653 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001655 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656
1657 /* Set S_IEXEC if it is an .exe, .bat, ... */
1658 dot = wcsrchr(path, '.');
1659 if (dot) {
1660 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1661 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1662 result->st_mode |= 0111;
1663 }
1664 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665}
1666
1667static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001668win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 /* Protocol violation: we explicitly clear errno, instead of
1671 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001672 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673 errno = 0;
1674 return code;
1675}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001678win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679{
1680 /* Protocol violation: we explicitly clear errno, instead of
1681 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001682 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683 errno = 0;
1684 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685}
Brian Curtind25aef52011-06-13 15:16:04 -05001686/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001687
1688 In Posix, stat automatically traverses symlinks and returns the stat
1689 structure for the target. In Windows, the equivalent GetFileAttributes by
1690 default does not traverse symlinks and instead returns attributes for
1691 the symlink.
1692
1693 Therefore, win32_lstat will get the attributes traditionally, and
1694 win32_stat will first explicitly resolve the symlink target and then will
1695 call win32_lstat on that result.
1696
Ezio Melotti4969f702011-03-15 05:59:46 +02001697 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001698
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001699static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001700win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001701{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001703}
1704
Victor Stinner8c62be82010-05-06 00:08:46 +00001705static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001706win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001707{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001709}
1710
1711static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001712win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001713{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001715}
1716
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001717static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001718win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001719{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001721}
1722
Martin v. Löwis14694662006-02-03 12:54:16 +00001723#endif /* MS_WINDOWS */
1724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001725PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001726"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001727This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001728 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001729or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1730\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001731Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1732or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001733\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735
1736static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001737 {"st_mode", "protection bits"},
1738 {"st_ino", "inode"},
1739 {"st_dev", "device"},
1740 {"st_nlink", "number of hard links"},
1741 {"st_uid", "user ID of owner"},
1742 {"st_gid", "group ID of owner"},
1743 {"st_size", "total size, in bytes"},
1744 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1745 {NULL, "integer time of last access"},
1746 {NULL, "integer time of last modification"},
1747 {NULL, "integer time of last change"},
1748 {"st_atime", "time of last access"},
1749 {"st_mtime", "time of last modification"},
1750 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001751 {"st_atime_ns", "time of last access in nanoseconds"},
1752 {"st_mtime_ns", "time of last modification in nanoseconds"},
1753 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001754#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001755 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001757#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001759#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001760#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001763#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001765#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001766#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001768#endif
1769#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001771#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001772#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1773 {"st_file_attributes", "Windows file attribute bits"},
1774#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776};
1777
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001778#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001779#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001781#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782#endif
1783
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1786#else
1787#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1788#endif
1789
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1792#else
1793#define ST_RDEV_IDX ST_BLOCKS_IDX
1794#endif
1795
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001796#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1797#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1798#else
1799#define ST_FLAGS_IDX ST_RDEV_IDX
1800#endif
1801
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001803#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001804#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001805#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001806#endif
1807
1808#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1809#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1810#else
1811#define ST_BIRTHTIME_IDX ST_GEN_IDX
1812#endif
1813
Zachary Ware63f277b2014-06-19 09:46:37 -05001814#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1815#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1816#else
1817#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1818#endif
1819
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001820static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 "stat_result", /* name */
1822 stat_result__doc__, /* doc */
1823 stat_result_fields,
1824 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825};
1826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001828"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1829This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001830 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001831or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834
1835static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001836 {"f_bsize", },
1837 {"f_frsize", },
1838 {"f_blocks", },
1839 {"f_bfree", },
1840 {"f_bavail", },
1841 {"f_files", },
1842 {"f_ffree", },
1843 {"f_favail", },
1844 {"f_flag", },
1845 {"f_namemax",},
1846 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847};
1848
1849static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 "statvfs_result", /* name */
1851 statvfs_result__doc__, /* doc */
1852 statvfs_result_fields,
1853 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854};
1855
Ross Lagerwall7807c352011-03-17 20:20:30 +02001856#if defined(HAVE_WAITID) && !defined(__APPLE__)
1857PyDoc_STRVAR(waitid_result__doc__,
1858"waitid_result: Result from waitid.\n\n\
1859This object may be accessed either as a tuple of\n\
1860 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1861or via the attributes si_pid, si_uid, and so on.\n\
1862\n\
1863See os.waitid for more information.");
1864
1865static PyStructSequence_Field waitid_result_fields[] = {
1866 {"si_pid", },
1867 {"si_uid", },
1868 {"si_signo", },
1869 {"si_status", },
1870 {"si_code", },
1871 {0}
1872};
1873
1874static PyStructSequence_Desc waitid_result_desc = {
1875 "waitid_result", /* name */
1876 waitid_result__doc__, /* doc */
1877 waitid_result_fields,
1878 5
1879};
1880static PyTypeObject WaitidResultType;
1881#endif
1882
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001883static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001884static PyTypeObject StatResultType;
1885static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001886#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001887static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001888#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001889static newfunc structseq_new;
1890
1891static PyObject *
1892statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1893{
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 PyStructSequence *result;
1895 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 result = (PyStructSequence*)structseq_new(type, args, kwds);
1898 if (!result)
1899 return NULL;
1900 /* If we have been initialized from a tuple,
1901 st_?time might be set to None. Initialize it
1902 from the int slots. */
1903 for (i = 7; i <= 9; i++) {
1904 if (result->ob_item[i+3] == Py_None) {
1905 Py_DECREF(Py_None);
1906 Py_INCREF(result->ob_item[i]);
1907 result->ob_item[i+3] = result->ob_item[i];
1908 }
1909 }
1910 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001911}
1912
1913
1914
1915/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001916static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917
1918PyDoc_STRVAR(stat_float_times__doc__,
1919"stat_float_times([newval]) -> oldval\n\n\
1920Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001921\n\
1922If value is True, future calls to stat() return floats; if it is False,\n\
1923future calls return ints.\n\
1924If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001925
Larry Hastings2f936352014-08-05 14:04:04 +10001926/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001927static PyObject*
1928stat_float_times(PyObject* self, PyObject *args)
1929{
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 int newval = -1;
1931 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1932 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001933 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1934 "stat_float_times() is deprecated",
1935 1))
1936 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 if (newval == -1)
1938 /* Return old value */
1939 return PyBool_FromLong(_stat_float_times);
1940 _stat_float_times = newval;
1941 Py_INCREF(Py_None);
1942 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001943}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944
Larry Hastings6fe20b32012-04-19 15:07:49 -07001945static PyObject *billion = NULL;
1946
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001947static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001948fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001949{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001950 PyObject *s = _PyLong_FromTime_t(sec);
1951 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1952 PyObject *s_in_ns = NULL;
1953 PyObject *ns_total = NULL;
1954 PyObject *float_s = NULL;
1955
1956 if (!(s && ns_fractional))
1957 goto exit;
1958
1959 s_in_ns = PyNumber_Multiply(s, billion);
1960 if (!s_in_ns)
1961 goto exit;
1962
1963 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1964 if (!ns_total)
1965 goto exit;
1966
Victor Stinner4195b5c2012-02-08 23:03:19 +01001967 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001968 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1969 if (!float_s)
1970 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001972 else {
1973 float_s = s;
1974 Py_INCREF(float_s);
1975 }
1976
1977 PyStructSequence_SET_ITEM(v, index, s);
1978 PyStructSequence_SET_ITEM(v, index+3, float_s);
1979 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1980 s = NULL;
1981 float_s = NULL;
1982 ns_total = NULL;
1983exit:
1984 Py_XDECREF(s);
1985 Py_XDECREF(ns_fractional);
1986 Py_XDECREF(s_in_ns);
1987 Py_XDECREF(ns_total);
1988 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001989}
1990
Tim Peters5aa91602002-01-30 05:46:57 +00001991/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001992 (used by posix_stat() and posix_fstat()) */
1993static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001994_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001995{
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 unsigned long ansec, mnsec, cnsec;
1997 PyObject *v = PyStructSequence_New(&StatResultType);
1998 if (v == NULL)
1999 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002000
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002002#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 PyStructSequence_SET_ITEM(v, 1,
2004 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002005#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002008#ifdef MS_WINDOWS
2009 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002010#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002011 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002014#if defined(MS_WINDOWS)
2015 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2016 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2017#else
2018 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2019 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2020#endif
Fred Drake699f3522000-06-29 21:12:41 +00002021#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 PyStructSequence_SET_ITEM(v, 6,
2023 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002024#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002026#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002027
Martin v. Löwis14694662006-02-03 12:54:16 +00002028#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 ansec = st->st_atim.tv_nsec;
2030 mnsec = st->st_mtim.tv_nsec;
2031 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002032#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 ansec = st->st_atimespec.tv_nsec;
2034 mnsec = st->st_mtimespec.tv_nsec;
2035 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002036#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 ansec = st->st_atime_nsec;
2038 mnsec = st->st_mtime_nsec;
2039 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002040#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002043 fill_time(v, 7, st->st_atime, ansec);
2044 fill_time(v, 8, st->st_mtime, mnsec);
2045 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002046
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002047#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2049 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002050#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002051#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2053 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002055#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2057 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002058#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002059#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2061 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002062#endif
2063#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002065 PyObject *val;
2066 unsigned long bsec,bnsec;
2067 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002069 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002071 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002072#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073 if (_stat_float_times) {
2074 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2075 } else {
2076 val = PyLong_FromLong((long)bsec);
2077 }
2078 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2079 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002081#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002082#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2084 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002085#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002086#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2087 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2088 PyLong_FromUnsignedLong(st->st_file_attributes));
2089#endif
Fred Drake699f3522000-06-29 21:12:41 +00002090
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 if (PyErr_Occurred()) {
2092 Py_DECREF(v);
2093 return NULL;
2094 }
Fred Drake699f3522000-06-29 21:12:41 +00002095
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002097}
2098
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002099/* POSIX methods */
2100
Guido van Rossum94f6f721999-01-06 18:42:14 +00002101
2102static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103posix_do_stat(char *function_name, path_t *path,
2104 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002106 STRUCT_STAT st;
2107 int result;
2108
2109#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2110 if (follow_symlinks_specified(function_name, follow_symlinks))
2111 return NULL;
2112#endif
2113
2114 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2115 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2116 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2117 return NULL;
2118
2119 Py_BEGIN_ALLOW_THREADS
2120 if (path->fd != -1)
2121 result = FSTAT(path->fd, &st);
2122 else
2123#ifdef MS_WINDOWS
2124 if (path->wide) {
2125 if (follow_symlinks)
2126 result = win32_stat_w(path->wide, &st);
2127 else
2128 result = win32_lstat_w(path->wide, &st);
2129 }
2130 else
2131#endif
2132#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2133 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2134 result = LSTAT(path->narrow, &st);
2135 else
2136#endif
2137#ifdef HAVE_FSTATAT
2138 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2139 result = fstatat(dir_fd, path->narrow, &st,
2140 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2141 else
2142#endif
2143 result = STAT(path->narrow, &st);
2144 Py_END_ALLOW_THREADS
2145
Victor Stinner292c8352012-10-30 02:17:38 +01002146 if (result != 0) {
2147 return path_error(path);
2148 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002149
2150 return _pystat_fromstructstat(&st);
2151}
2152
Larry Hastings2f936352014-08-05 14:04:04 +10002153/*[python input]
2154
2155for s in """
2156
2157FACCESSAT
2158FCHMODAT
2159FCHOWNAT
2160FSTATAT
2161LINKAT
2162MKDIRAT
2163MKFIFOAT
2164MKNODAT
2165OPENAT
2166READLINKAT
2167SYMLINKAT
2168UNLINKAT
2169
2170""".strip().split():
2171 s = s.strip()
2172 print("""
2173#ifdef HAVE_{s}
2174 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002175#else
Larry Hastings2f936352014-08-05 14:04:04 +10002176 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002177#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002178""".rstrip().format(s=s))
2179
2180for s in """
2181
2182FCHDIR
2183FCHMOD
2184FCHOWN
2185FDOPENDIR
2186FEXECVE
2187FPATHCONF
2188FSTATVFS
2189FTRUNCATE
2190
2191""".strip().split():
2192 s = s.strip()
2193 print("""
2194#ifdef HAVE_{s}
2195 #define PATH_HAVE_{s} 1
2196#else
2197 #define PATH_HAVE_{s} 0
2198#endif
2199
2200""".rstrip().format(s=s))
2201[python start generated code]*/
2202
2203#ifdef HAVE_FACCESSAT
2204 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2205#else
2206 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2207#endif
2208
2209#ifdef HAVE_FCHMODAT
2210 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2211#else
2212 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2213#endif
2214
2215#ifdef HAVE_FCHOWNAT
2216 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2217#else
2218 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2219#endif
2220
2221#ifdef HAVE_FSTATAT
2222 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2223#else
2224 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2225#endif
2226
2227#ifdef HAVE_LINKAT
2228 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2229#else
2230 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2231#endif
2232
2233#ifdef HAVE_MKDIRAT
2234 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2235#else
2236 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2237#endif
2238
2239#ifdef HAVE_MKFIFOAT
2240 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_MKNODAT
2246 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_OPENAT
2252 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_READLINKAT
2258 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_SYMLINKAT
2264 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_UNLINKAT
2270 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_FCHDIR
2276 #define PATH_HAVE_FCHDIR 1
2277#else
2278 #define PATH_HAVE_FCHDIR 0
2279#endif
2280
2281#ifdef HAVE_FCHMOD
2282 #define PATH_HAVE_FCHMOD 1
2283#else
2284 #define PATH_HAVE_FCHMOD 0
2285#endif
2286
2287#ifdef HAVE_FCHOWN
2288 #define PATH_HAVE_FCHOWN 1
2289#else
2290 #define PATH_HAVE_FCHOWN 0
2291#endif
2292
2293#ifdef HAVE_FDOPENDIR
2294 #define PATH_HAVE_FDOPENDIR 1
2295#else
2296 #define PATH_HAVE_FDOPENDIR 0
2297#endif
2298
2299#ifdef HAVE_FEXECVE
2300 #define PATH_HAVE_FEXECVE 1
2301#else
2302 #define PATH_HAVE_FEXECVE 0
2303#endif
2304
2305#ifdef HAVE_FPATHCONF
2306 #define PATH_HAVE_FPATHCONF 1
2307#else
2308 #define PATH_HAVE_FPATHCONF 0
2309#endif
2310
2311#ifdef HAVE_FSTATVFS
2312 #define PATH_HAVE_FSTATVFS 1
2313#else
2314 #define PATH_HAVE_FSTATVFS 0
2315#endif
2316
2317#ifdef HAVE_FTRUNCATE
2318 #define PATH_HAVE_FTRUNCATE 1
2319#else
2320 #define PATH_HAVE_FTRUNCATE 0
2321#endif
2322/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002323
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002324#ifdef MS_WINDOWS
2325 #undef PATH_HAVE_FTRUNCATE
2326 #define PATH_HAVE_FTRUNCATE 1
2327#endif
Larry Hastings31826802013-10-19 00:09:25 -07002328
Larry Hastings61272b72014-01-07 12:41:53 -08002329/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002330
2331class path_t_converter(CConverter):
2332
2333 type = "path_t"
2334 impl_by_reference = True
2335 parse_by_reference = True
2336
2337 converter = 'path_converter'
2338
2339 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002340 # right now path_t doesn't support default values.
2341 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002342 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002343 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002344
Larry Hastings2f936352014-08-05 14:04:04 +10002345 if self.c_default not in (None, 'Py_None'):
2346 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002347
2348 self.nullable = nullable
2349 self.allow_fd = allow_fd
2350
Larry Hastings7726ac92014-01-31 22:03:12 -08002351 def pre_render(self):
2352 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002353 if isinstance(value, str):
2354 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002355 return str(int(bool(value)))
2356
2357 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002358 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002359 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002360 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 strify(self.nullable),
2362 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002363 )
2364
2365 def cleanup(self):
2366 return "path_cleanup(&" + self.name + ");\n"
2367
2368
2369class dir_fd_converter(CConverter):
2370 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002371
Larry Hastings2f936352014-08-05 14:04:04 +10002372 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002373 if self.default in (unspecified, None):
2374 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002375 if isinstance(requires, str):
2376 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2377 else:
2378 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002379
Larry Hastings2f936352014-08-05 14:04:04 +10002380class fildes_converter(CConverter):
2381 type = 'int'
2382 converter = 'fildes_converter'
2383
2384class uid_t_converter(CConverter):
2385 type = "uid_t"
2386 converter = '_Py_Uid_Converter'
2387
2388class gid_t_converter(CConverter):
2389 type = "gid_t"
2390 converter = '_Py_Gid_Converter'
2391
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002392class dev_t_converter(CConverter):
2393 type = 'dev_t'
2394 converter = '_Py_Dev_Converter'
2395
2396class dev_t_return_converter(unsigned_long_return_converter):
2397 type = 'dev_t'
2398 conversion_fn = '_PyLong_FromDev'
2399 unsigned_cast = '(dev_t)'
2400
Larry Hastings2f936352014-08-05 14:04:04 +10002401class FSConverter_converter(CConverter):
2402 type = 'PyObject *'
2403 converter = 'PyUnicode_FSConverter'
2404 def converter_init(self):
2405 if self.default is not unspecified:
2406 fail("FSConverter_converter does not support default values")
2407 self.c_default = 'NULL'
2408
2409 def cleanup(self):
2410 return "Py_XDECREF(" + self.name + ");\n"
2411
2412class pid_t_converter(CConverter):
2413 type = 'pid_t'
2414 format_unit = '" _Py_PARSE_PID "'
2415
2416class idtype_t_converter(int_converter):
2417 type = 'idtype_t'
2418
2419class id_t_converter(CConverter):
2420 type = 'id_t'
2421 format_unit = '" _Py_PARSE_PID "'
2422
2423class Py_intptr_t_converter(CConverter):
2424 type = 'Py_intptr_t'
2425 format_unit = '" _Py_PARSE_INTPTR "'
2426
2427class Py_off_t_converter(CConverter):
2428 type = 'Py_off_t'
2429 converter = 'Py_off_t_converter'
2430
2431class Py_off_t_return_converter(long_return_converter):
2432 type = 'Py_off_t'
2433 conversion_fn = 'PyLong_FromPy_off_t'
2434
2435class path_confname_converter(CConverter):
2436 type="int"
2437 converter="conv_path_confname"
2438
2439class confstr_confname_converter(path_confname_converter):
2440 converter='conv_confstr_confname'
2441
2442class sysconf_confname_converter(path_confname_converter):
2443 converter="conv_sysconf_confname"
2444
2445class sched_param_converter(CConverter):
2446 type = 'struct sched_param'
2447 converter = 'convert_sched_param'
2448 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings61272b72014-01-07 12:41:53 -08002450[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002451/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002452
Larry Hastings61272b72014-01-07 12:41:53 -08002453/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002454
Larry Hastings2a727912014-01-16 11:32:01 -08002455os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002456
2457 path : path_t(allow_fd=True)
2458 Path to be examined; can be string, bytes, or open-file-descriptor int.
2459
2460 *
2461
Larry Hastings2f936352014-08-05 14:04:04 +10002462 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002463 If not None, it should be a file descriptor open to a directory,
2464 and path should be a relative string; path will then be relative to
2465 that directory.
2466
2467 follow_symlinks: bool = True
2468 If False, and the last element of the path is a symbolic link,
2469 stat will examine the symbolic link itself instead of the file
2470 the link points to.
2471
2472Perform a stat system call on the given path.
2473
2474dir_fd and follow_symlinks may not be implemented
2475 on your platform. If they are unavailable, using them will raise a
2476 NotImplementedError.
2477
2478It's an error to use dir_fd or follow_symlinks when specifying path as
2479 an open file descriptor.
2480
Larry Hastings61272b72014-01-07 12:41:53 -08002481[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings31826802013-10-19 00:09:25 -07002483static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002484os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd,
2485 int follow_symlinks)
2486/*[clinic end generated code: output=e4f7569f95d523ca input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002487{
2488 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2489}
2490
Larry Hastings2f936352014-08-05 14:04:04 +10002491
2492/*[clinic input]
2493os.lstat
2494
2495 path : path_t
2496
2497 *
2498
2499 dir_fd : dir_fd(requires='fstatat') = None
2500
2501Perform a stat system call on the given path, without following symbolic links.
2502
2503Like stat(), but do not follow symbolic links.
2504Equivalent to stat(path, follow_symlinks=False).
2505[clinic start generated code]*/
2506
Larry Hastings2f936352014-08-05 14:04:04 +10002507static PyObject *
2508os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002509/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002510{
2511 int follow_symlinks = 0;
2512 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2513}
Larry Hastings31826802013-10-19 00:09:25 -07002514
Larry Hastings2f936352014-08-05 14:04:04 +10002515
Larry Hastings61272b72014-01-07 12:41:53 -08002516/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002517os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002518
2519 path: path_t(allow_fd=True)
2520 Path to be tested; can be string, bytes, or open-file-descriptor int.
2521
2522 mode: int
2523 Operating-system mode bitfield. Can be F_OK to test existence,
2524 or the inclusive-OR of R_OK, W_OK, and X_OK.
2525
2526 *
2527
Larry Hastings2f936352014-08-05 14:04:04 +10002528 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002529 If not None, it should be a file descriptor open to a directory,
2530 and path should be relative; path will then be relative to that
2531 directory.
2532
2533 effective_ids: bool = False
2534 If True, access will use the effective uid/gid instead of
2535 the real uid/gid.
2536
2537 follow_symlinks: bool = True
2538 If False, and the last element of the path is a symbolic link,
2539 access will examine the symbolic link itself instead of the file
2540 the link points to.
2541
2542Use the real uid/gid to test for access to a path.
2543
2544{parameters}
2545dir_fd, effective_ids, and follow_symlinks may not be implemented
2546 on your platform. If they are unavailable, using them will raise a
2547 NotImplementedError.
2548
2549Note that most operations will use the effective uid/gid, therefore this
2550 routine can be used in a suid/sgid environment to test if the invoking user
2551 has the specified access to the path.
2552
Larry Hastings61272b72014-01-07 12:41:53 -08002553[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002554
Larry Hastings2f936352014-08-05 14:04:04 +10002555static int
Larry Hastings89964c42015-04-14 18:07:59 -04002556os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2557 int effective_ids, int follow_symlinks)
2558/*[clinic end generated code: output=abaa53340210088d input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559{
Larry Hastings2f936352014-08-05 14:04:04 +10002560 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002561
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002562#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002564#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002565 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002566#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002567
Larry Hastings9cf065c2012-06-22 16:30:09 -07002568#ifndef HAVE_FACCESSAT
2569 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002570 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002571
2572 if (effective_ids) {
2573 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002574 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 }
2576#endif
2577
2578#ifdef MS_WINDOWS
2579 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002580 if (path->wide != NULL)
2581 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002583 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 Py_END_ALLOW_THREADS
2585
2586 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002587 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002588 * * we didn't get a -1, and
2589 * * write access wasn't requested,
2590 * * or the file isn't read-only,
2591 * * or it's a directory.
2592 * (Directories cannot be read-only on Windows.)
2593 */
Larry Hastings2f936352014-08-05 14:04:04 +10002594 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002595 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002597 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002598#else
2599
2600 Py_BEGIN_ALLOW_THREADS
2601#ifdef HAVE_FACCESSAT
2602 if ((dir_fd != DEFAULT_DIR_FD) ||
2603 effective_ids ||
2604 !follow_symlinks) {
2605 int flags = 0;
2606 if (!follow_symlinks)
2607 flags |= AT_SYMLINK_NOFOLLOW;
2608 if (effective_ids)
2609 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002610 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611 }
2612 else
2613#endif
Larry Hastings31826802013-10-19 00:09:25 -07002614 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002615 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002616 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617#endif
2618
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002620}
2621
Guido van Rossumd371ff11999-01-25 16:12:23 +00002622#ifndef F_OK
2623#define F_OK 0
2624#endif
2625#ifndef R_OK
2626#define R_OK 4
2627#endif
2628#ifndef W_OK
2629#define W_OK 2
2630#endif
2631#ifndef X_OK
2632#define X_OK 1
2633#endif
2634
Larry Hastings31826802013-10-19 00:09:25 -07002635
Guido van Rossumd371ff11999-01-25 16:12:23 +00002636#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002637/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002638os.ttyname -> DecodeFSDefault
2639
2640 fd: int
2641 Integer file descriptor handle.
2642
2643 /
2644
2645Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002646[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002647
Larry Hastings31826802013-10-19 00:09:25 -07002648static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002649os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002650/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002651{
2652 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002653
Larry Hastings31826802013-10-19 00:09:25 -07002654 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002656 posix_error();
2657 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002658}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002659#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002660
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002661#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002662/*[clinic input]
2663os.ctermid
2664
2665Return the name of the controlling terminal for this process.
2666[clinic start generated code]*/
2667
Larry Hastings2f936352014-08-05 14:04:04 +10002668static PyObject *
2669os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002670/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671{
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 char *ret;
2673 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002674
Greg Wardb48bc172000-03-01 21:51:56 +00002675#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002676 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002678 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002680 if (ret == NULL)
2681 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002682 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683}
Larry Hastings2f936352014-08-05 14:04:04 +10002684#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002685
Larry Hastings2f936352014-08-05 14:04:04 +10002686
2687/*[clinic input]
2688os.chdir
2689
2690 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2691
2692Change the current working directory to the specified path.
2693
2694path may always be specified as a string.
2695On some platforms, path may also be specified as an open file descriptor.
2696 If this functionality is unavailable, using it raises an exception.
2697[clinic start generated code]*/
2698
Larry Hastings2f936352014-08-05 14:04:04 +10002699static PyObject *
2700os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002701/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002702{
2703 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704
2705 Py_BEGIN_ALLOW_THREADS
2706#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002707 if (path->wide)
2708 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 else
Larry Hastings2f936352014-08-05 14:04:04 +10002710 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002711 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#else
2713#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002714 if (path->fd != -1)
2715 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 else
2717#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002718 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719#endif
2720 Py_END_ALLOW_THREADS
2721
2722 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002723 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 }
2725
Larry Hastings2f936352014-08-05 14:04:04 +10002726 Py_RETURN_NONE;
2727}
2728
2729
2730#ifdef HAVE_FCHDIR
2731/*[clinic input]
2732os.fchdir
2733
2734 fd: fildes
2735
2736Change to the directory of the given file descriptor.
2737
2738fd must be opened on a directory, not a file.
2739Equivalent to os.chdir(fd).
2740
2741[clinic start generated code]*/
2742
Fred Drake4d1e64b2002-04-15 19:40:07 +00002743static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002744os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002745/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002746{
Larry Hastings2f936352014-08-05 14:04:04 +10002747 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002748}
2749#endif /* HAVE_FCHDIR */
2750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002751
Larry Hastings2f936352014-08-05 14:04:04 +10002752/*[clinic input]
2753os.chmod
2754
2755 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2756 Path to be modified. May always be specified as a str or bytes.
2757 On some platforms, path may also be specified as an open file descriptor.
2758 If this functionality is unavailable, using it raises an exception.
2759
2760 mode: int
2761 Operating-system mode bitfield.
2762
2763 *
2764
2765 dir_fd : dir_fd(requires='fchmodat') = None
2766 If not None, it should be a file descriptor open to a directory,
2767 and path should be relative; path will then be relative to that
2768 directory.
2769
2770 follow_symlinks: bool = True
2771 If False, and the last element of the path is a symbolic link,
2772 chmod will modify the symbolic link itself instead of the file
2773 the link points to.
2774
2775Change the access permissions of a file.
2776
2777It is an error to use dir_fd or follow_symlinks when specifying path as
2778 an open file descriptor.
2779dir_fd and follow_symlinks may not be implemented on your platform.
2780 If they are unavailable, using them will raise a NotImplementedError.
2781
2782[clinic start generated code]*/
2783
Larry Hastings2f936352014-08-05 14:04:04 +10002784static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002785os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2786 int follow_symlinks)
2787/*[clinic end generated code: output=05e7f73b1a843ba2 input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002788{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002789 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002791#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002794
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795#ifdef HAVE_FCHMODAT
2796 int fchmodat_nofollow_unsupported = 0;
2797#endif
2798
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2800 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002801 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#endif
2803
2804#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002805 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002806 if (path->wide)
2807 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 else
Larry Hastings2f936352014-08-05 14:04:04 +10002809 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002810 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 result = 0;
2812 else {
2813 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 attr &= ~FILE_ATTRIBUTE_READONLY;
2815 else
2816 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002817 if (path->wide)
2818 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 else
Larry Hastings2f936352014-08-05 14:04:04 +10002820 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821 }
2822 Py_END_ALLOW_THREADS
2823
2824 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002825 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 }
2827#else /* MS_WINDOWS */
2828 Py_BEGIN_ALLOW_THREADS
2829#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002830 if (path->fd != -1)
2831 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832 else
2833#endif
2834#ifdef HAVE_LCHMOD
2835 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002836 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 else
2838#endif
2839#ifdef HAVE_FCHMODAT
2840 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2841 /*
2842 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2843 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002844 * and then says it isn't implemented yet.
2845 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002846 *
2847 * Once it is supported, os.chmod will automatically
2848 * support dir_fd and follow_symlinks=False. (Hopefully.)
2849 * Until then, we need to be careful what exception we raise.
2850 */
Larry Hastings2f936352014-08-05 14:04:04 +10002851 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2853 /*
2854 * But wait! We can't throw the exception without allowing threads,
2855 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2856 */
2857 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002858 result &&
2859 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2860 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 }
2862 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002863#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002864 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865 Py_END_ALLOW_THREADS
2866
2867 if (result) {
2868#ifdef HAVE_FCHMODAT
2869 if (fchmodat_nofollow_unsupported) {
2870 if (dir_fd != DEFAULT_DIR_FD)
2871 dir_fd_and_follow_symlinks_invalid("chmod",
2872 dir_fd, follow_symlinks);
2873 else
2874 follow_symlinks_specified("chmod", follow_symlinks);
2875 }
2876 else
2877#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002878 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 }
2880#endif
2881
Larry Hastings2f936352014-08-05 14:04:04 +10002882 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002883}
2884
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885
Christian Heimes4e30a842007-11-30 22:12:06 +00002886#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002887/*[clinic input]
2888os.fchmod
2889
2890 fd: int
2891 mode: int
2892
2893Change the access permissions of the file given by file descriptor fd.
2894
2895Equivalent to os.chmod(fd, mode).
2896[clinic start generated code]*/
2897
Larry Hastings2f936352014-08-05 14:04:04 +10002898static PyObject *
2899os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002900/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002901{
2902 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002903 int async_err = 0;
2904
2905 do {
2906 Py_BEGIN_ALLOW_THREADS
2907 res = fchmod(fd, mode);
2908 Py_END_ALLOW_THREADS
2909 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2910 if (res != 0)
2911 return (!async_err) ? posix_error() : NULL;
2912
Victor Stinner8c62be82010-05-06 00:08:46 +00002913 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002914}
2915#endif /* HAVE_FCHMOD */
2916
Larry Hastings2f936352014-08-05 14:04:04 +10002917
Christian Heimes4e30a842007-11-30 22:12:06 +00002918#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002919/*[clinic input]
2920os.lchmod
2921
2922 path: path_t
2923 mode: int
2924
2925Change the access permissions of a file, without following symbolic links.
2926
2927If path is a symlink, this affects the link itself rather than the target.
2928Equivalent to chmod(path, mode, follow_symlinks=False)."
2929[clinic start generated code]*/
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931static PyObject *
2932os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002933/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002934{
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002937 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002939 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002940 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002941 return NULL;
2942 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002944}
2945#endif /* HAVE_LCHMOD */
2946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Thomas Wouterscf297e42007-02-23 15:07:44 +00002948#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002949/*[clinic input]
2950os.chflags
2951
2952 path: path_t
2953 flags: unsigned_long(bitwise=True)
2954 follow_symlinks: bool=True
2955
2956Set file flags.
2957
2958If follow_symlinks is False, and the last element of the path is a symbolic
2959 link, chflags will change flags on the symbolic link itself instead of the
2960 file the link points to.
2961follow_symlinks may not be implemented on your platform. If it is
2962unavailable, using it will raise a NotImplementedError.
2963
2964[clinic start generated code]*/
2965
Larry Hastings2f936352014-08-05 14:04:04 +10002966static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002967os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags,
2968 int follow_symlinks)
2969/*[clinic end generated code: output=ff2d6e73534a95b9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002970{
2971 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
2973#ifndef HAVE_LCHFLAGS
2974 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002975 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002976#endif
2977
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#ifdef HAVE_LCHFLAGS
2980 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002981 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982 else
2983#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002984 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986
Larry Hastings2f936352014-08-05 14:04:04 +10002987 if (result)
2988 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989
Larry Hastings2f936352014-08-05 14:04:04 +10002990 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002991}
2992#endif /* HAVE_CHFLAGS */
2993
Larry Hastings2f936352014-08-05 14:04:04 +10002994
Thomas Wouterscf297e42007-02-23 15:07:44 +00002995#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002996/*[clinic input]
2997os.lchflags
2998
2999 path: path_t
3000 flags: unsigned_long(bitwise=True)
3001
3002Set file flags.
3003
3004This function will not follow symbolic links.
3005Equivalent to chflags(path, flags, follow_symlinks=False).
3006[clinic start generated code]*/
3007
Larry Hastings2f936352014-08-05 14:04:04 +10003008static PyObject *
3009os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003010/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003011{
Victor Stinner8c62be82010-05-06 00:08:46 +00003012 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003014 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003016 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003017 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003018 }
Victor Stinner292c8352012-10-30 02:17:38 +01003019 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003020}
3021#endif /* HAVE_LCHFLAGS */
3022
Larry Hastings2f936352014-08-05 14:04:04 +10003023
Martin v. Löwis244edc82001-10-04 22:44:26 +00003024#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003025/*[clinic input]
3026os.chroot
3027 path: path_t
3028
3029Change root directory to path.
3030
3031[clinic start generated code]*/
3032
Larry Hastings2f936352014-08-05 14:04:04 +10003033static PyObject *
3034os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003035/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003036{
3037 int res;
3038 Py_BEGIN_ALLOW_THREADS
3039 res = chroot(path->narrow);
3040 Py_END_ALLOW_THREADS
3041 if (res < 0)
3042 return path_error(path);
3043 Py_RETURN_NONE;
3044}
3045#endif /* HAVE_CHROOT */
3046
Martin v. Löwis244edc82001-10-04 22:44:26 +00003047
Guido van Rossum21142a01999-01-08 21:05:37 +00003048#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003049/*[clinic input]
3050os.fsync
3051
3052 fd: fildes
3053
3054Force write of fd to disk.
3055[clinic start generated code]*/
3056
Larry Hastings2f936352014-08-05 14:04:04 +10003057static PyObject *
3058os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003059/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003060{
3061 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003062}
3063#endif /* HAVE_FSYNC */
3064
Larry Hastings2f936352014-08-05 14:04:04 +10003065
Ross Lagerwall7807c352011-03-17 20:20:30 +02003066#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003067/*[clinic input]
3068os.sync
3069
3070Force write of everything to disk.
3071[clinic start generated code]*/
3072
Larry Hastings2f936352014-08-05 14:04:04 +10003073static PyObject *
3074os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003075/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003076{
3077 Py_BEGIN_ALLOW_THREADS
3078 sync();
3079 Py_END_ALLOW_THREADS
3080 Py_RETURN_NONE;
3081}
Larry Hastings2f936352014-08-05 14:04:04 +10003082#endif /* HAVE_SYNC */
3083
Ross Lagerwall7807c352011-03-17 20:20:30 +02003084
Guido van Rossum21142a01999-01-08 21:05:37 +00003085#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003086#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003087extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3088#endif
3089
Larry Hastings2f936352014-08-05 14:04:04 +10003090/*[clinic input]
3091os.fdatasync
3092
3093 fd: fildes
3094
3095Force write of fd to disk without forcing update of metadata.
3096[clinic start generated code]*/
3097
Larry Hastings2f936352014-08-05 14:04:04 +10003098static PyObject *
3099os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003100/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003101{
3102 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003103}
3104#endif /* HAVE_FDATASYNC */
3105
3106
Fredrik Lundh10723342000-07-10 16:38:09 +00003107#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003108/*[clinic input]
3109os.chown
3110
3111 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3112 Path to be examined; can be string, bytes, or open-file-descriptor int.
3113
3114 uid: uid_t
3115
3116 gid: gid_t
3117
3118 *
3119
3120 dir_fd : dir_fd(requires='fchownat') = None
3121 If not None, it should be a file descriptor open to a directory,
3122 and path should be relative; path will then be relative to that
3123 directory.
3124
3125 follow_symlinks: bool = True
3126 If False, and the last element of the path is a symbolic link,
3127 stat will examine the symbolic link itself instead of the file
3128 the link points to.
3129
3130Change the owner and group id of path to the numeric uid and gid.\
3131
3132path may always be specified as a string.
3133On some platforms, path may also be specified as an open file descriptor.
3134 If this functionality is unavailable, using it raises an exception.
3135If dir_fd is not None, it should be a file descriptor open to a directory,
3136 and path should be relative; path will then be relative to that directory.
3137If follow_symlinks is False, and the last element of the path is a symbolic
3138 link, chown will modify the symbolic link itself instead of the file the
3139 link points to.
3140It is an error to use dir_fd or follow_symlinks when specifying path as
3141 an open file descriptor.
3142dir_fd and follow_symlinks may not be implemented on your platform.
3143 If they are unavailable, using them will raise a NotImplementedError.
3144
3145[clinic start generated code]*/
3146
Larry Hastings2f936352014-08-05 14:04:04 +10003147static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003148os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid,
3149 int dir_fd, int follow_symlinks)
3150/*[clinic end generated code: output=e0a4559f394dbd91 input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003151{
3152 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153
3154#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3155 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003156 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003158 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3159 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3160 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161
3162#ifdef __APPLE__
3163 /*
3164 * This is for Mac OS X 10.3, which doesn't have lchown.
3165 * (But we still have an lchown symbol because of weak-linking.)
3166 * It doesn't have fchownat either. So there's no possibility
3167 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003168 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 if ((!follow_symlinks) && (lchown == NULL)) {
3170 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003171 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172 }
3173#endif
3174
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003176#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003177 if (path->fd != -1)
3178 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179 else
3180#endif
3181#ifdef HAVE_LCHOWN
3182 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003183 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 else
3185#endif
3186#ifdef HAVE_FCHOWNAT
3187 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3190 else
3191#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003192 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194
Larry Hastings2f936352014-08-05 14:04:04 +10003195 if (result)
3196 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197
Larry Hastings2f936352014-08-05 14:04:04 +10003198 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003199}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003200#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003201
Larry Hastings2f936352014-08-05 14:04:04 +10003202
Christian Heimes4e30a842007-11-30 22:12:06 +00003203#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003204/*[clinic input]
3205os.fchown
3206
3207 fd: int
3208 uid: uid_t
3209 gid: gid_t
3210
3211Change the owner and group id of the file specified by file descriptor.
3212
3213Equivalent to os.chown(fd, uid, gid).
3214
3215[clinic start generated code]*/
3216
Larry Hastings2f936352014-08-05 14:04:04 +10003217static PyObject *
3218os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003219/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003220{
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003222 int async_err = 0;
3223
3224 do {
3225 Py_BEGIN_ALLOW_THREADS
3226 res = fchown(fd, uid, gid);
3227 Py_END_ALLOW_THREADS
3228 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3229 if (res != 0)
3230 return (!async_err) ? posix_error() : NULL;
3231
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003233}
3234#endif /* HAVE_FCHOWN */
3235
Larry Hastings2f936352014-08-05 14:04:04 +10003236
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003237#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003238/*[clinic input]
3239os.lchown
3240
3241 path : path_t
3242 uid: uid_t
3243 gid: gid_t
3244
3245Change the owner and group id of path to the numeric uid and gid.
3246
3247This function will not follow symbolic links.
3248Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3249[clinic start generated code]*/
3250
Larry Hastings2f936352014-08-05 14:04:04 +10003251static PyObject *
3252os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003253/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003254{
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003257 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003259 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003260 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003261 }
Larry Hastings2f936352014-08-05 14:04:04 +10003262 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003263}
3264#endif /* HAVE_LCHOWN */
3265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003268posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003269{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003270 char *buf, *tmpbuf;
3271 char *cwd;
3272 const size_t chunk = 1024;
3273 size_t buflen = 0;
3274 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003275
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003276#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003278 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 wchar_t *wbuf2 = wbuf;
3280 PyObject *resobj;
3281 DWORD len;
3282 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003283 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 /* If the buffer is large enough, len does not include the
3285 terminating \0. If the buffer is too small, len includes
3286 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003287 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003288 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 if (wbuf2)
3290 len = GetCurrentDirectoryW(len, wbuf2);
3291 }
3292 Py_END_ALLOW_THREADS
3293 if (!wbuf2) {
3294 PyErr_NoMemory();
3295 return NULL;
3296 }
3297 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003298 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003299 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003300 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 }
3302 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003304 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 return resobj;
3306 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003307
3308 if (win32_warn_bytes_api())
3309 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003310#endif
3311
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314 do {
3315 buflen += chunk;
3316 tmpbuf = PyMem_RawRealloc(buf, buflen);
3317 if (tmpbuf == NULL)
3318 break;
3319
3320 buf = tmpbuf;
3321 cwd = getcwd(buf, buflen);
3322 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003324
3325 if (cwd == NULL) {
3326 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 }
3329
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003331 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3332 else
3333 obj = PyUnicode_DecodeFSDefault(buf);
3334 PyMem_RawFree(buf);
3335
3336 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003337}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003338
Larry Hastings2f936352014-08-05 14:04:04 +10003339
3340/*[clinic input]
3341os.getcwd
3342
3343Return a unicode string representing the current working directory.
3344[clinic start generated code]*/
3345
Larry Hastings2f936352014-08-05 14:04:04 +10003346static PyObject *
3347os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003348/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003349{
3350 return posix_getcwd(0);
3351}
3352
Larry Hastings2f936352014-08-05 14:04:04 +10003353
3354/*[clinic input]
3355os.getcwdb
3356
3357Return a bytes string representing the current working directory.
3358[clinic start generated code]*/
3359
Larry Hastings2f936352014-08-05 14:04:04 +10003360static PyObject *
3361os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003362/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003363{
3364 return posix_getcwd(1);
3365}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003366
Larry Hastings2f936352014-08-05 14:04:04 +10003367
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3369#define HAVE_LINK 1
3370#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Guido van Rossumb6775db1994-08-01 11:34:53 +00003372#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003373/*[clinic input]
3374
3375os.link
3376
3377 src : path_t
3378 dst : path_t
3379 *
3380 src_dir_fd : dir_fd = None
3381 dst_dir_fd : dir_fd = None
3382 follow_symlinks: bool = True
3383
3384Create a hard link to a file.
3385
3386If either src_dir_fd or dst_dir_fd is not None, it should be a file
3387 descriptor open to a directory, and the respective path string (src or dst)
3388 should be relative; the path will then be relative to that directory.
3389If follow_symlinks is False, and the last element of src is a symbolic
3390 link, link will create a link to the symbolic link itself instead of the
3391 file the link points to.
3392src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3393 platform. If they are unavailable, using them will raise a
3394 NotImplementedError.
3395[clinic start generated code]*/
3396
Larry Hastings2f936352014-08-05 14:04:04 +10003397static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003398os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
3399 int dst_dir_fd, int follow_symlinks)
3400/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402#ifdef MS_WINDOWS
3403 BOOL result;
3404#else
3405 int result;
3406#endif
3407
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408#ifndef HAVE_LINKAT
3409 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3410 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003411 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412 }
3413#endif
3414
Larry Hastings2f936352014-08-05 14:04:04 +10003415 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 PyErr_SetString(PyExc_NotImplementedError,
3417 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003418 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003420
Brian Curtin1b9df392010-11-24 20:24:31 +00003421#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003423 if (src->wide)
3424 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 else
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003428
Larry Hastings2f936352014-08-05 14:04:04 +10003429 if (!result)
3430 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431#else
3432 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003433#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3435 (dst_dir_fd != DEFAULT_DIR_FD) ||
3436 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003437 result = linkat(src_dir_fd, src->narrow,
3438 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3440 else
3441#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003442 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003444
Larry Hastings2f936352014-08-05 14:04:04 +10003445 if (result)
3446 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447#endif
3448
Larry Hastings2f936352014-08-05 14:04:04 +10003449 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003450}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451#endif
3452
Brian Curtin1b9df392010-11-24 20:24:31 +00003453
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003454#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003455static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003456_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003457{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 PyObject *v;
3459 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3460 BOOL result;
3461 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003462 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 char *bufptr = namebuf;
3464 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003465 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 PyObject *po = NULL;
3467 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468
Gregory P. Smith40a21602013-03-20 20:52:50 -07003469 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003472
Gregory P. Smith40a21602013-03-20 20:52:50 -07003473 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003474 po_wchars = L".";
3475 len = 1;
3476 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003477 po_wchars = path->wide;
3478 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003479 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003481 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 if (!wnamebuf) {
3483 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003486 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003488 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003489 if (wch != SEP && wch != ALTSEP && wch != L':')
3490 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 wcscpy(wnamebuf + len, L"*.*");
3492 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 if ((list = PyList_New(0)) == NULL) {
3494 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003496 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003498 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 if (hFindFile == INVALID_HANDLE_VALUE) {
3500 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 if (error == ERROR_FILE_NOT_FOUND)
3502 goto exit;
3503 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003504 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 }
3507 do {
3508 /* Skip over . and .. */
3509 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3510 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 v = PyUnicode_FromWideChar(wFileData.cFileName,
3512 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 Py_DECREF(list);
3515 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 break;
3517 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 break;
3523 }
3524 Py_DECREF(v);
3525 }
3526 Py_BEGIN_ALLOW_THREADS
3527 result = FindNextFileW(hFindFile, &wFileData);
3528 Py_END_ALLOW_THREADS
3529 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3530 it got to the end of the directory. */
3531 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003533 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
3536 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003537
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003540 strcpy(namebuf, path->narrow);
3541 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 if (len > 0) {
3543 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003544 if (ch != '\\' && ch != '/' && ch != ':')
3545 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 strcpy(namebuf + len, "*.*");
3547 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003548
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003551
Antoine Pitroub73caab2010-08-09 23:39:31 +00003552 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003554 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 if (hFindFile == INVALID_HANDLE_VALUE) {
3556 int error = GetLastError();
3557 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 goto exit;
3559 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003560 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 }
3563 do {
3564 /* Skip over . and .. */
3565 if (strcmp(FileData.cFileName, ".") != 0 &&
3566 strcmp(FileData.cFileName, "..") != 0) {
3567 v = PyBytes_FromString(FileData.cFileName);
3568 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 Py_DECREF(list);
3570 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 break;
3572 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 Py_DECREF(list);
3576 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 break;
3578 }
3579 Py_DECREF(v);
3580 }
3581 Py_BEGIN_ALLOW_THREADS
3582 result = FindNextFile(hFindFile, &FileData);
3583 Py_END_ALLOW_THREADS
3584 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3585 it got to the end of the directory. */
3586 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003588 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
3591 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003592
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593exit:
3594 if (hFindFile != INVALID_HANDLE_VALUE) {
3595 if (FindClose(hFindFile) == FALSE) {
3596 if (list != NULL) {
3597 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 }
3600 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003602 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003603
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003605} /* end of _listdir_windows_no_opendir */
3606
3607#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3608
3609static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003611{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003612 PyObject *v;
3613 DIR *dirp = NULL;
3614 struct dirent *ep;
3615 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003616#ifdef HAVE_FDOPENDIR
3617 int fd = -1;
3618#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003619
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003622 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003624 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003625 if (fd == -1)
3626 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627
Larry Hastingsfdaea062012-06-25 04:42:23 -07003628 return_str = 1;
3629
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 Py_BEGIN_ALLOW_THREADS
3631 dirp = fdopendir(fd);
3632 Py_END_ALLOW_THREADS
3633 }
3634 else
3635#endif
3636 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003637 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003638 if (path->narrow) {
3639 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003640 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 }
3643 else {
3644 name = ".";
3645 return_str = 1;
3646 }
3647
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648 Py_BEGIN_ALLOW_THREADS
3649 dirp = opendir(name);
3650 Py_END_ALLOW_THREADS
3651 }
3652
3653 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003654 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003655#ifdef HAVE_FDOPENDIR
3656 if (fd != -1) {
3657 Py_BEGIN_ALLOW_THREADS
3658 close(fd);
3659 Py_END_ALLOW_THREADS
3660 }
3661#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 goto exit;
3663 }
3664 if ((list = PyList_New(0)) == NULL) {
3665 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 }
3667 for (;;) {
3668 errno = 0;
3669 Py_BEGIN_ALLOW_THREADS
3670 ep = readdir(dirp);
3671 Py_END_ALLOW_THREADS
3672 if (ep == NULL) {
3673 if (errno == 0) {
3674 break;
3675 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003677 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 }
3680 }
3681 if (ep->d_name[0] == '.' &&
3682 (NAMLEN(ep) == 1 ||
3683 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3684 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003685 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003686 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3687 else
3688 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 break;
3692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
3698 Py_DECREF(v);
3699 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003700
Larry Hastings9cf065c2012-06-22 16:30:09 -07003701exit:
3702 if (dirp != NULL) {
3703 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003704#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003705 if (fd > -1)
3706 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003707#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 closedir(dirp);
3709 Py_END_ALLOW_THREADS
3710 }
3711
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003713} /* end of _posix_listdir */
3714#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003715
Larry Hastings2f936352014-08-05 14:04:04 +10003716
3717/*[clinic input]
3718os.listdir
3719
3720 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3721
3722Return a list containing the names of the files in the directory.
3723
3724path can be specified as either str or bytes. If path is bytes,
3725 the filenames returned will also be bytes; in all other circumstances
3726 the filenames returned will be str.
3727If path is None, uses the path='.'.
3728On some platforms, path may also be specified as an open file descriptor;\
3729 the file descriptor must refer to a directory.
3730 If this functionality is unavailable, using it raises NotImplementedError.
3731
3732The list is in arbitrary order. It does not include the special
3733entries '.' and '..' even if they are present in the directory.
3734
3735
3736[clinic start generated code]*/
3737
Larry Hastings2f936352014-08-05 14:04:04 +10003738static PyObject *
3739os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003740/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003741{
3742#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3743 return _listdir_windows_no_opendir(path, NULL);
3744#else
3745 return _posix_listdir(path, NULL);
3746#endif
3747}
3748
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003749#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003750/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003751/*[clinic input]
3752os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003753
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003754 path: path_t
3755 /
3756
3757[clinic start generated code]*/
3758
3759static PyObject *
3760os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3761/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3762{
3763 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003764 {
Victor Stinner75875072013-11-24 19:23:25 +01003765 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003766 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 DWORD result;
3768 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003770 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003771 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003773 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003774 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 if (!woutbufp)
3776 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003777 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 }
3779 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003780 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003782 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003784 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003785 return v;
3786 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 else {
3788 char outbuf[MAX_PATH];
3789 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003790
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003791 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3792 outbuf, &temp)) {
3793 win32_error_object("GetFullPathName", path->object);
3794 return NULL;
3795 }
3796 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 }
Larry Hastings2f936352014-08-05 14:04:04 +10003798}
Brian Curtind40e6f72010-07-08 21:39:08 +00003799
Brian Curtind25aef52011-06-13 15:16:04 -05003800
Larry Hastings2f936352014-08-05 14:04:04 +10003801/*[clinic input]
3802os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003803
Larry Hastings2f936352014-08-05 14:04:04 +10003804 path: unicode
3805 /
3806
3807A helper function for samepath on windows.
3808[clinic start generated code]*/
3809
Larry Hastings2f936352014-08-05 14:04:04 +10003810static PyObject *
3811os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003812/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003813{
3814 HANDLE hFile;
3815 int buf_size;
3816 wchar_t *target_path;
3817 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003818 PyObject *result;
3819 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003820
Larry Hastings2f936352014-08-05 14:04:04 +10003821 path_wchar = PyUnicode_AsUnicode(path);
3822 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003823 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003824
Brian Curtind40e6f72010-07-08 21:39:08 +00003825 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003826 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003827 0, /* desired access */
3828 0, /* share mode */
3829 NULL, /* security attributes */
3830 OPEN_EXISTING,
3831 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3832 FILE_FLAG_BACKUP_SEMANTICS,
3833 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003834
Victor Stinnereb5657a2011-09-30 01:44:27 +02003835 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003836 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003837
3838 /* We have a good handle to the target, use it to determine the
3839 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003840 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003841
3842 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003843 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003844
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003845 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003846 if(!target_path)
3847 return PyErr_NoMemory();
3848
Steve Dower2ea51c92015-03-20 21:49:12 -07003849 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3850 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003852 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003853
3854 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003855 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856
3857 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003858 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003859 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003860 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003861}
Brian Curtin62857742010-09-06 17:07:27 +00003862
Brian Curtin95d028f2011-06-09 09:10:38 -05003863PyDoc_STRVAR(posix__isdir__doc__,
3864"Return true if the pathname refers to an existing directory.");
3865
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003866/*[clinic input]
3867os._isdir
3868
3869 path: path_t
3870 /
3871
3872[clinic start generated code]*/
3873
Brian Curtin9c669cc2011-06-08 18:17:18 -05003874static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003875os__isdir_impl(PyModuleDef *module, path_t *path)
3876/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003877{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003878 DWORD attributes;
3879
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003880 if (!path->narrow)
3881 attributes = GetFileAttributesW(path->wide);
3882 else
3883 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003884
Brian Curtin9c669cc2011-06-08 18:17:18 -05003885 if (attributes == INVALID_FILE_ATTRIBUTES)
3886 Py_RETURN_FALSE;
3887
Brian Curtin9c669cc2011-06-08 18:17:18 -05003888 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3889 Py_RETURN_TRUE;
3890 else
3891 Py_RETURN_FALSE;
3892}
Tim Golden6b528062013-08-01 12:44:00 +01003893
Tim Golden6b528062013-08-01 12:44:00 +01003894
Larry Hastings2f936352014-08-05 14:04:04 +10003895/*[clinic input]
3896os._getvolumepathname
3897
3898 path: unicode
3899
3900A helper function for ismount on Win32.
3901[clinic start generated code]*/
3902
Larry Hastings2f936352014-08-05 14:04:04 +10003903static PyObject *
3904os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003905/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003906{
3907 PyObject *result;
3908 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003909 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003910 BOOL ret;
3911
Larry Hastings2f936352014-08-05 14:04:04 +10003912 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3913 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003914 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003915 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003916
3917 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003918 buflen = Py_MAX(buflen, MAX_PATH);
3919
3920 if (buflen > DWORD_MAX) {
3921 PyErr_SetString(PyExc_OverflowError, "path too long");
3922 return NULL;
3923 }
3924
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003925 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003926 if (mountpath == NULL)
3927 return PyErr_NoMemory();
3928
3929 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003930 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003931 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003932 Py_END_ALLOW_THREADS
3933
3934 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003935 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003936 goto exit;
3937 }
3938 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3939
3940exit:
3941 PyMem_Free(mountpath);
3942 return result;
3943}
Tim Golden6b528062013-08-01 12:44:00 +01003944
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003945#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003946
Larry Hastings2f936352014-08-05 14:04:04 +10003947
3948/*[clinic input]
3949os.mkdir
3950
3951 path : path_t
3952
3953 mode: int = 0o777
3954
3955 *
3956
3957 dir_fd : dir_fd(requires='mkdirat') = None
3958
3959# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3960
3961Create a directory.
3962
3963If dir_fd is not None, it should be a file descriptor open to a directory,
3964 and path should be relative; path will then be relative to that directory.
3965dir_fd may not be implemented on your platform.
3966 If it is unavailable, using it will raise a NotImplementedError.
3967
3968The mode argument is ignored on Windows.
3969[clinic start generated code]*/
3970
Larry Hastings2f936352014-08-05 14:04:04 +10003971static PyObject *
3972os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003973/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003974{
3975 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003976
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003977#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003979 if (path->wide)
3980 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981 else
Larry Hastings2f936352014-08-05 14:04:04 +10003982 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984
Larry Hastings2f936352014-08-05 14:04:04 +10003985 if (!result)
3986 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003988 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989#if HAVE_MKDIRAT
3990 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003991 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992 else
3993#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003994#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003995 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003996#else
Larry Hastings2f936352014-08-05 14:04:04 +10003997 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003998#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003999 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004000 if (result < 0)
4001 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004002#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004003 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004004}
4005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004006
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004007/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4008#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004009#include <sys/resource.h>
4010#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004011
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004012
4013#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004014/*[clinic input]
4015os.nice
4016
4017 increment: int
4018 /
4019
4020Add increment to the priority of process and return the new priority.
4021[clinic start generated code]*/
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023static PyObject *
4024os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004025/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004026{
4027 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004028
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 /* There are two flavours of 'nice': one that returns the new
4030 priority (as required by almost all standards out there) and the
4031 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4032 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004033
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 If we are of the nice family that returns the new priority, we
4035 need to clear errno before the call, and check if errno is filled
4036 before calling posix_error() on a returnvalue of -1, because the
4037 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004038
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 errno = 0;
4040 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004041#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 if (value == 0)
4043 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004044#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 if (value == -1 && errno != 0)
4046 /* either nice() or getpriority() returned an error */
4047 return posix_error();
4048 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004049}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004050#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004051
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004052
4053#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004054/*[clinic input]
4055os.getpriority
4056
4057 which: int
4058 who: int
4059
4060Return program scheduling priority.
4061[clinic start generated code]*/
4062
Larry Hastings2f936352014-08-05 14:04:04 +10004063static PyObject *
4064os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004065/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004066{
4067 int retval;
4068
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004069 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004070 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004071 if (errno != 0)
4072 return posix_error();
4073 return PyLong_FromLong((long)retval);
4074}
4075#endif /* HAVE_GETPRIORITY */
4076
4077
4078#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004079/*[clinic input]
4080os.setpriority
4081
4082 which: int
4083 who: int
4084 priority: int
4085
4086Set program scheduling priority.
4087[clinic start generated code]*/
4088
Larry Hastings2f936352014-08-05 14:04:04 +10004089static PyObject *
4090os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004091/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004092{
4093 int retval;
4094
4095 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004096 if (retval == -1)
4097 return posix_error();
4098 Py_RETURN_NONE;
4099}
4100#endif /* HAVE_SETPRIORITY */
4101
4102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004104internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004109#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004110 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004111 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004112#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004114#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4117 (dst_dir_fd != DEFAULT_DIR_FD);
4118#ifndef HAVE_RENAMEAT
4119 if (dir_fd_specified) {
4120 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004121 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 }
4123#endif
4124
Larry Hastings2f936352014-08-05 14:04:04 +10004125 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 PyErr_Format(PyExc_ValueError,
4127 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004128 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 }
4130
4131#ifdef MS_WINDOWS
4132 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004133 if (src->wide)
4134 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 else
Larry Hastings2f936352014-08-05 14:04:04 +10004136 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 Py_END_ALLOW_THREADS
4138
Larry Hastings2f936352014-08-05 14:04:04 +10004139 if (!result)
4140 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141
4142#else
4143 Py_BEGIN_ALLOW_THREADS
4144#ifdef HAVE_RENAMEAT
4145 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004146 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 else
4148#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004149 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 Py_END_ALLOW_THREADS
4151
Larry Hastings2f936352014-08-05 14:04:04 +10004152 if (result)
4153 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004155 Py_RETURN_NONE;
4156}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004157
Larry Hastings2f936352014-08-05 14:04:04 +10004158
4159/*[clinic input]
4160os.rename
4161
4162 src : path_t
4163 dst : path_t
4164 *
4165 src_dir_fd : dir_fd = None
4166 dst_dir_fd : dir_fd = None
4167
4168Rename a file or directory.
4169
4170If either src_dir_fd or dst_dir_fd is not None, it should be a file
4171 descriptor open to a directory, and the respective path string (src or dst)
4172 should be relative; the path will then be relative to that directory.
4173src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4174 If they are unavailable, using them will raise a NotImplementedError.
4175[clinic start generated code]*/
4176
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004177static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004178os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4179 int dst_dir_fd)
4180/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004181{
Larry Hastings2f936352014-08-05 14:04:04 +10004182 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004183}
4184
Larry Hastings2f936352014-08-05 14:04:04 +10004185
4186/*[clinic input]
4187os.replace = os.rename
4188
4189Rename a file or directory, overwriting the destination.
4190
4191If either src_dir_fd or dst_dir_fd is not None, it should be a file
4192 descriptor open to a directory, and the respective path string (src or dst)
4193 should be relative; the path will then be relative to that directory.
4194src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4195 If they are unavailable, using them will raise a NotImplementedError."
4196[clinic start generated code]*/
4197
Larry Hastings2f936352014-08-05 14:04:04 +10004198static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004199os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4200 int src_dir_fd, int dst_dir_fd)
4201/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004202{
4203 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4204}
4205
4206
4207/*[clinic input]
4208os.rmdir
4209
4210 path: path_t
4211 *
4212 dir_fd: dir_fd(requires='unlinkat') = None
4213
4214Remove a directory.
4215
4216If dir_fd is not None, it should be a file descriptor open to a directory,
4217 and path should be relative; path will then be relative to that directory.
4218dir_fd may not be implemented on your platform.
4219 If it is unavailable, using it will raise a NotImplementedError.
4220[clinic start generated code]*/
4221
Larry Hastings2f936352014-08-05 14:04:04 +10004222static PyObject *
4223os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004224/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004225{
4226 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004227
4228 Py_BEGIN_ALLOW_THREADS
4229#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004230 if (path->wide)
4231 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232 else
Larry Hastings2f936352014-08-05 14:04:04 +10004233 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234 result = !result; /* Windows, success=1, UNIX, success=0 */
4235#else
4236#ifdef HAVE_UNLINKAT
4237 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 else
4240#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004241 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004242#endif
4243 Py_END_ALLOW_THREADS
4244
Larry Hastings2f936352014-08-05 14:04:04 +10004245 if (result)
4246 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247
Larry Hastings2f936352014-08-05 14:04:04 +10004248 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004249}
4250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004251
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004252#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004253#ifdef MS_WINDOWS
4254/*[clinic input]
4255os.system -> long
4256
4257 command: Py_UNICODE
4258
4259Execute the command in a subshell.
4260[clinic start generated code]*/
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262static long
4263os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004264/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004265{
4266 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004268 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004270 return result;
4271}
4272#else /* MS_WINDOWS */
4273/*[clinic input]
4274os.system -> long
4275
4276 command: FSConverter
4277
4278Execute the command in a subshell.
4279[clinic start generated code]*/
4280
Larry Hastings2f936352014-08-05 14:04:04 +10004281static long
4282os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004283/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004284{
4285 long result;
4286 char *bytes = PyBytes_AsString(command);
4287 Py_BEGIN_ALLOW_THREADS
4288 result = system(bytes);
4289 Py_END_ALLOW_THREADS
4290 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004291}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004292#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004293#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Larry Hastings2f936352014-08-05 14:04:04 +10004296/*[clinic input]
4297os.umask
4298
4299 mask: int
4300 /
4301
4302Set the current numeric umask and return the previous umask.
4303[clinic start generated code]*/
4304
Larry Hastings2f936352014-08-05 14:04:04 +10004305static PyObject *
4306os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004307/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004308{
4309 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 if (i < 0)
4311 return posix_error();
4312 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004313}
4314
Brian Curtind40e6f72010-07-08 21:39:08 +00004315#ifdef MS_WINDOWS
4316
4317/* override the default DeleteFileW behavior so that directory
4318symlinks can be removed with this function, the same as with
4319Unix symlinks */
4320BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4321{
4322 WIN32_FILE_ATTRIBUTE_DATA info;
4323 WIN32_FIND_DATAW find_data;
4324 HANDLE find_data_handle;
4325 int is_directory = 0;
4326 int is_link = 0;
4327
4328 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4329 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004330
Brian Curtind40e6f72010-07-08 21:39:08 +00004331 /* Get WIN32_FIND_DATA structure for the path to determine if
4332 it is a symlink */
4333 if(is_directory &&
4334 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4335 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4336
4337 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004338 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4339 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4340 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4341 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004342 FindClose(find_data_handle);
4343 }
4344 }
4345 }
4346
4347 if (is_directory && is_link)
4348 return RemoveDirectoryW(lpFileName);
4349
4350 return DeleteFileW(lpFileName);
4351}
4352#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004354
Larry Hastings2f936352014-08-05 14:04:04 +10004355/*[clinic input]
4356os.unlink
4357
4358 path: path_t
4359 *
4360 dir_fd: dir_fd(requires='unlinkat')=None
4361
4362Remove a file (same as remove()).
4363
4364If dir_fd is not None, it should be a file descriptor open to a directory,
4365 and path should be relative; path will then be relative to that directory.
4366dir_fd may not be implemented on your platform.
4367 If it is unavailable, using it will raise a NotImplementedError.
4368
4369[clinic start generated code]*/
4370
Larry Hastings2f936352014-08-05 14:04:04 +10004371static PyObject *
4372os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004373/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004374{
4375 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376
4377 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004378 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004380 if (path->wide)
4381 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004382 else
Larry Hastings2f936352014-08-05 14:04:04 +10004383 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 result = !result; /* Windows, success=1, UNIX, success=0 */
4385#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386#ifdef HAVE_UNLINKAT
4387 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004388 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 else
4390#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004391 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004393 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 Py_END_ALLOW_THREADS
4395
Larry Hastings2f936352014-08-05 14:04:04 +10004396 if (result)
4397 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398
Larry Hastings2f936352014-08-05 14:04:04 +10004399 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004400}
4401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004402
Larry Hastings2f936352014-08-05 14:04:04 +10004403/*[clinic input]
4404os.remove = os.unlink
4405
4406Remove a file (same as unlink()).
4407
4408If dir_fd is not None, it should be a file descriptor open to a directory,
4409 and path should be relative; path will then be relative to that directory.
4410dir_fd may not be implemented on your platform.
4411 If it is unavailable, using it will raise a NotImplementedError.
4412[clinic start generated code]*/
4413
Larry Hastings2f936352014-08-05 14:04:04 +10004414static PyObject *
4415os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004416/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004417{
4418 return os_unlink_impl(module, path, dir_fd);
4419}
4420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004421
Larry Hastings605a62d2012-06-24 04:33:36 -07004422static PyStructSequence_Field uname_result_fields[] = {
4423 {"sysname", "operating system name"},
4424 {"nodename", "name of machine on network (implementation-defined)"},
4425 {"release", "operating system release"},
4426 {"version", "operating system version"},
4427 {"machine", "hardware identifier"},
4428 {NULL}
4429};
4430
4431PyDoc_STRVAR(uname_result__doc__,
4432"uname_result: Result from os.uname().\n\n\
4433This object may be accessed either as a tuple of\n\
4434 (sysname, nodename, release, version, machine),\n\
4435or via the attributes sysname, nodename, release, version, and machine.\n\
4436\n\
4437See os.uname for more information.");
4438
4439static PyStructSequence_Desc uname_result_desc = {
4440 "uname_result", /* name */
4441 uname_result__doc__, /* doc */
4442 uname_result_fields,
4443 5
4444};
4445
4446static PyTypeObject UnameResultType;
4447
4448
4449#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004450/*[clinic input]
4451os.uname
4452
4453Return an object identifying the current operating system.
4454
4455The object behaves like a named tuple with the following fields:
4456 (sysname, nodename, release, version, machine)
4457
4458[clinic start generated code]*/
4459
Larry Hastings2f936352014-08-05 14:04:04 +10004460static PyObject *
4461os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004462/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004463{
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 struct utsname u;
4465 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004466 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004467
Victor Stinner8c62be82010-05-06 00:08:46 +00004468 Py_BEGIN_ALLOW_THREADS
4469 res = uname(&u);
4470 Py_END_ALLOW_THREADS
4471 if (res < 0)
4472 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004473
4474 value = PyStructSequence_New(&UnameResultType);
4475 if (value == NULL)
4476 return NULL;
4477
4478#define SET(i, field) \
4479 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004480 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004481 if (!o) { \
4482 Py_DECREF(value); \
4483 return NULL; \
4484 } \
4485 PyStructSequence_SET_ITEM(value, i, o); \
4486 } \
4487
4488 SET(0, u.sysname);
4489 SET(1, u.nodename);
4490 SET(2, u.release);
4491 SET(3, u.version);
4492 SET(4, u.machine);
4493
4494#undef SET
4495
4496 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004498#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004499
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004500
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501
4502typedef struct {
4503 int now;
4504 time_t atime_s;
4505 long atime_ns;
4506 time_t mtime_s;
4507 long mtime_ns;
4508} utime_t;
4509
4510/*
Victor Stinner484df002014-10-09 13:52:31 +02004511 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 * they also intentionally leak the declaration of a pointer named "time"
4513 */
4514#define UTIME_TO_TIMESPEC \
4515 struct timespec ts[2]; \
4516 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004517 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 time = NULL; \
4519 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004520 ts[0].tv_sec = ut->atime_s; \
4521 ts[0].tv_nsec = ut->atime_ns; \
4522 ts[1].tv_sec = ut->mtime_s; \
4523 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 time = ts; \
4525 } \
4526
4527#define UTIME_TO_TIMEVAL \
4528 struct timeval tv[2]; \
4529 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004530 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 time = NULL; \
4532 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004533 tv[0].tv_sec = ut->atime_s; \
4534 tv[0].tv_usec = ut->atime_ns / 1000; \
4535 tv[1].tv_sec = ut->mtime_s; \
4536 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537 time = tv; \
4538 } \
4539
4540#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004541 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004543 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 time = NULL; \
4545 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004546 u.actime = ut->atime_s; \
4547 u.modtime = ut->mtime_s; \
4548 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 }
4550
4551#define UTIME_TO_TIME_T \
4552 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004553 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004554 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 time = NULL; \
4556 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004557 timet[0] = ut->atime_s; \
4558 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004559 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 } \
4561
4562
4563#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4564
4565#if UTIME_HAVE_DIR_FD
4566
4567static int
Victor Stinner484df002014-10-09 13:52:31 +02004568utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569{
4570#ifdef HAVE_UTIMENSAT
4571 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4572 UTIME_TO_TIMESPEC;
4573 return utimensat(dir_fd, path, time, flags);
4574#elif defined(HAVE_FUTIMESAT)
4575 UTIME_TO_TIMEVAL;
4576 /*
4577 * follow_symlinks will never be false here;
4578 * we only allow !follow_symlinks and dir_fd together
4579 * if we have utimensat()
4580 */
4581 assert(follow_symlinks);
4582 return futimesat(dir_fd, path, time);
4583#endif
4584}
4585
Larry Hastings2f936352014-08-05 14:04:04 +10004586 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4587#else
4588 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589#endif
4590
4591#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4592
4593#if UTIME_HAVE_FD
4594
4595static int
Victor Stinner484df002014-10-09 13:52:31 +02004596utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597{
4598#ifdef HAVE_FUTIMENS
4599 UTIME_TO_TIMESPEC;
4600 return futimens(fd, time);
4601#else
4602 UTIME_TO_TIMEVAL;
4603 return futimes(fd, time);
4604#endif
4605}
4606
Larry Hastings2f936352014-08-05 14:04:04 +10004607 #define PATH_UTIME_HAVE_FD 1
4608#else
4609 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610#endif
4611
4612
4613#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4614 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4615
4616#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4617
4618static int
Victor Stinner484df002014-10-09 13:52:31 +02004619utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620{
4621#ifdef HAVE_UTIMENSAT
4622 UTIME_TO_TIMESPEC;
4623 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4624#else
4625 UTIME_TO_TIMEVAL;
4626 return lutimes(path, time);
4627#endif
4628}
4629
4630#endif
4631
4632#ifndef MS_WINDOWS
4633
4634static int
Victor Stinner484df002014-10-09 13:52:31 +02004635utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636{
4637#ifdef HAVE_UTIMENSAT
4638 UTIME_TO_TIMESPEC;
4639 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4640#elif defined(HAVE_UTIMES)
4641 UTIME_TO_TIMEVAL;
4642 return utimes(path, time);
4643#elif defined(HAVE_UTIME_H)
4644 UTIME_TO_UTIMBUF;
4645 return utime(path, time);
4646#else
4647 UTIME_TO_TIME_T;
4648 return utime(path, time);
4649#endif
4650}
4651
4652#endif
4653
Larry Hastings76ad59b2012-05-03 00:30:07 -07004654static int
4655split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4656{
4657 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004658 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004659 divmod = PyNumber_Divmod(py_long, billion);
4660 if (!divmod)
4661 goto exit;
4662 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4663 if ((*s == -1) && PyErr_Occurred())
4664 goto exit;
4665 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004666 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667 goto exit;
4668
4669 result = 1;
4670exit:
4671 Py_XDECREF(divmod);
4672 return result;
4673}
4674
Larry Hastings2f936352014-08-05 14:04:04 +10004675
4676/*[clinic input]
4677os.utime
4678
4679 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4680 times: object = NULL
4681 *
4682 ns: object = NULL
4683 dir_fd: dir_fd(requires='futimensat') = None
4684 follow_symlinks: bool=True
4685
4686# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4687
4688Set the access and modified time of path.
4689
4690path may always be specified as a string.
4691On some platforms, path may also be specified as an open file descriptor.
4692 If this functionality is unavailable, using it raises an exception.
4693
4694If times is not None, it must be a tuple (atime, mtime);
4695 atime and mtime should be expressed as float seconds since the epoch.
4696If ns is not None, it must be a tuple (atime_ns, mtime_ns);
4697 atime_ns and mtime_ns should be expressed as integer nanoseconds
4698 since the epoch.
4699If both times and ns are None, utime uses the current time.
4700Specifying tuples for both times and ns is an error.
4701
4702If dir_fd is not None, it should be a file descriptor open to a directory,
4703 and path should be relative; path will then be relative to that directory.
4704If follow_symlinks is False, and the last element of the path is a symbolic
4705 link, utime will modify the symbolic link itself instead of the file the
4706 link points to.
4707It is an error to use dir_fd or follow_symlinks when specifying path
4708 as an open file descriptor.
4709dir_fd and follow_symlinks may not be available on your platform.
4710 If they are unavailable, using them will raise a NotImplementedError.
4711
4712[clinic start generated code]*/
4713
Larry Hastings2f936352014-08-05 14:04:04 +10004714static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004715os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4716 PyObject *ns, int dir_fd, int follow_symlinks)
4717/*[clinic end generated code: output=31f3434e560ba2f0 input=1f18c17d5941aa82]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004718{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719#ifdef MS_WINDOWS
4720 HANDLE hFile;
4721 FILETIME atime, mtime;
4722#else
4723 int result;
4724#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004725
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004727 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004728
Christian Heimesb3c87242013-08-01 00:08:16 +02004729 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 if (times && (times != Py_None) && ns) {
4732 PyErr_SetString(PyExc_ValueError,
4733 "utime: you may specify either 'times'"
4734 " or 'ns' but not both");
4735 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004736 }
4737
4738 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004739 time_t a_sec, m_sec;
4740 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 PyErr_SetString(PyExc_TypeError,
4743 "utime: 'times' must be either"
4744 " a tuple of two ints or None");
4745 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004746 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004748 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004749 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004750 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004751 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004753 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004754 utime.atime_s = a_sec;
4755 utime.atime_ns = a_nsec;
4756 utime.mtime_s = m_sec;
4757 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 PyErr_SetString(PyExc_TypeError,
4762 "utime: 'ns' must be a tuple of two ints");
4763 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004764 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004766 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004768 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 &utime.mtime_s, &utime.mtime_ns)) {
4770 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004771 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 }
4773 else {
4774 /* times and ns are both None/unspecified. use "now". */
4775 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004776 }
4777
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4779 if (follow_symlinks_specified("utime", follow_symlinks))
4780 goto exit;
4781#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004782
Larry Hastings2f936352014-08-05 14:04:04 +10004783 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4784 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4785 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788#if !defined(HAVE_UTIMENSAT)
4789 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004790 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 "utime: cannot use dir_fd and follow_symlinks "
4792 "together on this platform");
4793 goto exit;
4794 }
4795#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004796
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004797#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004799 if (path->wide)
4800 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 NULL, OPEN_EXISTING,
4802 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 else
Larry Hastings2f936352014-08-05 14:04:04 +10004804 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 NULL, OPEN_EXISTING,
4806 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 Py_END_ALLOW_THREADS
4808 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004809 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004811 }
4812
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004814 GetSystemTimeAsFileTime(&mtime);
4815 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004818 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4819 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 }
4821 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4822 /* Avoid putting the file name into the error here,
4823 as that may confuse the user into believing that
4824 something is wrong with the file, when it also
4825 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004826 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004829#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004831
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4833 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004834 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004836#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837
4838#if UTIME_HAVE_DIR_FD
4839 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004840 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841 else
4842#endif
4843
4844#if UTIME_HAVE_FD
Larry Hastings2f936352014-08-05 14:04:04 +10004845 if (path->fd != -1)
4846 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847 else
4848#endif
4849
Larry Hastings2f936352014-08-05 14:04:04 +10004850 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851
4852 Py_END_ALLOW_THREADS
4853
4854 if (result < 0) {
4855 /* see previous comment about not putting filename in error here */
4856 return_value = posix_error();
4857 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004859
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004860#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004861
4862 Py_INCREF(Py_None);
4863 return_value = Py_None;
4864
4865exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004866#ifdef MS_WINDOWS
4867 if (hFile != INVALID_HANDLE_VALUE)
4868 CloseHandle(hFile);
4869#endif
4870 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004871}
4872
Guido van Rossum3b066191991-06-04 19:40:25 +00004873/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004874
Larry Hastings2f936352014-08-05 14:04:04 +10004875
4876/*[clinic input]
4877os._exit
4878
4879 status: int
4880
4881Exit to the system with specified status, without normal exit processing.
4882[clinic start generated code]*/
4883
Larry Hastings2f936352014-08-05 14:04:04 +10004884static PyObject *
4885os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004886/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004887{
4888 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004889 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004890}
4891
Martin v. Löwis114619e2002-10-07 06:44:21 +00004892#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4893static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004894free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004895{
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 Py_ssize_t i;
4897 for (i = 0; i < count; i++)
4898 PyMem_Free(array[i]);
4899 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004900}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004901
Antoine Pitrou69f71142009-05-24 21:25:49 +00004902static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004903int fsconvert_strdup(PyObject *o, char**out)
4904{
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 PyObject *bytes;
4906 Py_ssize_t size;
4907 if (!PyUnicode_FSConverter(o, &bytes))
4908 return 0;
4909 size = PyBytes_GET_SIZE(bytes);
4910 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004911 if (!*out) {
4912 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004914 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 memcpy(*out, PyBytes_AsString(bytes), size+1);
4916 Py_DECREF(bytes);
4917 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004918}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004919#endif
4920
Ross Lagerwall7807c352011-03-17 20:20:30 +02004921#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004922static char**
4923parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4924{
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 char **envlist;
4926 Py_ssize_t i, pos, envc;
4927 PyObject *keys=NULL, *vals=NULL;
4928 PyObject *key, *val, *key2, *val2;
4929 char *p, *k, *v;
4930 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004931
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 i = PyMapping_Size(env);
4933 if (i < 0)
4934 return NULL;
4935 envlist = PyMem_NEW(char *, i + 1);
4936 if (envlist == NULL) {
4937 PyErr_NoMemory();
4938 return NULL;
4939 }
4940 envc = 0;
4941 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004942 if (!keys)
4943 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004945 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 goto error;
4947 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4948 PyErr_Format(PyExc_TypeError,
4949 "env.keys() or env.values() is not a list");
4950 goto error;
4951 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 for (pos = 0; pos < i; pos++) {
4954 key = PyList_GetItem(keys, pos);
4955 val = PyList_GetItem(vals, pos);
4956 if (!key || !val)
4957 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004958
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 if (PyUnicode_FSConverter(key, &key2) == 0)
4960 goto error;
4961 if (PyUnicode_FSConverter(val, &val2) == 0) {
4962 Py_DECREF(key2);
4963 goto error;
4964 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004965
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 k = PyBytes_AsString(key2);
4967 v = PyBytes_AsString(val2);
4968 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004969
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 p = PyMem_NEW(char, len);
4971 if (p == NULL) {
4972 PyErr_NoMemory();
4973 Py_DECREF(key2);
4974 Py_DECREF(val2);
4975 goto error;
4976 }
4977 PyOS_snprintf(p, len, "%s=%s", k, v);
4978 envlist[envc++] = p;
4979 Py_DECREF(key2);
4980 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 }
4982 Py_DECREF(vals);
4983 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 envlist[envc] = 0;
4986 *envc_ptr = envc;
4987 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004988
4989error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 Py_XDECREF(keys);
4991 Py_XDECREF(vals);
4992 while (--envc >= 0)
4993 PyMem_DEL(envlist[envc]);
4994 PyMem_DEL(envlist);
4995 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004996}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998static char**
4999parse_arglist(PyObject* argv, Py_ssize_t *argc)
5000{
5001 int i;
5002 char **argvlist = PyMem_NEW(char *, *argc+1);
5003 if (argvlist == NULL) {
5004 PyErr_NoMemory();
5005 return NULL;
5006 }
5007 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005008 PyObject* item = PySequence_ITEM(argv, i);
5009 if (item == NULL)
5010 goto fail;
5011 if (!fsconvert_strdup(item, &argvlist[i])) {
5012 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 goto fail;
5014 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005015 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 }
5017 argvlist[*argc] = NULL;
5018 return argvlist;
5019fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005020 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021 free_string_array(argvlist, *argc);
5022 return NULL;
5023}
5024#endif
5025
Larry Hastings2f936352014-08-05 14:04:04 +10005026
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005028/*[clinic input]
5029os.execv
5030
5031 path: FSConverter
5032 Path of executable file.
5033 argv: object
5034 Tuple or list of strings.
5035 /
5036
5037Execute an executable path with arguments, replacing current process.
5038[clinic start generated code]*/
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040static PyObject *
5041os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005042/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005043{
5044 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005045 char **argvlist;
5046 Py_ssize_t argc;
5047
5048 /* execv has two arguments: (path, argv), where
5049 argv is a list or tuple of strings. */
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5053 PyErr_SetString(PyExc_TypeError,
5054 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 return NULL;
5056 }
5057 argc = PySequence_Size(argv);
5058 if (argc < 1) {
5059 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 return NULL;
5061 }
5062
5063 argvlist = parse_arglist(argv, &argc);
5064 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065 return NULL;
5066 }
5067
Larry Hastings2f936352014-08-05 14:04:04 +10005068 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069
5070 /* If we get here it's definitely an error */
5071
5072 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 return posix_error();
5074}
5075
Larry Hastings2f936352014-08-05 14:04:04 +10005076
5077/*[clinic input]
5078os.execve
5079
5080 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5081 Path of executable file.
5082 argv: object
5083 Tuple or list of strings.
5084 env: object
5085 Dictionary of strings mapping to strings.
5086
5087Execute an executable path with arguments, replacing current process.
5088[clinic start generated code]*/
5089
Larry Hastings2f936352014-08-05 14:04:04 +10005090static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005091os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5092 PyObject *env)
5093/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005094{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005098
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 /* execve has three arguments: (path, argv, env), where
5100 argv is a list or tuple of strings and env is a dictionary
5101 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005102
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005105 "execve: argv must be a tuple or list");
5106 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 if (!PyMapping_Check(env)) {
5110 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005111 "execve: environment must be a mapping object");
5112 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005114
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005117 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005119
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 envlist = parse_envlist(env, &envc);
5121 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005122 goto fail;
5123
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005125 if (path->fd > -1)
5126 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127 else
5128#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005129 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130
5131 /* If we get here it's definitely an error */
5132
Larry Hastings2f936352014-08-05 14:04:04 +10005133 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005134
5135 while (--envc >= 0)
5136 PyMem_DEL(envlist[envc]);
5137 PyMem_DEL(envlist);
5138 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139 if (argvlist)
5140 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141 return NULL;
5142}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005143#endif /* HAVE_EXECV */
5144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005145
Guido van Rossuma1065681999-01-25 23:20:23 +00005146#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005147/*[clinic input]
5148os.spawnv
5149
5150 mode: int
5151 Mode of process creation.
5152 path: FSConverter
5153 Path of executable file.
5154 argv: object
5155 Tuple or list of strings.
5156 /
5157
5158Execute the program specified by path in a new process.
5159[clinic start generated code]*/
5160
Larry Hastings2f936352014-08-05 14:04:04 +10005161static PyObject *
5162os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005163/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005164{
5165 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005167 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 Py_ssize_t argc;
5169 Py_intptr_t spawnval;
5170 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 /* spawnv has three arguments: (mode, path, argv), where
5173 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005174
Larry Hastings2f936352014-08-05 14:04:04 +10005175 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 if (PyList_Check(argv)) {
5177 argc = PyList_Size(argv);
5178 getitem = PyList_GetItem;
5179 }
5180 else if (PyTuple_Check(argv)) {
5181 argc = PyTuple_Size(argv);
5182 getitem = PyTuple_GetItem;
5183 }
5184 else {
5185 PyErr_SetString(PyExc_TypeError,
5186 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 return NULL;
5188 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 argvlist = PyMem_NEW(char *, argc+1);
5191 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 return PyErr_NoMemory();
5193 }
5194 for (i = 0; i < argc; i++) {
5195 if (!fsconvert_strdup((*getitem)(argv, i),
5196 &argvlist[i])) {
5197 free_string_array(argvlist, i);
5198 PyErr_SetString(
5199 PyExc_TypeError,
5200 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 return NULL;
5202 }
5203 }
5204 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 if (mode == _OLD_P_OVERLAY)
5207 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005210 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005212
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005214
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 if (spawnval == -1)
5216 return posix_error();
5217 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005218 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005219}
5220
5221
Larry Hastings2f936352014-08-05 14:04:04 +10005222/*[clinic input]
5223os.spawnve
5224
5225 mode: int
5226 Mode of process creation.
5227 path: FSConverter
5228 Path of executable file.
5229 argv: object
5230 Tuple or list of strings.
5231 env: object
5232 Dictionary of strings mapping to strings.
5233 /
5234
5235Execute the program specified by path in a new process.
5236[clinic start generated code]*/
5237
Larry Hastings2f936352014-08-05 14:04:04 +10005238static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005239os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5240 PyObject *argv, PyObject *env)
5241/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005242{
5243 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 char **argvlist;
5245 char **envlist;
5246 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005247 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 Py_intptr_t spawnval;
5249 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5250 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005251
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 /* spawnve has four arguments: (mode, path, argv, env), where
5253 argv is a list or tuple of strings and env is a dictionary
5254 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005255
Larry Hastings2f936352014-08-05 14:04:04 +10005256 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 if (PyList_Check(argv)) {
5258 argc = PyList_Size(argv);
5259 getitem = PyList_GetItem;
5260 }
5261 else if (PyTuple_Check(argv)) {
5262 argc = PyTuple_Size(argv);
5263 getitem = PyTuple_GetItem;
5264 }
5265 else {
5266 PyErr_SetString(PyExc_TypeError,
5267 "spawnve() arg 2 must be a tuple or list");
5268 goto fail_0;
5269 }
5270 if (!PyMapping_Check(env)) {
5271 PyErr_SetString(PyExc_TypeError,
5272 "spawnve() arg 3 must be a mapping object");
5273 goto fail_0;
5274 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 argvlist = PyMem_NEW(char *, argc+1);
5277 if (argvlist == NULL) {
5278 PyErr_NoMemory();
5279 goto fail_0;
5280 }
5281 for (i = 0; i < argc; i++) {
5282 if (!fsconvert_strdup((*getitem)(argv, i),
5283 &argvlist[i]))
5284 {
5285 lastarg = i;
5286 goto fail_1;
5287 }
5288 }
5289 lastarg = argc;
5290 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 envlist = parse_envlist(env, &envc);
5293 if (envlist == NULL)
5294 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005295
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 if (mode == _OLD_P_OVERLAY)
5297 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005300 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005302
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 if (spawnval == -1)
5304 (void) posix_error();
5305 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005306 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005307
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 while (--envc >= 0)
5309 PyMem_DEL(envlist[envc]);
5310 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005311 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005313 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005315}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316
Guido van Rossuma1065681999-01-25 23:20:23 +00005317#endif /* HAVE_SPAWNV */
5318
5319
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005320#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005321/*[clinic input]
5322os.fork1
5323
5324Fork a child process with a single multiplexed (i.e., not bound) thread.
5325
5326Return 0 to child process and PID of child to parent process.
5327[clinic start generated code]*/
5328
Larry Hastings2f936352014-08-05 14:04:04 +10005329static PyObject *
5330os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005331/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005332{
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 pid_t pid;
5334 int result = 0;
5335 _PyImport_AcquireLock();
5336 pid = fork1();
5337 if (pid == 0) {
5338 /* child: this clobbers and resets the import lock. */
5339 PyOS_AfterFork();
5340 } else {
5341 /* parent: release the import lock. */
5342 result = _PyImport_ReleaseLock();
5343 }
5344 if (pid == -1)
5345 return posix_error();
5346 if (result < 0) {
5347 /* Don't clobber the OSError if the fork failed. */
5348 PyErr_SetString(PyExc_RuntimeError,
5349 "not holding the import lock");
5350 return NULL;
5351 }
5352 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005353}
Larry Hastings2f936352014-08-05 14:04:04 +10005354#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005355
5356
Guido van Rossumad0ee831995-03-01 10:34:45 +00005357#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005358/*[clinic input]
5359os.fork
5360
5361Fork a child process.
5362
5363Return 0 to child process and PID of child to parent process.
5364[clinic start generated code]*/
5365
Larry Hastings2f936352014-08-05 14:04:04 +10005366static PyObject *
5367os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005368/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005369{
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 pid_t pid;
5371 int result = 0;
5372 _PyImport_AcquireLock();
5373 pid = fork();
5374 if (pid == 0) {
5375 /* child: this clobbers and resets the import lock. */
5376 PyOS_AfterFork();
5377 } else {
5378 /* parent: release the import lock. */
5379 result = _PyImport_ReleaseLock();
5380 }
5381 if (pid == -1)
5382 return posix_error();
5383 if (result < 0) {
5384 /* Don't clobber the OSError if the fork failed. */
5385 PyErr_SetString(PyExc_RuntimeError,
5386 "not holding the import lock");
5387 return NULL;
5388 }
5389 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005390}
Larry Hastings2f936352014-08-05 14:04:04 +10005391#endif /* HAVE_FORK */
5392
Guido van Rossum85e3b011991-06-03 12:42:10 +00005393
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005394#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005395#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005396/*[clinic input]
5397os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005398
Larry Hastings2f936352014-08-05 14:04:04 +10005399 policy: int
5400
5401Get the maximum scheduling priority for policy.
5402[clinic start generated code]*/
5403
Larry Hastings2f936352014-08-05 14:04:04 +10005404static PyObject *
5405os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005406/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005407{
5408 int max;
5409
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005410 max = sched_get_priority_max(policy);
5411 if (max < 0)
5412 return posix_error();
5413 return PyLong_FromLong(max);
5414}
5415
Larry Hastings2f936352014-08-05 14:04:04 +10005416
5417/*[clinic input]
5418os.sched_get_priority_min
5419
5420 policy: int
5421
5422Get the minimum scheduling priority for policy.
5423[clinic start generated code]*/
5424
Larry Hastings2f936352014-08-05 14:04:04 +10005425static PyObject *
5426os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005427/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005428{
5429 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005430 if (min < 0)
5431 return posix_error();
5432 return PyLong_FromLong(min);
5433}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005434#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005436
Larry Hastings2f936352014-08-05 14:04:04 +10005437#ifdef HAVE_SCHED_SETSCHEDULER
5438/*[clinic input]
5439os.sched_getscheduler
5440 pid: pid_t
5441 /
5442
5443Get the scheduling policy for the process identifiedy by pid.
5444
5445Passing 0 for pid returns the scheduling policy for the calling process.
5446[clinic start generated code]*/
5447
Larry Hastings2f936352014-08-05 14:04:04 +10005448static PyObject *
5449os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005450/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005451{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005452 int policy;
5453
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454 policy = sched_getscheduler(pid);
5455 if (policy < 0)
5456 return posix_error();
5457 return PyLong_FromLong(policy);
5458}
Larry Hastings2f936352014-08-05 14:04:04 +10005459#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005460
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005461
5462#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005463/*[clinic input]
5464class os.sched_param "PyObject *" "&SchedParamType"
5465
5466@classmethod
5467os.sched_param.__new__
5468
5469 sched_priority: object
5470 A scheduling parameter.
5471
5472Current has only one field: sched_priority");
5473[clinic start generated code]*/
5474
Larry Hastings2f936352014-08-05 14:04:04 +10005475static PyObject *
5476os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005477/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005478{
5479 PyObject *res;
5480
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005481 res = PyStructSequence_New(type);
5482 if (!res)
5483 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005484 Py_INCREF(sched_priority);
5485 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005486 return res;
5487}
5488
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005489
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005490PyDoc_VAR(os_sched_param__doc__);
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492static PyStructSequence_Field sched_param_fields[] = {
5493 {"sched_priority", "the scheduling priority"},
5494 {0}
5495};
5496
5497static PyStructSequence_Desc sched_param_desc = {
5498 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005499 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500 sched_param_fields,
5501 1
5502};
5503
5504static int
5505convert_sched_param(PyObject *param, struct sched_param *res)
5506{
5507 long priority;
5508
5509 if (Py_TYPE(param) != &SchedParamType) {
5510 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5511 return 0;
5512 }
5513 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5514 if (priority == -1 && PyErr_Occurred())
5515 return 0;
5516 if (priority > INT_MAX || priority < INT_MIN) {
5517 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5518 return 0;
5519 }
5520 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5521 return 1;
5522}
Larry Hastings2f936352014-08-05 14:04:04 +10005523#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005525
5526#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005527/*[clinic input]
5528os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005529
Larry Hastings2f936352014-08-05 14:04:04 +10005530 pid: pid_t
5531 policy: int
5532 param: sched_param
5533 /
5534
5535Set the scheduling policy for the process identified by pid.
5536
5537If pid is 0, the calling process is changed.
5538param is an instance of sched_param.
5539[clinic start generated code]*/
5540
Larry Hastings2f936352014-08-05 14:04:04 +10005541static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005542os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5543 struct sched_param *param)
5544/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005545{
Jesus Cea9c822272011-09-10 01:40:52 +02005546 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005547 ** sched_setscheduler() returns 0 in Linux, but the previous
5548 ** scheduling policy under Solaris/Illumos, and others.
5549 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005550 */
Larry Hastings2f936352014-08-05 14:04:04 +10005551 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552 return posix_error();
5553 Py_RETURN_NONE;
5554}
Larry Hastings2f936352014-08-05 14:04:04 +10005555#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005556
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005557
5558#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005559/*[clinic input]
5560os.sched_getparam
5561 pid: pid_t
5562 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005563
Larry Hastings2f936352014-08-05 14:04:04 +10005564Returns scheduling parameters for the process identified by pid.
5565
5566If pid is 0, returns parameters for the calling process.
5567Return value is an instance of sched_param.
5568[clinic start generated code]*/
5569
Larry Hastings2f936352014-08-05 14:04:04 +10005570static PyObject *
5571os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005572/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005573{
5574 struct sched_param param;
5575 PyObject *result;
5576 PyObject *priority;
5577
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005578 if (sched_getparam(pid, &param))
5579 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005580 result = PyStructSequence_New(&SchedParamType);
5581 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005582 return NULL;
5583 priority = PyLong_FromLong(param.sched_priority);
5584 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005585 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586 return NULL;
5587 }
Larry Hastings2f936352014-08-05 14:04:04 +10005588 PyStructSequence_SET_ITEM(result, 0, priority);
5589 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005590}
5591
Larry Hastings2f936352014-08-05 14:04:04 +10005592
5593/*[clinic input]
5594os.sched_setparam
5595 pid: pid_t
5596 param: sched_param
5597 /
5598
5599Set scheduling parameters for the process identified by pid.
5600
5601If pid is 0, sets parameters for the calling process.
5602param should be an instance of sched_param.
5603[clinic start generated code]*/
5604
Larry Hastings2f936352014-08-05 14:04:04 +10005605static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005606os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5607 struct sched_param *param)
5608/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005609{
5610 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611 return posix_error();
5612 Py_RETURN_NONE;
5613}
Larry Hastings2f936352014-08-05 14:04:04 +10005614#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616
5617#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005618/*[clinic input]
5619os.sched_rr_get_interval -> double
5620 pid: pid_t
5621 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005622
Larry Hastings2f936352014-08-05 14:04:04 +10005623Return the round-robin quantum for the process identified by pid, in seconds.
5624
5625Value returned is a float.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static double
5629os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005630/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005631{
5632 struct timespec interval;
5633 if (sched_rr_get_interval(pid, &interval)) {
5634 posix_error();
5635 return -1.0;
5636 }
5637 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5638}
5639#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005640
Larry Hastings2f936352014-08-05 14:04:04 +10005641
5642/*[clinic input]
5643os.sched_yield
5644
5645Voluntarily relinquish the CPU.
5646[clinic start generated code]*/
5647
Larry Hastings2f936352014-08-05 14:04:04 +10005648static PyObject *
5649os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005650/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005651{
5652 if (sched_yield())
5653 return posix_error();
5654 Py_RETURN_NONE;
5655}
5656
Benjamin Peterson2740af82011-08-02 17:41:34 -05005657#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005658/* The minimum number of CPUs allocated in a cpu_set_t */
5659static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005660
Larry Hastings2f936352014-08-05 14:04:04 +10005661/*[clinic input]
5662os.sched_setaffinity
5663 pid: pid_t
5664 mask : object
5665 /
5666
5667Set the CPU affinity of the process identified by pid to mask.
5668
5669mask should be an iterable of integers identifying CPUs.
5670[clinic start generated code]*/
5671
Larry Hastings2f936352014-08-05 14:04:04 +10005672static PyObject *
5673os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005674/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005675{
Antoine Pitrou84869872012-08-04 16:16:35 +02005676 int ncpus;
5677 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005678 cpu_set_t *cpu_set = NULL;
5679 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680
Larry Hastings2f936352014-08-05 14:04:04 +10005681 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005682 if (iterator == NULL)
5683 return NULL;
5684
5685 ncpus = NCPUS_START;
5686 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005687 cpu_set = CPU_ALLOC(ncpus);
5688 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005689 PyErr_NoMemory();
5690 goto error;
5691 }
Larry Hastings2f936352014-08-05 14:04:04 +10005692 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005693
5694 while ((item = PyIter_Next(iterator))) {
5695 long cpu;
5696 if (!PyLong_Check(item)) {
5697 PyErr_Format(PyExc_TypeError,
5698 "expected an iterator of ints, "
5699 "but iterator yielded %R",
5700 Py_TYPE(item));
5701 Py_DECREF(item);
5702 goto error;
5703 }
5704 cpu = PyLong_AsLong(item);
5705 Py_DECREF(item);
5706 if (cpu < 0) {
5707 if (!PyErr_Occurred())
5708 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5709 goto error;
5710 }
5711 if (cpu > INT_MAX - 1) {
5712 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5713 goto error;
5714 }
5715 if (cpu >= ncpus) {
5716 /* Grow CPU mask to fit the CPU number */
5717 int newncpus = ncpus;
5718 cpu_set_t *newmask;
5719 size_t newsetsize;
5720 while (newncpus <= cpu) {
5721 if (newncpus > INT_MAX / 2)
5722 newncpus = cpu + 1;
5723 else
5724 newncpus = newncpus * 2;
5725 }
5726 newmask = CPU_ALLOC(newncpus);
5727 if (newmask == NULL) {
5728 PyErr_NoMemory();
5729 goto error;
5730 }
5731 newsetsize = CPU_ALLOC_SIZE(newncpus);
5732 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005733 memcpy(newmask, cpu_set, setsize);
5734 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005735 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005736 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005737 ncpus = newncpus;
5738 }
Larry Hastings2f936352014-08-05 14:04:04 +10005739 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005740 }
5741 Py_CLEAR(iterator);
5742
Larry Hastings2f936352014-08-05 14:04:04 +10005743 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 posix_error();
5745 goto error;
5746 }
Larry Hastings2f936352014-08-05 14:04:04 +10005747 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005749
5750error:
Larry Hastings2f936352014-08-05 14:04:04 +10005751 if (cpu_set)
5752 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005753 Py_XDECREF(iterator);
5754 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005755}
5756
Larry Hastings2f936352014-08-05 14:04:04 +10005757
5758/*[clinic input]
5759os.sched_getaffinity
5760 pid: pid_t
5761 /
5762
5763Return the affinity of the process identified by pid.
5764
5765The affinity is returned as a set of CPU identifiers.
5766[clinic start generated code]*/
5767
Larry Hastings2f936352014-08-05 14:04:04 +10005768static PyObject *
5769os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005770/*[clinic end generated code: output=b431a8f310e369e7 input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005771{
Antoine Pitrou84869872012-08-04 16:16:35 +02005772 int cpu, ncpus, count;
5773 size_t setsize;
5774 cpu_set_t *mask = NULL;
5775 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005776
Antoine Pitrou84869872012-08-04 16:16:35 +02005777 ncpus = NCPUS_START;
5778 while (1) {
5779 setsize = CPU_ALLOC_SIZE(ncpus);
5780 mask = CPU_ALLOC(ncpus);
5781 if (mask == NULL)
5782 return PyErr_NoMemory();
5783 if (sched_getaffinity(pid, setsize, mask) == 0)
5784 break;
5785 CPU_FREE(mask);
5786 if (errno != EINVAL)
5787 return posix_error();
5788 if (ncpus > INT_MAX / 2) {
5789 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5790 "a large enough CPU set");
5791 return NULL;
5792 }
5793 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005794 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005795
5796 res = PySet_New(NULL);
5797 if (res == NULL)
5798 goto error;
5799 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5800 if (CPU_ISSET_S(cpu, setsize, mask)) {
5801 PyObject *cpu_num = PyLong_FromLong(cpu);
5802 --count;
5803 if (cpu_num == NULL)
5804 goto error;
5805 if (PySet_Add(res, cpu_num)) {
5806 Py_DECREF(cpu_num);
5807 goto error;
5808 }
5809 Py_DECREF(cpu_num);
5810 }
5811 }
5812 CPU_FREE(mask);
5813 return res;
5814
5815error:
5816 if (mask)
5817 CPU_FREE(mask);
5818 Py_XDECREF(res);
5819 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005820}
5821
Benjamin Peterson2740af82011-08-02 17:41:34 -05005822#endif /* HAVE_SCHED_SETAFFINITY */
5823
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005824#endif /* HAVE_SCHED_H */
5825
Larry Hastings2f936352014-08-05 14:04:04 +10005826
Neal Norwitzb59798b2003-03-21 01:43:31 +00005827/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005828/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5829#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005830#define DEV_PTY_FILE "/dev/ptc"
5831#define HAVE_DEV_PTMX
5832#else
5833#define DEV_PTY_FILE "/dev/ptmx"
5834#endif
5835
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005836#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005837#ifdef HAVE_PTY_H
5838#include <pty.h>
5839#else
5840#ifdef HAVE_LIBUTIL_H
5841#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005842#else
5843#ifdef HAVE_UTIL_H
5844#include <util.h>
5845#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005846#endif /* HAVE_LIBUTIL_H */
5847#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005848#ifdef HAVE_STROPTS_H
5849#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005850#endif
5851#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005852
Larry Hastings2f936352014-08-05 14:04:04 +10005853
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005854#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005855/*[clinic input]
5856os.openpty
5857
5858Open a pseudo-terminal.
5859
5860Return a tuple of (master_fd, slave_fd) containing open file descriptors
5861for both the master and slave ends.
5862[clinic start generated code]*/
5863
Larry Hastings2f936352014-08-05 14:04:04 +10005864static PyObject *
5865os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005866/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005867{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005868 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005869#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005870 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005871#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005872#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005873 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005874#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005875 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005876#endif
5877#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005878
Thomas Wouters70c21a12000-07-14 14:28:33 +00005879#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005881 goto posix_error;
5882
5883 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5884 goto error;
5885 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5886 goto error;
5887
Neal Norwitzb59798b2003-03-21 01:43:31 +00005888#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5890 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891 goto posix_error;
5892 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5893 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005894
Victor Stinnerdaf45552013-08-28 00:53:59 +02005895 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005897 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005898
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005899#else
Victor Stinner000de532013-11-25 23:19:58 +01005900 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005901 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005902 goto posix_error;
5903
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 /* change permission of slave */
5907 if (grantpt(master_fd) < 0) {
5908 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005909 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 /* unlock slave */
5913 if (unlockpt(master_fd) < 0) {
5914 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005917
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005919
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 slave_name = ptsname(master_fd); /* get name of slave */
5921 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922 goto posix_error;
5923
5924 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005925 if (slave_fd == -1)
5926 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005927
5928 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5929 goto posix_error;
5930
Neal Norwitzb59798b2003-03-21 01:43:31 +00005931#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5933 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005934#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005936#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005937#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005938#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005939
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942posix_error:
5943 posix_error();
5944error:
5945 if (master_fd != -1)
5946 close(master_fd);
5947 if (slave_fd != -1)
5948 close(slave_fd);
5949 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005950}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005951#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952
Larry Hastings2f936352014-08-05 14:04:04 +10005953
Fred Drake8cef4cf2000-06-28 16:40:38 +00005954#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005955/*[clinic input]
5956os.forkpty
5957
5958Fork a new process with a new pseudo-terminal as controlling tty.
5959
5960Returns a tuple of (pid, master_fd).
5961Like fork(), return pid of 0 to the child process,
5962and pid of child to the parent process.
5963To both, return fd of newly opened pseudo-terminal.
5964[clinic start generated code]*/
5965
Larry Hastings2f936352014-08-05 14:04:04 +10005966static PyObject *
5967os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005968/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005969{
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 int master_fd = -1, result = 0;
5971 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005972
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 _PyImport_AcquireLock();
5974 pid = forkpty(&master_fd, NULL, NULL, NULL);
5975 if (pid == 0) {
5976 /* child: this clobbers and resets the import lock. */
5977 PyOS_AfterFork();
5978 } else {
5979 /* parent: release the import lock. */
5980 result = _PyImport_ReleaseLock();
5981 }
5982 if (pid == -1)
5983 return posix_error();
5984 if (result < 0) {
5985 /* Don't clobber the OSError if the fork failed. */
5986 PyErr_SetString(PyExc_RuntimeError,
5987 "not holding the import lock");
5988 return NULL;
5989 }
5990 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005991}
Larry Hastings2f936352014-08-05 14:04:04 +10005992#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005993
Ross Lagerwall7807c352011-03-17 20:20:30 +02005994
Guido van Rossumad0ee831995-03-01 10:34:45 +00005995#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005996/*[clinic input]
5997os.getegid
5998
5999Return the current process's effective group id.
6000[clinic start generated code]*/
6001
Larry Hastings2f936352014-08-05 14:04:04 +10006002static PyObject *
6003os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006004/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006005{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006006 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006007}
Larry Hastings2f936352014-08-05 14:04:04 +10006008#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Guido van Rossumad0ee831995-03-01 10:34:45 +00006011#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006012/*[clinic input]
6013os.geteuid
6014
6015Return the current process's effective user id.
6016[clinic start generated code]*/
6017
Larry Hastings2f936352014-08-05 14:04:04 +10006018static PyObject *
6019os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006020/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006021{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006022 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006023}
Larry Hastings2f936352014-08-05 14:04:04 +10006024#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006026
Guido van Rossumad0ee831995-03-01 10:34:45 +00006027#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006028/*[clinic input]
6029os.getgid
6030
6031Return the current process's group id.
6032[clinic start generated code]*/
6033
Larry Hastings2f936352014-08-05 14:04:04 +10006034static PyObject *
6035os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006036/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006037{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006038 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006039}
Larry Hastings2f936352014-08-05 14:04:04 +10006040#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Larry Hastings2f936352014-08-05 14:04:04 +10006043/*[clinic input]
6044os.getpid
6045
6046Return the current process id.
6047[clinic start generated code]*/
6048
Larry Hastings2f936352014-08-05 14:04:04 +10006049static PyObject *
6050os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006051/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006052{
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006054}
6055
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006056#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006057
6058/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006059PyDoc_STRVAR(posix_getgrouplist__doc__,
6060"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6061Returns a list of groups to which a user belongs.\n\n\
6062 user: username to lookup\n\
6063 group: base group id of the user");
6064
6065static PyObject *
6066posix_getgrouplist(PyObject *self, PyObject *args)
6067{
6068#ifdef NGROUPS_MAX
6069#define MAX_GROUPS NGROUPS_MAX
6070#else
6071 /* defined to be 16 on Solaris7, so this should be a small number */
6072#define MAX_GROUPS 64
6073#endif
6074
6075 const char *user;
6076 int i, ngroups;
6077 PyObject *list;
6078#ifdef __APPLE__
6079 int *groups, basegid;
6080#else
6081 gid_t *groups, basegid;
6082#endif
6083 ngroups = MAX_GROUPS;
6084
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006085#ifdef __APPLE__
6086 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006087 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006088#else
6089 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6090 _Py_Gid_Converter, &basegid))
6091 return NULL;
6092#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006093
6094#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006095 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006096#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006097 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006098#endif
6099 if (groups == NULL)
6100 return PyErr_NoMemory();
6101
6102 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6103 PyMem_Del(groups);
6104 return posix_error();
6105 }
6106
6107 list = PyList_New(ngroups);
6108 if (list == NULL) {
6109 PyMem_Del(groups);
6110 return NULL;
6111 }
6112
6113 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006114#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006115 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006116#else
6117 PyObject *o = _PyLong_FromGid(groups[i]);
6118#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006119 if (o == NULL) {
6120 Py_DECREF(list);
6121 PyMem_Del(groups);
6122 return NULL;
6123 }
6124 PyList_SET_ITEM(list, i, o);
6125 }
6126
6127 PyMem_Del(groups);
6128
6129 return list;
6130}
Larry Hastings2f936352014-08-05 14:04:04 +10006131#endif /* HAVE_GETGROUPLIST */
6132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006133
Fred Drakec9680921999-12-13 16:37:25 +00006134#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006135/*[clinic input]
6136os.getgroups
6137
6138Return list of supplemental group IDs for the process.
6139[clinic start generated code]*/
6140
Larry Hastings2f936352014-08-05 14:04:04 +10006141static PyObject *
6142os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006143/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006144{
6145 PyObject *result = NULL;
6146
Fred Drakec9680921999-12-13 16:37:25 +00006147#ifdef NGROUPS_MAX
6148#define MAX_GROUPS NGROUPS_MAX
6149#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006151#define MAX_GROUPS 64
6152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006154
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006155 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006156 * This is a helper variable to store the intermediate result when
6157 * that happens.
6158 *
6159 * To keep the code readable the OSX behaviour is unconditional,
6160 * according to the POSIX spec this should be safe on all unix-y
6161 * systems.
6162 */
6163 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006165
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006166#ifdef __APPLE__
6167 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6168 * there are more groups than can fit in grouplist. Therefore, on OS X
6169 * always first call getgroups with length 0 to get the actual number
6170 * of groups.
6171 */
6172 n = getgroups(0, NULL);
6173 if (n < 0) {
6174 return posix_error();
6175 } else if (n <= MAX_GROUPS) {
6176 /* groups will fit in existing array */
6177 alt_grouplist = grouplist;
6178 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006179 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006180 if (alt_grouplist == NULL) {
6181 errno = EINVAL;
6182 return posix_error();
6183 }
6184 }
6185
6186 n = getgroups(n, alt_grouplist);
6187 if (n == -1) {
6188 if (alt_grouplist != grouplist) {
6189 PyMem_Free(alt_grouplist);
6190 }
6191 return posix_error();
6192 }
6193#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006195 if (n < 0) {
6196 if (errno == EINVAL) {
6197 n = getgroups(0, NULL);
6198 if (n == -1) {
6199 return posix_error();
6200 }
6201 if (n == 0) {
6202 /* Avoid malloc(0) */
6203 alt_grouplist = grouplist;
6204 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006205 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006206 if (alt_grouplist == NULL) {
6207 errno = EINVAL;
6208 return posix_error();
6209 }
6210 n = getgroups(n, alt_grouplist);
6211 if (n == -1) {
6212 PyMem_Free(alt_grouplist);
6213 return posix_error();
6214 }
6215 }
6216 } else {
6217 return posix_error();
6218 }
6219 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006220#endif
6221
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006222 result = PyList_New(n);
6223 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 int i;
6225 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006226 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006228 Py_DECREF(result);
6229 result = NULL;
6230 break;
Fred Drakec9680921999-12-13 16:37:25 +00006231 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006233 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006234 }
6235
6236 if (alt_grouplist != grouplist) {
6237 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006239
Fred Drakec9680921999-12-13 16:37:25 +00006240 return result;
6241}
Larry Hastings2f936352014-08-05 14:04:04 +10006242#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006243
Antoine Pitroub7572f02009-12-02 20:46:48 +00006244#ifdef HAVE_INITGROUPS
6245PyDoc_STRVAR(posix_initgroups__doc__,
6246"initgroups(username, gid) -> None\n\n\
6247Call the system initgroups() to initialize the group access list with all of\n\
6248the groups of which the specified username is a member, plus the specified\n\
6249group id.");
6250
Larry Hastings2f936352014-08-05 14:04:04 +10006251/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006252static PyObject *
6253posix_initgroups(PyObject *self, PyObject *args)
6254{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006255 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006257 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#ifdef __APPLE__
6259 int gid;
6260#else
6261 gid_t gid;
6262#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006263
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006264#ifdef __APPLE__
6265 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6266 PyUnicode_FSConverter, &oname,
6267 &gid))
6268#else
6269 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6270 PyUnicode_FSConverter, &oname,
6271 _Py_Gid_Converter, &gid))
6272#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006274 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006275
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006276 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006277 Py_DECREF(oname);
6278 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006280
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 Py_INCREF(Py_None);
6282 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006283}
Larry Hastings2f936352014-08-05 14:04:04 +10006284#endif /* HAVE_INITGROUPS */
6285
Antoine Pitroub7572f02009-12-02 20:46:48 +00006286
Martin v. Löwis606edc12002-06-13 21:09:11 +00006287#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006288/*[clinic input]
6289os.getpgid
6290
6291 pid: pid_t
6292
6293Call the system call getpgid(), and return the result.
6294[clinic start generated code]*/
6295
Larry Hastings2f936352014-08-05 14:04:04 +10006296static PyObject *
6297os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006298/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006299{
6300 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 if (pgid < 0)
6302 return posix_error();
6303 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006304}
6305#endif /* HAVE_GETPGID */
6306
6307
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006309/*[clinic input]
6310os.getpgrp
6311
6312Return the current process group id.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
6316os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006317/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006318{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006319#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006321#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006323#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006325#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Guido van Rossumb6775db1994-08-01 11:34:53 +00006328#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006329/*[clinic input]
6330os.setpgrp
6331
6332Make the current process the leader of its process group.
6333[clinic start generated code]*/
6334
Larry Hastings2f936352014-08-05 14:04:04 +10006335static PyObject *
6336os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006337/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006338{
Guido van Rossum64933891994-10-20 21:56:42 +00006339#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006341#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006343#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 return posix_error();
6345 Py_INCREF(Py_None);
6346 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006347}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006348#endif /* HAVE_SETPGRP */
6349
Guido van Rossumad0ee831995-03-01 10:34:45 +00006350#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006351
6352#ifdef MS_WINDOWS
6353#include <tlhelp32.h>
6354
6355static PyObject*
6356win32_getppid()
6357{
6358 HANDLE snapshot;
6359 pid_t mypid;
6360 PyObject* result = NULL;
6361 BOOL have_record;
6362 PROCESSENTRY32 pe;
6363
6364 mypid = getpid(); /* This function never fails */
6365
6366 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6367 if (snapshot == INVALID_HANDLE_VALUE)
6368 return PyErr_SetFromWindowsErr(GetLastError());
6369
6370 pe.dwSize = sizeof(pe);
6371 have_record = Process32First(snapshot, &pe);
6372 while (have_record) {
6373 if (mypid == (pid_t)pe.th32ProcessID) {
6374 /* We could cache the ulong value in a static variable. */
6375 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6376 break;
6377 }
6378
6379 have_record = Process32Next(snapshot, &pe);
6380 }
6381
6382 /* If our loop exits and our pid was not found (result will be NULL)
6383 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6384 * error anyway, so let's raise it. */
6385 if (!result)
6386 result = PyErr_SetFromWindowsErr(GetLastError());
6387
6388 CloseHandle(snapshot);
6389
6390 return result;
6391}
6392#endif /*MS_WINDOWS*/
6393
Larry Hastings2f936352014-08-05 14:04:04 +10006394
6395/*[clinic input]
6396os.getppid
6397
6398Return the parent's process id.
6399
6400If the parent process has already exited, Windows machines will still
6401return its id; others systems will return the id of the 'init' process (1).
6402[clinic start generated code]*/
6403
Larry Hastings2f936352014-08-05 14:04:04 +10006404static PyObject *
6405os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006406/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006407{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006408#ifdef MS_WINDOWS
6409 return win32_getppid();
6410#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006412#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006413}
6414#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006416
Fred Drake12c6e2d1999-12-14 21:25:03 +00006417#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006418/*[clinic input]
6419os.getlogin
6420
6421Return the actual login name.
6422[clinic start generated code]*/
6423
Larry Hastings2f936352014-08-05 14:04:04 +10006424static PyObject *
6425os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006426/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006427{
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006429#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006430 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006431 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006432
6433 if (GetUserNameW(user_name, &num_chars)) {
6434 /* num_chars is the number of unicode chars plus null terminator */
6435 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006436 }
6437 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006438 result = PyErr_SetFromWindowsErr(GetLastError());
6439#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 char *name;
6441 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006442
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 errno = 0;
6444 name = getlogin();
6445 if (name == NULL) {
6446 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006447 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006448 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006449 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 }
6451 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006452 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006454#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006455 return result;
6456}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006457#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006458
Larry Hastings2f936352014-08-05 14:04:04 +10006459
Guido van Rossumad0ee831995-03-01 10:34:45 +00006460#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006461/*[clinic input]
6462os.getuid
6463
6464Return the current process's user id.
6465[clinic start generated code]*/
6466
Larry Hastings2f936352014-08-05 14:04:04 +10006467static PyObject *
6468os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006469/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006470{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006471 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006472}
Larry Hastings2f936352014-08-05 14:04:04 +10006473#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006475
Brian Curtineb24d742010-04-12 17:16:38 +00006476#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006477#define HAVE_KILL
6478#endif /* MS_WINDOWS */
6479
6480#ifdef HAVE_KILL
6481/*[clinic input]
6482os.kill
6483
6484 pid: pid_t
6485 signal: Py_ssize_t
6486 /
6487
6488Kill a process with a signal.
6489[clinic start generated code]*/
6490
Larry Hastings2f936352014-08-05 14:04:04 +10006491static PyObject *
6492os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006493/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006494#ifndef MS_WINDOWS
6495{
6496 if (kill(pid, (int)signal) == -1)
6497 return posix_error();
6498 Py_RETURN_NONE;
6499}
6500#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006501{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006502 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006503 DWORD sig = (DWORD)signal;
6504 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 /* Console processes which share a common console can be sent CTRL+C or
6508 CTRL+BREAK events, provided they handle said events. */
6509 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006510 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 err = GetLastError();
6512 PyErr_SetFromWindowsErr(err);
6513 }
6514 else
6515 Py_RETURN_NONE;
6516 }
Brian Curtineb24d742010-04-12 17:16:38 +00006517
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6519 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006520 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 if (handle == NULL) {
6522 err = GetLastError();
6523 return PyErr_SetFromWindowsErr(err);
6524 }
Brian Curtineb24d742010-04-12 17:16:38 +00006525
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 if (TerminateProcess(handle, sig) == 0) {
6527 err = GetLastError();
6528 result = PyErr_SetFromWindowsErr(err);
6529 } else {
6530 Py_INCREF(Py_None);
6531 result = Py_None;
6532 }
Brian Curtineb24d742010-04-12 17:16:38 +00006533
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 CloseHandle(handle);
6535 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006536}
Larry Hastings2f936352014-08-05 14:04:04 +10006537#endif /* !MS_WINDOWS */
6538#endif /* HAVE_KILL */
6539
6540
6541#ifdef HAVE_KILLPG
6542/*[clinic input]
6543os.killpg
6544
6545 pgid: pid_t
6546 signal: int
6547 /
6548
6549Kill a process group with a signal.
6550[clinic start generated code]*/
6551
Larry Hastings2f936352014-08-05 14:04:04 +10006552static PyObject *
6553os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006554/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006555{
6556 /* XXX some man pages make the `pgid` parameter an int, others
6557 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6558 take the same type. Moreover, pid_t is always at least as wide as
6559 int (else compilation of this module fails), which is safe. */
6560 if (killpg(pgid, signal) == -1)
6561 return posix_error();
6562 Py_RETURN_NONE;
6563}
6564#endif /* HAVE_KILLPG */
6565
Brian Curtineb24d742010-04-12 17:16:38 +00006566
Guido van Rossumc0125471996-06-28 18:55:32 +00006567#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006568#ifdef HAVE_SYS_LOCK_H
6569#include <sys/lock.h>
6570#endif
6571
Larry Hastings2f936352014-08-05 14:04:04 +10006572/*[clinic input]
6573os.plock
6574 op: int
6575 /
6576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006577Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006578[clinic start generated code]*/
6579
Larry Hastings2f936352014-08-05 14:04:04 +10006580static PyObject *
6581os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006582/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006583{
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 if (plock(op) == -1)
6585 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006586 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006587}
Larry Hastings2f936352014-08-05 14:04:04 +10006588#endif /* HAVE_PLOCK */
6589
Guido van Rossumc0125471996-06-28 18:55:32 +00006590
Guido van Rossumb6775db1994-08-01 11:34:53 +00006591#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006592/*[clinic input]
6593os.setuid
6594
6595 uid: uid_t
6596 /
6597
6598Set the current process's user id.
6599[clinic start generated code]*/
6600
Larry Hastings2f936352014-08-05 14:04:04 +10006601static PyObject *
6602os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006603/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006604{
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 if (setuid(uid) < 0)
6606 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006607 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006608}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006609#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006611
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006612#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006613/*[clinic input]
6614os.seteuid
6615
6616 euid: uid_t
6617 /
6618
6619Set the current process's effective user id.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
6623os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006624/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
6626 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006628 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006629}
6630#endif /* HAVE_SETEUID */
6631
Larry Hastings2f936352014-08-05 14:04:04 +10006632
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006633#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.setegid
6636
6637 egid: gid_t
6638 /
6639
6640Set the current process's effective group id.
6641[clinic start generated code]*/
6642
Larry Hastings2f936352014-08-05 14:04:04 +10006643static PyObject *
6644os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006645/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006646{
6647 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006649 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006650}
6651#endif /* HAVE_SETEGID */
6652
Larry Hastings2f936352014-08-05 14:04:04 +10006653
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006654#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006655/*[clinic input]
6656os.setreuid
6657
6658 ruid: uid_t
6659 euid: uid_t
6660 /
6661
6662Set the current process's real and effective user ids.
6663[clinic start generated code]*/
6664
Larry Hastings2f936352014-08-05 14:04:04 +10006665static PyObject *
6666os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006667/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006668{
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 if (setreuid(ruid, euid) < 0) {
6670 return posix_error();
6671 } else {
6672 Py_INCREF(Py_None);
6673 return Py_None;
6674 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006675}
6676#endif /* HAVE_SETREUID */
6677
Larry Hastings2f936352014-08-05 14:04:04 +10006678
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006679#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006680/*[clinic input]
6681os.setregid
6682
6683 rgid: gid_t
6684 egid: gid_t
6685 /
6686
6687Set the current process's real and effective group ids.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
6691os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006692/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006693{
6694 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006696 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006697}
6698#endif /* HAVE_SETREGID */
6699
Larry Hastings2f936352014-08-05 14:04:04 +10006700
Guido van Rossumb6775db1994-08-01 11:34:53 +00006701#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006702/*[clinic input]
6703os.setgid
6704 gid: gid_t
6705 /
6706
6707Set the current process's group id.
6708[clinic start generated code]*/
6709
Larry Hastings2f936352014-08-05 14:04:04 +10006710static PyObject *
6711os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006712/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 if (setgid(gid) < 0)
6715 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006716 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006717}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006718#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006719
Larry Hastings2f936352014-08-05 14:04:04 +10006720
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006721#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006722/*[clinic input]
6723os.setgroups
6724
6725 groups: object
6726 /
6727
6728Set the groups of the current process to list.
6729[clinic start generated code]*/
6730
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006731static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006732os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006733/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006734{
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 int i, len;
6736 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006737
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 if (!PySequence_Check(groups)) {
6739 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6740 return NULL;
6741 }
6742 len = PySequence_Size(groups);
6743 if (len > MAX_GROUPS) {
6744 PyErr_SetString(PyExc_ValueError, "too many groups");
6745 return NULL;
6746 }
6747 for(i = 0; i < len; i++) {
6748 PyObject *elem;
6749 elem = PySequence_GetItem(groups, i);
6750 if (!elem)
6751 return NULL;
6752 if (!PyLong_Check(elem)) {
6753 PyErr_SetString(PyExc_TypeError,
6754 "groups must be integers");
6755 Py_DECREF(elem);
6756 return NULL;
6757 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006758 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 Py_DECREF(elem);
6760 return NULL;
6761 }
6762 }
6763 Py_DECREF(elem);
6764 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006765
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 if (setgroups(len, grouplist) < 0)
6767 return posix_error();
6768 Py_INCREF(Py_None);
6769 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006770}
6771#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006772
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006773#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6774static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006775wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 PyObject *result;
6778 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006779 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (pid == -1)
6782 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (struct_rusage == NULL) {
6785 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6786 if (m == NULL)
6787 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006788 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 Py_DECREF(m);
6790 if (struct_rusage == NULL)
6791 return NULL;
6792 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6795 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6796 if (!result)
6797 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798
6799#ifndef doubletime
6800#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6801#endif
6802
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006804 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006806 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006807#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6809 SET_INT(result, 2, ru->ru_maxrss);
6810 SET_INT(result, 3, ru->ru_ixrss);
6811 SET_INT(result, 4, ru->ru_idrss);
6812 SET_INT(result, 5, ru->ru_isrss);
6813 SET_INT(result, 6, ru->ru_minflt);
6814 SET_INT(result, 7, ru->ru_majflt);
6815 SET_INT(result, 8, ru->ru_nswap);
6816 SET_INT(result, 9, ru->ru_inblock);
6817 SET_INT(result, 10, ru->ru_oublock);
6818 SET_INT(result, 11, ru->ru_msgsnd);
6819 SET_INT(result, 12, ru->ru_msgrcv);
6820 SET_INT(result, 13, ru->ru_nsignals);
6821 SET_INT(result, 14, ru->ru_nvcsw);
6822 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823#undef SET_INT
6824
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 if (PyErr_Occurred()) {
6826 Py_DECREF(result);
6827 return NULL;
6828 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006831}
6832#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6833
Larry Hastings2f936352014-08-05 14:04:04 +10006834
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006836/*[clinic input]
6837os.wait3
6838
6839 options: int
6840Wait for completion of a child process.
6841
6842Returns a tuple of information about the child process:
6843 (pid, status, rusage)
6844[clinic start generated code]*/
6845
Larry Hastings2f936352014-08-05 14:04:04 +10006846static PyObject *
6847os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006848/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849{
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006852 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 WAIT_TYPE status;
6854 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006856 do {
6857 Py_BEGIN_ALLOW_THREADS
6858 pid = wait3(&status, options, &ru);
6859 Py_END_ALLOW_THREADS
6860 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6861 if (pid < 0)
6862 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863
Victor Stinner4195b5c2012-02-08 23:03:19 +01006864 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865}
6866#endif /* HAVE_WAIT3 */
6867
Larry Hastings2f936352014-08-05 14:04:04 +10006868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006870/*[clinic input]
6871
6872os.wait4
6873
6874 pid: pid_t
6875 options: int
6876
6877Wait for completion of a specific child process.
6878
6879Returns a tuple of information about the child process:
6880 (pid, status, rusage)
6881[clinic start generated code]*/
6882
Larry Hastings2f936352014-08-05 14:04:04 +10006883static PyObject *
6884os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006885/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006886{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006887 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 WAIT_TYPE status;
6891 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006893 do {
6894 Py_BEGIN_ALLOW_THREADS
6895 res = wait4(pid, &status, options, &ru);
6896 Py_END_ALLOW_THREADS
6897 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6898 if (res < 0)
6899 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006901 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902}
6903#endif /* HAVE_WAIT4 */
6904
Larry Hastings2f936352014-08-05 14:04:04 +10006905
Ross Lagerwall7807c352011-03-17 20:20:30 +02006906#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006907/*[clinic input]
6908os.waitid
6909
6910 idtype: idtype_t
6911 Must be one of be P_PID, P_PGID or P_ALL.
6912 id: id_t
6913 The id to wait on.
6914 options: int
6915 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6916 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6917 /
6918
6919Returns the result of waiting for a process or processes.
6920
6921Returns either waitid_result or None if WNOHANG is specified and there are
6922no children in a waitable state.
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
6926os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006927/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006928{
6929 PyObject *result;
6930 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006931 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006932 siginfo_t si;
6933 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
6937 res = waitid(idtype, id, &si, options);
6938 Py_END_ALLOW_THREADS
6939 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6940 if (res < 0)
6941 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006942
6943 if (si.si_pid == 0)
6944 Py_RETURN_NONE;
6945
6946 result = PyStructSequence_New(&WaitidResultType);
6947 if (!result)
6948 return NULL;
6949
6950 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006951 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006952 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6953 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6954 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6955 if (PyErr_Occurred()) {
6956 Py_DECREF(result);
6957 return NULL;
6958 }
6959
6960 return result;
6961}
Larry Hastings2f936352014-08-05 14:04:04 +10006962#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963
Larry Hastings2f936352014-08-05 14:04:04 +10006964
6965#if defined(HAVE_WAITPID)
6966/*[clinic input]
6967os.waitpid
6968 pid: pid_t
6969 options: int
6970 /
6971
6972Wait for completion of a given child process.
6973
6974Returns a tuple of information regarding the child process:
6975 (pid, status)
6976
6977The options argument is ignored on Windows.
6978[clinic start generated code]*/
6979
Larry Hastings2f936352014-08-05 14:04:04 +10006980static PyObject *
6981os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006982/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006983{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006984 pid_t res;
6985 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 WAIT_TYPE status;
6987 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006988
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006989 do {
6990 Py_BEGIN_ALLOW_THREADS
6991 res = waitpid(pid, &status, options);
6992 Py_END_ALLOW_THREADS
6993 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6994 if (res < 0)
6995 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006996
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006997 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006998}
Tim Petersab034fa2002-02-01 11:27:43 +00006999#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007000/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007001/*[clinic input]
7002os.waitpid
7003 pid: Py_intptr_t
7004 options: int
7005 /
7006
7007Wait for completion of a given process.
7008
7009Returns a tuple of information regarding the process:
7010 (pid, status << 8)
7011
7012The options argument is ignored on Windows.
7013[clinic start generated code]*/
7014
Larry Hastings2f936352014-08-05 14:04:04 +10007015static PyObject *
7016os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007017/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007018{
7019 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007020 Py_intptr_t res;
7021 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007022
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007023 do {
7024 Py_BEGIN_ALLOW_THREADS
7025 res = _cwait(&status, pid, options);
7026 Py_END_ALLOW_THREADS
7027 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7028 if (res != 0)
7029 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007030
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007032 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007033}
Larry Hastings2f936352014-08-05 14:04:04 +10007034#endif
7035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007036
Guido van Rossumad0ee831995-03-01 10:34:45 +00007037#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007038/*[clinic input]
7039os.wait
7040
7041Wait for completion of a child process.
7042
7043Returns a tuple of information about the child process:
7044 (pid, status)
7045[clinic start generated code]*/
7046
Larry Hastings2f936352014-08-05 14:04:04 +10007047static PyObject *
7048os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007049/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007050{
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007052 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007053 WAIT_TYPE status;
7054 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007055
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007056 do {
7057 Py_BEGIN_ALLOW_THREADS
7058 pid = wait(&status);
7059 Py_END_ALLOW_THREADS
7060 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7061 if (pid < 0)
7062 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007063
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007065}
Larry Hastings2f936352014-08-05 14:04:04 +10007066#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007068
Larry Hastings9cf065c2012-06-22 16:30:09 -07007069#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7070PyDoc_STRVAR(readlink__doc__,
7071"readlink(path, *, dir_fd=None) -> path\n\n\
7072Return a string representing the path to which the symbolic link points.\n\
7073\n\
7074If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7075 and path should be relative; path will then be relative to that directory.\n\
7076dir_fd may not be implemented on your platform.\n\
7077 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007078#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007079
Guido van Rossumb6775db1994-08-01 11:34:53 +00007080#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007081
Larry Hastings2f936352014-08-05 14:04:04 +10007082/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007083static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007085{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007086 path_t path;
7087 int dir_fd = DEFAULT_DIR_FD;
7088 char buffer[MAXPATHLEN];
7089 ssize_t length;
7090 PyObject *return_value = NULL;
7091 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007092
Larry Hastings9cf065c2012-06-22 16:30:09 -07007093 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007094 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7096 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007097 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007099
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101#ifdef HAVE_READLINKAT
7102 if (dir_fd != DEFAULT_DIR_FD)
7103 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007104 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105#endif
7106 length = readlink(path.narrow, buffer, sizeof(buffer));
7107 Py_END_ALLOW_THREADS
7108
7109 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007110 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111 goto exit;
7112 }
7113
7114 if (PyUnicode_Check(path.object))
7115 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7116 else
7117 return_value = PyBytes_FromStringAndSize(buffer, length);
7118exit:
7119 path_cleanup(&path);
7120 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007121}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122
Guido van Rossumb6775db1994-08-01 11:34:53 +00007123#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007124
Larry Hastings2f936352014-08-05 14:04:04 +10007125#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7126
7127static PyObject *
7128win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7129{
7130 wchar_t *path;
7131 DWORD n_bytes_returned;
7132 DWORD io_result;
7133 PyObject *po, *result;
7134 int dir_fd;
7135 HANDLE reparse_point_handle;
7136
7137 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7138 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7139 wchar_t *print_name;
7140
7141 static char *keywords[] = {"path", "dir_fd", NULL};
7142
7143 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7144 &po,
7145 dir_fd_unavailable, &dir_fd
7146 ))
7147 return NULL;
7148
7149 path = PyUnicode_AsUnicode(po);
7150 if (path == NULL)
7151 return NULL;
7152
7153 /* First get a handle to the reparse point */
7154 Py_BEGIN_ALLOW_THREADS
7155 reparse_point_handle = CreateFileW(
7156 path,
7157 0,
7158 0,
7159 0,
7160 OPEN_EXISTING,
7161 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7162 0);
7163 Py_END_ALLOW_THREADS
7164
7165 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7166 return win32_error_object("readlink", po);
7167
7168 Py_BEGIN_ALLOW_THREADS
7169 /* New call DeviceIoControl to read the reparse point */
7170 io_result = DeviceIoControl(
7171 reparse_point_handle,
7172 FSCTL_GET_REPARSE_POINT,
7173 0, 0, /* in buffer */
7174 target_buffer, sizeof(target_buffer),
7175 &n_bytes_returned,
7176 0 /* we're not using OVERLAPPED_IO */
7177 );
7178 CloseHandle(reparse_point_handle);
7179 Py_END_ALLOW_THREADS
7180
7181 if (io_result==0)
7182 return win32_error_object("readlink", po);
7183
7184 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7185 {
7186 PyErr_SetString(PyExc_ValueError,
7187 "not a symbolic link");
7188 return NULL;
7189 }
7190 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7191 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7192
7193 result = PyUnicode_FromWideChar(print_name,
7194 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7195 return result;
7196}
7197
7198#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7199
7200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007201
Larry Hastings9cf065c2012-06-22 16:30:09 -07007202#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007203
7204#if defined(MS_WINDOWS)
7205
7206/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7207static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7208static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007209
Larry Hastings9cf065c2012-06-22 16:30:09 -07007210static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007211check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007212{
7213 HINSTANCE hKernel32;
7214 /* only recheck */
7215 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7216 return 1;
7217 hKernel32 = GetModuleHandleW(L"KERNEL32");
7218 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7219 "CreateSymbolicLinkW");
7220 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7221 "CreateSymbolicLinkA");
7222 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7223}
7224
Victor Stinner31b3b922013-06-05 01:49:17 +02007225/* Remove the last portion of the path */
7226static void
7227_dirnameW(WCHAR *path)
7228{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007229 WCHAR *ptr;
7230
7231 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007232 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007233 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007234 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235 }
7236 *ptr = 0;
7237}
7238
Victor Stinner31b3b922013-06-05 01:49:17 +02007239/* Remove the last portion of the path */
7240static void
7241_dirnameA(char *path)
7242{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 char *ptr;
7244
7245 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007246 for(ptr = path + strlen(path); ptr != path; ptr--) {
7247 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 }
7250 *ptr = 0;
7251}
7252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253/* Is this path absolute? */
7254static int
7255_is_absW(const WCHAR *path)
7256{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007257 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7258
7259}
7260
Victor Stinner31b3b922013-06-05 01:49:17 +02007261/* Is this path absolute? */
7262static int
7263_is_absA(const char *path)
7264{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007265 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7266
7267}
7268
Victor Stinner31b3b922013-06-05 01:49:17 +02007269/* join root and rest with a backslash */
7270static void
7271_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7272{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007273 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007274
Victor Stinner31b3b922013-06-05 01:49:17 +02007275 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276 wcscpy(dest_path, rest);
7277 return;
7278 }
7279
7280 root_len = wcslen(root);
7281
7282 wcscpy(dest_path, root);
7283 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007284 dest_path[root_len] = L'\\';
7285 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007286 }
7287 wcscpy(dest_path+root_len, rest);
7288}
7289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290/* join root and rest with a backslash */
7291static void
7292_joinA(char *dest_path, const char *root, const char *rest)
7293{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007294 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295
Victor Stinner31b3b922013-06-05 01:49:17 +02007296 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 strcpy(dest_path, rest);
7298 return;
7299 }
7300
7301 root_len = strlen(root);
7302
7303 strcpy(dest_path, root);
7304 if(root_len) {
7305 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007306 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007307 }
7308 strcpy(dest_path+root_len, rest);
7309}
7310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311/* Return True if the path at src relative to dest is a directory */
7312static int
7313_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315 WIN32_FILE_ATTRIBUTE_DATA src_info;
7316 WCHAR dest_parent[MAX_PATH];
7317 WCHAR src_resolved[MAX_PATH] = L"";
7318
7319 /* dest_parent = os.path.dirname(dest) */
7320 wcscpy(dest_parent, dest);
7321 _dirnameW(dest_parent);
7322 /* src_resolved = os.path.join(dest_parent, src) */
7323 _joinW(src_resolved, dest_parent, src);
7324 return (
7325 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7326 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7327 );
7328}
7329
Victor Stinner31b3b922013-06-05 01:49:17 +02007330/* Return True if the path at src relative to dest is a directory */
7331static int
7332_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334 WIN32_FILE_ATTRIBUTE_DATA src_info;
7335 char dest_parent[MAX_PATH];
7336 char src_resolved[MAX_PATH] = "";
7337
7338 /* dest_parent = os.path.dirname(dest) */
7339 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007340 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007341 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007342 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 return (
7344 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7345 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7346 );
7347}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007348#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007349
Larry Hastings2f936352014-08-05 14:04:04 +10007350
7351/*[clinic input]
7352os.symlink
7353 src: path_t
7354 dst: path_t
7355 target_is_directory: bool = False
7356 *
7357 dir_fd: dir_fd(requires='symlinkat')=None
7358
7359# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7360
7361Create a symbolic link pointing to src named dst.
7362
7363target_is_directory is required on Windows if the target is to be
7364 interpreted as a directory. (On Windows, symlink requires
7365 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7366 target_is_directory is ignored on non-Windows platforms.
7367
7368If dir_fd is not None, it should be a file descriptor open to a directory,
7369 and path should be relative; path will then be relative to that directory.
7370dir_fd may not be implemented on your platform.
7371 If it is unavailable, using it will raise a NotImplementedError.
7372
7373[clinic start generated code]*/
7374
Larry Hastings2f936352014-08-05 14:04:04 +10007375static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007376os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7377 int target_is_directory, int dir_fd)
7378/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007379{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380#ifdef MS_WINDOWS
7381 DWORD result;
7382#else
7383 int result;
7384#endif
7385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386#ifdef MS_WINDOWS
7387 if (!check_CreateSymbolicLink()) {
7388 PyErr_SetString(PyExc_NotImplementedError,
7389 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007390 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007391 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392 if (!win32_can_symlink) {
7393 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007394 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396#endif
7397
Larry Hastings2f936352014-08-05 14:04:04 +10007398 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399 PyErr_SetString(PyExc_ValueError,
7400 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007401 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 }
7403
7404#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007405
Larry Hastings9cf065c2012-06-22 16:30:09 -07007406 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007407 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007408 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007409 target_is_directory |= _check_dirW(src->wide, dst->wide);
7410 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007412 }
7413 else {
7414 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007415 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7416 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007418 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 Py_END_ALLOW_THREADS
7420
Larry Hastings2f936352014-08-05 14:04:04 +10007421 if (!result)
7422 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423
7424#else
7425
7426 Py_BEGIN_ALLOW_THREADS
7427#if HAVE_SYMLINKAT
7428 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007429 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 else
7431#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007432 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433 Py_END_ALLOW_THREADS
7434
Larry Hastings2f936352014-08-05 14:04:04 +10007435 if (result)
7436 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007437#endif
7438
Larry Hastings2f936352014-08-05 14:04:04 +10007439 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007440}
7441#endif /* HAVE_SYMLINK */
7442
Larry Hastings9cf065c2012-06-22 16:30:09 -07007443
Brian Curtind40e6f72010-07-08 21:39:08 +00007444
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007445
Larry Hastings605a62d2012-06-24 04:33:36 -07007446static PyStructSequence_Field times_result_fields[] = {
7447 {"user", "user time"},
7448 {"system", "system time"},
7449 {"children_user", "user time of children"},
7450 {"children_system", "system time of children"},
7451 {"elapsed", "elapsed time since an arbitrary point in the past"},
7452 {NULL}
7453};
7454
7455PyDoc_STRVAR(times_result__doc__,
7456"times_result: Result from os.times().\n\n\
7457This object may be accessed either as a tuple of\n\
7458 (user, system, children_user, children_system, elapsed),\n\
7459or via the attributes user, system, children_user, children_system,\n\
7460and elapsed.\n\
7461\n\
7462See os.times for more information.");
7463
7464static PyStructSequence_Desc times_result_desc = {
7465 "times_result", /* name */
7466 times_result__doc__, /* doc */
7467 times_result_fields,
7468 5
7469};
7470
7471static PyTypeObject TimesResultType;
7472
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007473#ifdef MS_WINDOWS
7474#define HAVE_TIMES /* mandatory, for the method table */
7475#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007476
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007477#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007478
7479static PyObject *
7480build_times_result(double user, double system,
7481 double children_user, double children_system,
7482 double elapsed)
7483{
7484 PyObject *value = PyStructSequence_New(&TimesResultType);
7485 if (value == NULL)
7486 return NULL;
7487
7488#define SET(i, field) \
7489 { \
7490 PyObject *o = PyFloat_FromDouble(field); \
7491 if (!o) { \
7492 Py_DECREF(value); \
7493 return NULL; \
7494 } \
7495 PyStructSequence_SET_ITEM(value, i, o); \
7496 } \
7497
7498 SET(0, user);
7499 SET(1, system);
7500 SET(2, children_user);
7501 SET(3, children_system);
7502 SET(4, elapsed);
7503
7504#undef SET
7505
7506 return value;
7507}
7508
Larry Hastings605a62d2012-06-24 04:33:36 -07007509
Larry Hastings2f936352014-08-05 14:04:04 +10007510#ifndef MS_WINDOWS
7511#define NEED_TICKS_PER_SECOND
7512static long ticks_per_second = -1;
7513#endif /* MS_WINDOWS */
7514
7515/*[clinic input]
7516os.times
7517
7518Return a collection containing process timing information.
7519
7520The object returned behaves like a named tuple with these fields:
7521 (utime, stime, cutime, cstime, elapsed_time)
7522All fields are floating point numbers.
7523[clinic start generated code]*/
7524
Larry Hastings2f936352014-08-05 14:04:04 +10007525static PyObject *
7526os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007527/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007528#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007529{
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 FILETIME create, exit, kernel, user;
7531 HANDLE hProc;
7532 hProc = GetCurrentProcess();
7533 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7534 /* The fields of a FILETIME structure are the hi and lo part
7535 of a 64-bit value expressed in 100 nanosecond units.
7536 1e7 is one second in such units; 1e-7 the inverse.
7537 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7538 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007539 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 (double)(user.dwHighDateTime*429.4967296 +
7541 user.dwLowDateTime*1e-7),
7542 (double)(kernel.dwHighDateTime*429.4967296 +
7543 kernel.dwLowDateTime*1e-7),
7544 (double)0,
7545 (double)0,
7546 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007547}
Larry Hastings2f936352014-08-05 14:04:04 +10007548#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007549{
Larry Hastings2f936352014-08-05 14:04:04 +10007550
7551
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007552 struct tms t;
7553 clock_t c;
7554 errno = 0;
7555 c = times(&t);
7556 if (c == (clock_t) -1)
7557 return posix_error();
7558 return build_times_result(
7559 (double)t.tms_utime / ticks_per_second,
7560 (double)t.tms_stime / ticks_per_second,
7561 (double)t.tms_cutime / ticks_per_second,
7562 (double)t.tms_cstime / ticks_per_second,
7563 (double)c / ticks_per_second);
7564}
Larry Hastings2f936352014-08-05 14:04:04 +10007565#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007566#endif /* HAVE_TIMES */
7567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007568
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007569#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007570/*[clinic input]
7571os.getsid
7572
7573 pid: pid_t
7574 /
7575
7576Call the system call getsid(pid) and return the result.
7577[clinic start generated code]*/
7578
Larry Hastings2f936352014-08-05 14:04:04 +10007579static PyObject *
7580os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007581/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007582{
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 sid = getsid(pid);
7585 if (sid < 0)
7586 return posix_error();
7587 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007588}
7589#endif /* HAVE_GETSID */
7590
7591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007593/*[clinic input]
7594os.setsid
7595
7596Call the system call setsid().
7597[clinic start generated code]*/
7598
Larry Hastings2f936352014-08-05 14:04:04 +10007599static PyObject *
7600os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007601/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602{
Victor Stinner8c62be82010-05-06 00:08:46 +00007603 if (setsid() < 0)
7604 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007605 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007606}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007608
Larry Hastings2f936352014-08-05 14:04:04 +10007609
Guido van Rossumb6775db1994-08-01 11:34:53 +00007610#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007611/*[clinic input]
7612os.setpgid
7613
7614 pid: pid_t
7615 pgrp: pid_t
7616 /
7617
7618Call the system call setpgid(pid, pgrp).
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
7622os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007623/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 if (setpgid(pid, pgrp) < 0)
7626 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007627 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007628}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007629#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Guido van Rossumb6775db1994-08-01 11:34:53 +00007632#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007633/*[clinic input]
7634os.tcgetpgrp
7635
7636 fd: int
7637 /
7638
7639Return the process group associated with the terminal specified by fd.
7640[clinic start generated code]*/
7641
Larry Hastings2f936352014-08-05 14:04:04 +10007642static PyObject *
7643os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007644/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007645{
7646 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 if (pgid < 0)
7648 return posix_error();
7649 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007650}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007651#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007653
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007655/*[clinic input]
7656os.tcsetpgrp
7657
7658 fd: int
7659 pgid: pid_t
7660 /
7661
7662Set the process group associated with the terminal specified by fd.
7663[clinic start generated code]*/
7664
Larry Hastings2f936352014-08-05 14:04:04 +10007665static PyObject *
7666os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007667/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 if (tcsetpgrp(fd, pgid) < 0)
7670 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007671 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007672}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007673#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007674
Guido van Rossum687dd131993-05-17 08:34:16 +00007675/* Functions acting on file descriptors */
7676
Victor Stinnerdaf45552013-08-28 00:53:59 +02007677#ifdef O_CLOEXEC
7678extern int _Py_open_cloexec_works;
7679#endif
7680
Larry Hastings2f936352014-08-05 14:04:04 +10007681
7682/*[clinic input]
7683os.open -> int
7684 path: path_t
7685 flags: int
7686 mode: int = 0o777
7687 *
7688 dir_fd: dir_fd(requires='openat') = None
7689
7690# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7691
7692Open a file for low level IO. Returns a file descriptor (integer).
7693
7694If dir_fd is not None, it should be a file descriptor open to a directory,
7695 and path should be relative; path will then be relative to that directory.
7696dir_fd may not be implemented on your platform.
7697 If it is unavailable, using it will raise a NotImplementedError.
7698[clinic start generated code]*/
7699
Larry Hastings2f936352014-08-05 14:04:04 +10007700static int
Larry Hastings89964c42015-04-14 18:07:59 -04007701os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7702 int dir_fd)
7703/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007704{
7705 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007706 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007707
Victor Stinnerdaf45552013-08-28 00:53:59 +02007708#ifdef O_CLOEXEC
7709 int *atomic_flag_works = &_Py_open_cloexec_works;
7710#elif !defined(MS_WINDOWS)
7711 int *atomic_flag_works = NULL;
7712#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007713
Victor Stinnerdaf45552013-08-28 00:53:59 +02007714#ifdef MS_WINDOWS
7715 flags |= O_NOINHERIT;
7716#elif defined(O_CLOEXEC)
7717 flags |= O_CLOEXEC;
7718#endif
7719
Steve Dower8fc89802015-04-12 00:26:27 -04007720 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007721 do {
7722 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007723#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007724 if (path->wide)
7725 fd = _wopen(path->wide, flags, mode);
7726 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727#endif
7728#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 if (dir_fd != DEFAULT_DIR_FD)
7730 fd = openat(dir_fd, path->narrow, flags, mode);
7731 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007732#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 fd = open(path->narrow, flags, mode);
7734 Py_END_ALLOW_THREADS
7735 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007736 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007737
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738 if (fd == -1) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007739 if (!async_err)
7740 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007741 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742 }
7743
Victor Stinnerdaf45552013-08-28 00:53:59 +02007744#ifndef MS_WINDOWS
7745 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7746 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007747 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007748 }
7749#endif
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751 return fd;
7752}
7753
7754
7755/*[clinic input]
7756os.close
7757
7758 fd: int
7759
7760Close a file descriptor.
7761[clinic start generated code]*/
7762
Barry Warsaw53699e91996-12-10 23:23:01 +00007763static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007764os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007765/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007766{
Larry Hastings2f936352014-08-05 14:04:04 +10007767 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 if (!_PyVerify_fd(fd))
7769 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007770 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7771 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7772 * for more details.
7773 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007775 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007777 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 Py_END_ALLOW_THREADS
7779 if (res < 0)
7780 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007781 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007782}
7783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007784
Larry Hastings2f936352014-08-05 14:04:04 +10007785/*[clinic input]
7786os.closerange
7787
7788 fd_low: int
7789 fd_high: int
7790 /
7791
7792Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7793[clinic start generated code]*/
7794
Larry Hastings2f936352014-08-05 14:04:04 +10007795static PyObject *
7796os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007797/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007798{
7799 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007801 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007802 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 if (_PyVerify_fd(i))
7804 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007805 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 Py_END_ALLOW_THREADS
7807 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007808}
7809
7810
Larry Hastings2f936352014-08-05 14:04:04 +10007811/*[clinic input]
7812os.dup -> int
7813
7814 fd: int
7815 /
7816
7817Return a duplicate of a file descriptor.
7818[clinic start generated code]*/
7819
Larry Hastings2f936352014-08-05 14:04:04 +10007820static int
7821os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007822/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007823{
7824 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007825}
7826
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007827
Larry Hastings2f936352014-08-05 14:04:04 +10007828/*[clinic input]
7829os.dup2
7830 fd: int
7831 fd2: int
7832 inheritable: bool=True
7833
7834Duplicate file descriptor.
7835[clinic start generated code]*/
7836
Larry Hastings2f936352014-08-05 14:04:04 +10007837static PyObject *
7838os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007839/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007840{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007841 int res;
7842#if defined(HAVE_DUP3) && \
7843 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7844 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7845 int dup3_works = -1;
7846#endif
7847
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 if (!_PyVerify_fd_dup2(fd, fd2))
7849 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007850
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007851 /* dup2() can fail with EINTR if the target FD is already open, because it
7852 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7853 * upon close(), and therefore below.
7854 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007855#ifdef MS_WINDOWS
7856 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007857 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007859 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 if (res < 0)
7862 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007863
7864 /* Character files like console cannot be make non-inheritable */
7865 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7866 close(fd2);
7867 return NULL;
7868 }
7869
7870#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7871 Py_BEGIN_ALLOW_THREADS
7872 if (!inheritable)
7873 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7874 else
7875 res = dup2(fd, fd2);
7876 Py_END_ALLOW_THREADS
7877 if (res < 0)
7878 return posix_error();
7879
7880#else
7881
7882#ifdef HAVE_DUP3
7883 if (!inheritable && dup3_works != 0) {
7884 Py_BEGIN_ALLOW_THREADS
7885 res = dup3(fd, fd2, O_CLOEXEC);
7886 Py_END_ALLOW_THREADS
7887 if (res < 0) {
7888 if (dup3_works == -1)
7889 dup3_works = (errno != ENOSYS);
7890 if (dup3_works)
7891 return posix_error();
7892 }
7893 }
7894
7895 if (inheritable || dup3_works == 0)
7896 {
7897#endif
7898 Py_BEGIN_ALLOW_THREADS
7899 res = dup2(fd, fd2);
7900 Py_END_ALLOW_THREADS
7901 if (res < 0)
7902 return posix_error();
7903
7904 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7905 close(fd2);
7906 return NULL;
7907 }
7908#ifdef HAVE_DUP3
7909 }
7910#endif
7911
7912#endif
7913
Larry Hastings2f936352014-08-05 14:04:04 +10007914 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007915}
7916
Larry Hastings2f936352014-08-05 14:04:04 +10007917
Ross Lagerwall7807c352011-03-17 20:20:30 +02007918#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007919/*[clinic input]
7920os.lockf
7921
7922 fd: int
7923 An open file descriptor.
7924 command: int
7925 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7926 length: Py_off_t
7927 The number of bytes to lock, starting at the current position.
7928 /
7929
7930Apply, test or remove a POSIX lock on an open file descriptor.
7931
7932[clinic start generated code]*/
7933
Larry Hastings2f936352014-08-05 14:04:04 +10007934static PyObject *
7935os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007936/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007937{
7938 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939
7940 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007941 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007942 Py_END_ALLOW_THREADS
7943
7944 if (res < 0)
7945 return posix_error();
7946
7947 Py_RETURN_NONE;
7948}
Larry Hastings2f936352014-08-05 14:04:04 +10007949#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007951
Larry Hastings2f936352014-08-05 14:04:04 +10007952/*[clinic input]
7953os.lseek -> Py_off_t
7954
7955 fd: int
7956 position: Py_off_t
7957 how: int
7958 /
7959
7960Set the position of a file descriptor. Return the new position.
7961
7962Return the new cursor position in number of bytes
7963relative to the beginning of the file.
7964[clinic start generated code]*/
7965
Larry Hastings2f936352014-08-05 14:04:04 +10007966static Py_off_t
7967os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007968/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007969{
7970 Py_off_t result;
7971
7972 if (!_PyVerify_fd(fd)) {
7973 posix_error();
7974 return -1;
7975 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007976#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7978 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007979 case 0: how = SEEK_SET; break;
7980 case 1: how = SEEK_CUR; break;
7981 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007983#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007984
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007986 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007987
Larry Hastings2f936352014-08-05 14:04:04 +10007988 if (!_PyVerify_fd(fd)) {
7989 posix_error();
7990 return -1;
7991 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007993 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007994#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007995 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007996#else
Larry Hastings2f936352014-08-05 14:04:04 +10007997 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007998#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007999 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008001 if (result < 0)
8002 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008003
Larry Hastings2f936352014-08-05 14:04:04 +10008004 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008005}
8006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008007
Larry Hastings2f936352014-08-05 14:04:04 +10008008/*[clinic input]
8009os.read
8010 fd: int
8011 length: Py_ssize_t
8012 /
8013
8014Read from a file descriptor. Returns a bytes object.
8015[clinic start generated code]*/
8016
Larry Hastings2f936352014-08-05 14:04:04 +10008017static PyObject *
8018os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008019/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008020{
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 Py_ssize_t n;
8022 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008023
8024 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 errno = EINVAL;
8026 return posix_error();
8027 }
Larry Hastings2f936352014-08-05 14:04:04 +10008028
8029#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008030 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008031 if (length > INT_MAX)
8032 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008033#endif
8034
8035 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 if (buffer == NULL)
8037 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038
Victor Stinner66aab0c2015-03-19 22:53:20 +01008039 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8040 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008042 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 }
Larry Hastings2f936352014-08-05 14:04:04 +10008044
8045 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008046 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008047
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008049}
8050
Ross Lagerwall7807c352011-03-17 20:20:30 +02008051#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8052 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008053static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8055{
8056 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008057 Py_ssize_t blen, total = 0;
8058
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 *iov = PyMem_New(struct iovec, cnt);
8060 if (*iov == NULL) {
8061 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008062 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008064
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065 *buf = PyMem_New(Py_buffer, cnt);
8066 if (*buf == NULL) {
8067 PyMem_Del(*iov);
8068 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008069 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 }
8071
8072 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008073 PyObject *item = PySequence_GetItem(seq, i);
8074 if (item == NULL)
8075 goto fail;
8076 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8077 Py_DECREF(item);
8078 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008080 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008082 blen = (*buf)[i].len;
8083 (*iov)[i].iov_len = blen;
8084 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008085 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008086 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008087
8088fail:
8089 PyMem_Del(*iov);
8090 for (j = 0; j < i; j++) {
8091 PyBuffer_Release(&(*buf)[j]);
8092 }
8093 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008094 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095}
8096
8097static void
8098iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8099{
8100 int i;
8101 PyMem_Del(iov);
8102 for (i = 0; i < cnt; i++) {
8103 PyBuffer_Release(&buf[i]);
8104 }
8105 PyMem_Del(buf);
8106}
8107#endif
8108
Larry Hastings2f936352014-08-05 14:04:04 +10008109
Ross Lagerwall7807c352011-03-17 20:20:30 +02008110#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008111/*[clinic input]
8112os.readv -> Py_ssize_t
8113
8114 fd: int
8115 buffers: object
8116 /
8117
8118Read from a file descriptor fd into an iterable of buffers.
8119
8120The buffers should be mutable buffers accepting bytes.
8121readv will transfer data into each buffer until it is full
8122and then move on to the next buffer in the sequence to hold
8123the rest of the data.
8124
8125readv returns the total number of bytes read,
8126which may be less than the total capacity of all the buffers.
8127[clinic start generated code]*/
8128
Larry Hastings2f936352014-08-05 14:04:04 +10008129static Py_ssize_t
8130os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008131/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008132{
8133 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008134 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008135 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 struct iovec *iov;
8137 Py_buffer *buf;
8138
Larry Hastings2f936352014-08-05 14:04:04 +10008139 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008140 PyErr_SetString(PyExc_TypeError,
8141 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008142 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144
Larry Hastings2f936352014-08-05 14:04:04 +10008145 cnt = PySequence_Size(buffers);
8146
8147 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8148 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008150 do {
8151 Py_BEGIN_ALLOW_THREADS
8152 n = readv(fd, iov, cnt);
8153 Py_END_ALLOW_THREADS
8154 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008155
8156 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008157 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008158 if (!async_err)
8159 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008160 return -1;
8161 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008162
Larry Hastings2f936352014-08-05 14:04:04 +10008163 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008164}
Larry Hastings2f936352014-08-05 14:04:04 +10008165#endif /* HAVE_READV */
8166
Ross Lagerwall7807c352011-03-17 20:20:30 +02008167
8168#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008169/*[clinic input]
8170# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8171os.pread
8172
8173 fd: int
8174 length: int
8175 offset: Py_off_t
8176 /
8177
8178Read a number of bytes from a file descriptor starting at a particular offset.
8179
8180Read length bytes from file descriptor fd, starting at offset bytes from
8181the beginning of the file. The file offset remains unchanged.
8182[clinic start generated code]*/
8183
Larry Hastings2f936352014-08-05 14:04:04 +10008184static PyObject *
8185os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008186/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008187{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008189 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191
Larry Hastings2f936352014-08-05 14:04:04 +10008192 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008193 errno = EINVAL;
8194 return posix_error();
8195 }
Larry Hastings2f936352014-08-05 14:04:04 +10008196 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008197 if (buffer == NULL)
8198 return NULL;
8199 if (!_PyVerify_fd(fd)) {
8200 Py_DECREF(buffer);
8201 return posix_error();
8202 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008203
8204 do {
8205 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008206 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008207 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008208 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008209 Py_END_ALLOW_THREADS
8210 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8211
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212 if (n < 0) {
8213 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008214 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008215 }
Larry Hastings2f936352014-08-05 14:04:04 +10008216 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008217 _PyBytes_Resize(&buffer, n);
8218 return buffer;
8219}
Larry Hastings2f936352014-08-05 14:04:04 +10008220#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008221
Larry Hastings2f936352014-08-05 14:04:04 +10008222
8223/*[clinic input]
8224os.write -> Py_ssize_t
8225
8226 fd: int
8227 data: Py_buffer
8228 /
8229
8230Write a bytes object to a file descriptor.
8231[clinic start generated code]*/
8232
Larry Hastings2f936352014-08-05 14:04:04 +10008233static Py_ssize_t
8234os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008235/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008236{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008237 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008238}
8239
8240#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008241PyDoc_STRVAR(posix_sendfile__doc__,
8242"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8243sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8244 -> byteswritten\n\
8245Copy nbytes bytes from file descriptor in to file descriptor out.");
8246
Larry Hastings2f936352014-08-05 14:04:04 +10008247/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248static PyObject *
8249posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8250{
8251 int in, out;
8252 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008253 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008254 off_t offset;
8255
8256#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8257#ifndef __APPLE__
8258 Py_ssize_t len;
8259#endif
8260 PyObject *headers = NULL, *trailers = NULL;
8261 Py_buffer *hbuf, *tbuf;
8262 off_t sbytes;
8263 struct sf_hdtr sf;
8264 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008265 static char *keywords[] = {"out", "in",
8266 "offset", "count",
8267 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008269 sf.headers = NULL;
8270 sf.trailers = NULL;
8271
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272#ifdef __APPLE__
8273 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008274 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275#else
8276 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008277 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008278#endif
8279 &headers, &trailers, &flags))
8280 return NULL;
8281 if (headers != NULL) {
8282 if (!PySequence_Check(headers)) {
8283 PyErr_SetString(PyExc_TypeError,
8284 "sendfile() headers must be a sequence or None");
8285 return NULL;
8286 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008287 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008289 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008290 (i = iov_setup(&(sf.headers), &hbuf,
8291 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008292 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008293#ifdef __APPLE__
8294 sbytes += i;
8295#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 }
8297 }
8298 if (trailers != NULL) {
8299 if (!PySequence_Check(trailers)) {
8300 PyErr_SetString(PyExc_TypeError,
8301 "sendfile() trailers must be a sequence or None");
8302 return NULL;
8303 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008304 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008306 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008307 (i = iov_setup(&(sf.trailers), &tbuf,
8308 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008310#ifdef __APPLE__
8311 sbytes += i;
8312#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008313 }
8314 }
8315
Steve Dower8fc89802015-04-12 00:26:27 -04008316 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 do {
8318 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008319#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 Py_END_ALLOW_THREADS
8325 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008326 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327
8328 if (sf.headers != NULL)
8329 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8330 if (sf.trailers != NULL)
8331 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8332
8333 if (ret < 0) {
8334 if ((errno == EAGAIN) || (errno == EBUSY)) {
8335 if (sbytes != 0) {
8336 // some data has been sent
8337 goto done;
8338 }
8339 else {
8340 // no data has been sent; upper application is supposed
8341 // to retry on EAGAIN or EBUSY
8342 return posix_error();
8343 }
8344 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008345 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008346 }
8347 goto done;
8348
8349done:
8350 #if !defined(HAVE_LARGEFILE_SUPPORT)
8351 return Py_BuildValue("l", sbytes);
8352 #else
8353 return Py_BuildValue("L", sbytes);
8354 #endif
8355
8356#else
8357 Py_ssize_t count;
8358 PyObject *offobj;
8359 static char *keywords[] = {"out", "in",
8360 "offset", "count", NULL};
8361 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8362 keywords, &out, &in, &offobj, &count))
8363 return NULL;
8364#ifdef linux
8365 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 do {
8367 Py_BEGIN_ALLOW_THREADS
8368 ret = sendfile(out, in, NULL, count);
8369 Py_END_ALLOW_THREADS
8370 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008371 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008372 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008373 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008374 }
8375#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008376 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008377 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378
8379 do {
8380 Py_BEGIN_ALLOW_THREADS
8381 ret = sendfile(out, in, &offset, count);
8382 Py_END_ALLOW_THREADS
8383 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008384 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008385 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 return Py_BuildValue("n", ret);
8387#endif
8388}
Larry Hastings2f936352014-08-05 14:04:04 +10008389#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008390
Larry Hastings2f936352014-08-05 14:04:04 +10008391
8392/*[clinic input]
8393os.fstat
8394
8395 fd : int
8396
8397Perform a stat system call on the given file descriptor.
8398
8399Like stat(), but for an open file descriptor.
8400Equivalent to os.stat(fd).
8401[clinic start generated code]*/
8402
Larry Hastings2f936352014-08-05 14:04:04 +10008403static PyObject *
8404os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008405/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008406{
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 STRUCT_STAT st;
8408 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008410
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 do {
8412 Py_BEGIN_ALLOW_THREADS
8413 res = FSTAT(fd, &st);
8414 Py_END_ALLOW_THREADS
8415 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008417#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008418 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008419#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008421#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 }
Tim Peters5aa91602002-01-30 05:46:57 +00008423
Victor Stinner4195b5c2012-02-08 23:03:19 +01008424 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008425}
8426
Larry Hastings2f936352014-08-05 14:04:04 +10008427
8428/*[clinic input]
8429os.isatty -> bool
8430 fd: int
8431 /
8432
8433Return True if the fd is connected to a terminal.
8434
8435Return True if the file descriptor is an open file descriptor
8436connected to the slave end of a terminal.
8437[clinic start generated code]*/
8438
Larry Hastings2f936352014-08-05 14:04:04 +10008439static int
8440os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008441/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008442{
Steve Dower8fc89802015-04-12 00:26:27 -04008443 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008444 if (!_PyVerify_fd(fd))
8445 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008446 _Py_BEGIN_SUPPRESS_IPH
8447 return_value = isatty(fd);
8448 _Py_END_SUPPRESS_IPH
8449 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008450}
8451
8452
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008453#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008454/*[clinic input]
8455os.pipe
8456
8457Create a pipe.
8458
8459Returns a tuple of two file descriptors:
8460 (read_fd, write_fd)
8461[clinic start generated code]*/
8462
Larry Hastings2f936352014-08-05 14:04:04 +10008463static PyObject *
8464os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008465/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008466{
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008468#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472#else
8473 int res;
8474#endif
8475
8476#ifdef MS_WINDOWS
8477 attr.nLength = sizeof(attr);
8478 attr.lpSecurityDescriptor = NULL;
8479 attr.bInheritHandle = FALSE;
8480
8481 Py_BEGIN_ALLOW_THREADS
8482 ok = CreatePipe(&read, &write, &attr, 0);
8483 if (ok) {
8484 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8485 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8486 if (fds[0] == -1 || fds[1] == -1) {
8487 CloseHandle(read);
8488 CloseHandle(write);
8489 ok = 0;
8490 }
8491 }
8492 Py_END_ALLOW_THREADS
8493
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008495 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008496#else
8497
8498#ifdef HAVE_PIPE2
8499 Py_BEGIN_ALLOW_THREADS
8500 res = pipe2(fds, O_CLOEXEC);
8501 Py_END_ALLOW_THREADS
8502
8503 if (res != 0 && errno == ENOSYS)
8504 {
8505#endif
8506 Py_BEGIN_ALLOW_THREADS
8507 res = pipe(fds);
8508 Py_END_ALLOW_THREADS
8509
8510 if (res == 0) {
8511 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8512 close(fds[0]);
8513 close(fds[1]);
8514 return NULL;
8515 }
8516 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8517 close(fds[0]);
8518 close(fds[1]);
8519 return NULL;
8520 }
8521 }
8522#ifdef HAVE_PIPE2
8523 }
8524#endif
8525
8526 if (res != 0)
8527 return PyErr_SetFromErrno(PyExc_OSError);
8528#endif /* !MS_WINDOWS */
8529 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008530}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008531#endif /* HAVE_PIPE */
8532
Larry Hastings2f936352014-08-05 14:04:04 +10008533
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008534#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008535/*[clinic input]
8536os.pipe2
8537
8538 flags: int
8539 /
8540
8541Create a pipe with flags set atomically.
8542
8543Returns a tuple of two file descriptors:
8544 (read_fd, write_fd)
8545
8546flags can be constructed by ORing together one or more of these values:
8547O_NONBLOCK, O_CLOEXEC.
8548[clinic start generated code]*/
8549
Larry Hastings2f936352014-08-05 14:04:04 +10008550static PyObject *
8551os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008552/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008553{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008554 int fds[2];
8555 int res;
8556
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008557 res = pipe2(fds, flags);
8558 if (res != 0)
8559 return posix_error();
8560 return Py_BuildValue("(ii)", fds[0], fds[1]);
8561}
8562#endif /* HAVE_PIPE2 */
8563
Larry Hastings2f936352014-08-05 14:04:04 +10008564
Ross Lagerwall7807c352011-03-17 20:20:30 +02008565#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008566/*[clinic input]
8567os.writev -> Py_ssize_t
8568 fd: int
8569 buffers: object
8570 /
8571
8572Iterate over buffers, and write the contents of each to a file descriptor.
8573
8574Returns the total number of bytes written.
8575buffers must be a sequence of bytes-like objects.
8576[clinic start generated code]*/
8577
Larry Hastings2f936352014-08-05 14:04:04 +10008578static Py_ssize_t
8579os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008580/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008581{
8582 int cnt;
8583 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008584 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008585 struct iovec *iov;
8586 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008587
8588 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008589 PyErr_SetString(PyExc_TypeError,
8590 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008591 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008592 }
Larry Hastings2f936352014-08-05 14:04:04 +10008593 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594
Larry Hastings2f936352014-08-05 14:04:04 +10008595 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8596 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597 }
8598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008599 do {
8600 Py_BEGIN_ALLOW_THREADS
8601 result = writev(fd, iov, cnt);
8602 Py_END_ALLOW_THREADS
8603 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008604
8605 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008606 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008607 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008608
Georg Brandl306336b2012-06-24 12:55:33 +02008609 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008610}
Larry Hastings2f936352014-08-05 14:04:04 +10008611#endif /* HAVE_WRITEV */
8612
8613
8614#ifdef HAVE_PWRITE
8615/*[clinic input]
8616os.pwrite -> Py_ssize_t
8617
8618 fd: int
8619 buffer: Py_buffer
8620 offset: Py_off_t
8621 /
8622
8623Write bytes to a file descriptor starting at a particular offset.
8624
8625Write buffer to fd, starting at offset bytes from the beginning of
8626the file. Returns the number of bytes writte. Does not change the
8627current file offset.
8628[clinic start generated code]*/
8629
Larry Hastings2f936352014-08-05 14:04:04 +10008630static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008631os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8632 Py_off_t offset)
8633/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008634{
8635 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008636 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008637
8638 if (!_PyVerify_fd(fd)) {
8639 posix_error();
8640 return -1;
8641 }
8642
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 do {
8644 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008645 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008647 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 Py_END_ALLOW_THREADS
8649 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008650
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008652 posix_error();
8653 return size;
8654}
8655#endif /* HAVE_PWRITE */
8656
8657
8658#ifdef HAVE_MKFIFO
8659/*[clinic input]
8660os.mkfifo
8661
8662 path: path_t
8663 mode: int=0o666
8664 *
8665 dir_fd: dir_fd(requires='mkfifoat')=None
8666
8667Create a "fifo" (a POSIX named pipe).
8668
8669If dir_fd is not None, it should be a file descriptor open to a directory,
8670 and path should be relative; path will then be relative to that directory.
8671dir_fd may not be implemented on your platform.
8672 If it is unavailable, using it will raise a NotImplementedError.
8673[clinic start generated code]*/
8674
Larry Hastings2f936352014-08-05 14:04:04 +10008675static PyObject *
8676os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008677/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008678{
8679 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008681
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 do {
8683 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008684#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008685 if (dir_fd != DEFAULT_DIR_FD)
8686 result = mkfifoat(dir_fd, path->narrow, mode);
8687 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008688#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 result = mkfifo(path->narrow, mode);
8690 Py_END_ALLOW_THREADS
8691 } while (result != 0 && errno == EINTR &&
8692 !(async_err = PyErr_CheckSignals()));
8693 if (result != 0)
8694 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008695
8696 Py_RETURN_NONE;
8697}
8698#endif /* HAVE_MKFIFO */
8699
8700
8701#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8702/*[clinic input]
8703os.mknod
8704
8705 path: path_t
8706 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008707 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008708 *
8709 dir_fd: dir_fd(requires='mknodat')=None
8710
8711Create a node in the file system.
8712
8713Create a node in the file system (file, device special file or named pipe)
8714at path. mode specifies both the permissions to use and the
8715type of node to be created, being combined (bitwise OR) with one of
8716S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8717device defines the newly created device special file (probably using
8718os.makedev()). Otherwise device is ignored.
8719
8720If dir_fd is not None, it should be a file descriptor open to a directory,
8721 and path should be relative; path will then be relative to that directory.
8722dir_fd may not be implemented on your platform.
8723 If it is unavailable, using it will raise a NotImplementedError.
8724[clinic start generated code]*/
8725
Larry Hastings2f936352014-08-05 14:04:04 +10008726static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008727os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8728 int dir_fd)
8729/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008730{
8731 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008732 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008733
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008734 do {
8735 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008736#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008737 if (dir_fd != DEFAULT_DIR_FD)
8738 result = mknodat(dir_fd, path->narrow, mode, device);
8739 else
Larry Hastings2f936352014-08-05 14:04:04 +10008740#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 result = mknod(path->narrow, mode, device);
8742 Py_END_ALLOW_THREADS
8743 } while (result != 0 && errno == EINTR &&
8744 !(async_err = PyErr_CheckSignals()));
8745 if (result != 0)
8746 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008747
8748 Py_RETURN_NONE;
8749}
8750#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8751
8752
8753#ifdef HAVE_DEVICE_MACROS
8754/*[clinic input]
8755os.major -> unsigned_int
8756
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008757 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008758 /
8759
8760Extracts a device major number from a raw device number.
8761[clinic start generated code]*/
8762
Larry Hastings2f936352014-08-05 14:04:04 +10008763static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008764os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008765/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008766{
8767 return major(device);
8768}
8769
8770
8771/*[clinic input]
8772os.minor -> unsigned_int
8773
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008774 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008775 /
8776
8777Extracts a device minor number from a raw device number.
8778[clinic start generated code]*/
8779
Larry Hastings2f936352014-08-05 14:04:04 +10008780static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008781os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008782/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008783{
8784 return minor(device);
8785}
8786
8787
8788/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008789os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008790
8791 major: int
8792 minor: int
8793 /
8794
8795Composes a raw device number from the major and minor device numbers.
8796[clinic start generated code]*/
8797
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008798static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008799os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008800/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008801{
8802 return makedev(major, minor);
8803}
8804#endif /* HAVE_DEVICE_MACROS */
8805
8806
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008807#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008808/*[clinic input]
8809os.ftruncate
8810
8811 fd: int
8812 length: Py_off_t
8813 /
8814
8815Truncate a file, specified by file descriptor, to a specific length.
8816[clinic start generated code]*/
8817
Larry Hastings2f936352014-08-05 14:04:04 +10008818static PyObject *
8819os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008820/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008821{
8822 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008823 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008824
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008825 if (!_PyVerify_fd(fd))
8826 return posix_error();
8827
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008828 do {
8829 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008830 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008831#ifdef MS_WINDOWS
8832 result = _chsize_s(fd, length);
8833#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008834 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008835#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008836 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008837 Py_END_ALLOW_THREADS
8838 } while (result != 0 && errno == EINTR &&
8839 !(async_err = PyErr_CheckSignals()));
8840 if (result != 0)
8841 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008842 Py_RETURN_NONE;
8843}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008844#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008845
8846
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008847#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008848/*[clinic input]
8849os.truncate
8850 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8851 length: Py_off_t
8852
8853Truncate a file, specified by path, to a specific length.
8854
8855On some platforms, path may also be specified as an open file descriptor.
8856 If this functionality is unavailable, using it raises an exception.
8857[clinic start generated code]*/
8858
Larry Hastings2f936352014-08-05 14:04:04 +10008859static PyObject *
8860os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008861/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008862{
8863 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008864#ifdef MS_WINDOWS
8865 int fd;
8866#endif
8867
8868 if (path->fd != -1)
8869 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008870
8871 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008872 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008873#ifdef MS_WINDOWS
8874 if (path->wide)
8875 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008876 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008877 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008878 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008879 result = -1;
8880 else {
8881 result = _chsize_s(fd, length);
8882 close(fd);
8883 if (result < 0)
8884 errno = result;
8885 }
8886#else
8887 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008888#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008889 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008890 Py_END_ALLOW_THREADS
8891 if (result < 0)
8892 return path_error(path);
8893
8894 Py_RETURN_NONE;
8895}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008896#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008897
Ross Lagerwall7807c352011-03-17 20:20:30 +02008898
Victor Stinnerd6b17692014-09-30 12:20:05 +02008899/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8900 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8901 defined, which is the case in Python on AIX. AIX bug report:
8902 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8903#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8904# define POSIX_FADVISE_AIX_BUG
8905#endif
8906
Victor Stinnerec39e262014-09-30 12:35:58 +02008907
Victor Stinnerd6b17692014-09-30 12:20:05 +02008908#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008909/*[clinic input]
8910os.posix_fallocate
8911
8912 fd: int
8913 offset: Py_off_t
8914 length: Py_off_t
8915 /
8916
8917Ensure a file has allocated at least a particular number of bytes on disk.
8918
8919Ensure that the file specified by fd encompasses a range of bytes
8920starting at offset bytes from the beginning and continuing for length bytes.
8921[clinic start generated code]*/
8922
Larry Hastings2f936352014-08-05 14:04:04 +10008923static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008924os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8925 Py_off_t length)
8926/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008927{
8928 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008929 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008930
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008931 do {
8932 Py_BEGIN_ALLOW_THREADS
8933 result = posix_fallocate(fd, offset, length);
8934 Py_END_ALLOW_THREADS
8935 } while (result != 0 && errno == EINTR &&
8936 !(async_err = PyErr_CheckSignals()));
8937 if (result != 0)
8938 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008939 Py_RETURN_NONE;
8940}
Victor Stinnerec39e262014-09-30 12:35:58 +02008941#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008942
Ross Lagerwall7807c352011-03-17 20:20:30 +02008943
Victor Stinnerd6b17692014-09-30 12:20:05 +02008944#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008945/*[clinic input]
8946os.posix_fadvise
8947
8948 fd: int
8949 offset: Py_off_t
8950 length: Py_off_t
8951 advice: int
8952 /
8953
8954Announce an intention to access data in a specific pattern.
8955
8956Announce an intention to access data in a specific pattern, thus allowing
8957the kernel to make optimizations.
8958The advice applies to the region of the file specified by fd starting at
8959offset and continuing for length bytes.
8960advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8961POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8962POSIX_FADV_DONTNEED.
8963[clinic start generated code]*/
8964
Larry Hastings2f936352014-08-05 14:04:04 +10008965static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008966os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8967 Py_off_t length, int advice)
8968/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008969{
8970 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008971 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008972
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008973 do {
8974 Py_BEGIN_ALLOW_THREADS
8975 result = posix_fadvise(fd, offset, length, advice);
8976 Py_END_ALLOW_THREADS
8977 } while (result != 0 && errno == EINTR &&
8978 !(async_err = PyErr_CheckSignals()));
8979 if (result != 0)
8980 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008981 Py_RETURN_NONE;
8982}
Victor Stinnerec39e262014-09-30 12:35:58 +02008983#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008984
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008985#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008986
Fred Drake762e2061999-08-26 17:23:54 +00008987/* Save putenv() parameters as values here, so we can collect them when they
8988 * get re-set with another call for the same key. */
8989static PyObject *posix_putenv_garbage;
8990
Larry Hastings2f936352014-08-05 14:04:04 +10008991static void
8992posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008993{
Larry Hastings2f936352014-08-05 14:04:04 +10008994 /* Install the first arg and newstr in posix_putenv_garbage;
8995 * this will cause previous value to be collected. This has to
8996 * happen after the real putenv() call because the old value
8997 * was still accessible until then. */
8998 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8999 /* really not much we can do; just leak */
9000 PyErr_Clear();
9001 else
9002 Py_DECREF(value);
9003}
9004
9005
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009006#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009007/*[clinic input]
9008os.putenv
9009
9010 name: unicode
9011 value: unicode
9012 /
9013
9014Change or add an environment variable.
9015[clinic start generated code]*/
9016
Larry Hastings2f936352014-08-05 14:04:04 +10009017static PyObject *
9018os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009019/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009020{
9021 wchar_t *env;
9022
9023 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9024 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009025 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009026 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009027 }
Larry Hastings2f936352014-08-05 14:04:04 +10009028 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009029 PyErr_Format(PyExc_ValueError,
9030 "the environment variable is longer than %u characters",
9031 _MAX_ENV);
9032 goto error;
9033 }
9034
Larry Hastings2f936352014-08-05 14:04:04 +10009035 env = PyUnicode_AsUnicode(unicode);
9036 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009037 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009038 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009040 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009042
Larry Hastings2f936352014-08-05 14:04:04 +10009043 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009044 Py_RETURN_NONE;
9045
9046error:
Larry Hastings2f936352014-08-05 14:04:04 +10009047 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009048 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009049}
Larry Hastings2f936352014-08-05 14:04:04 +10009050#else /* MS_WINDOWS */
9051/*[clinic input]
9052os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009053
Larry Hastings2f936352014-08-05 14:04:04 +10009054 name: FSConverter
9055 value: FSConverter
9056 /
9057
9058Change or add an environment variable.
9059[clinic start generated code]*/
9060
Larry Hastings2f936352014-08-05 14:04:04 +10009061static PyObject *
9062os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009063/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009064{
9065 PyObject *bytes = NULL;
9066 char *env;
9067 char *name_string = PyBytes_AsString(name);
9068 char *value_string = PyBytes_AsString(value);
9069
9070 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9071 if (bytes == NULL) {
9072 PyErr_NoMemory();
9073 return NULL;
9074 }
9075
9076 env = PyBytes_AS_STRING(bytes);
9077 if (putenv(env)) {
9078 Py_DECREF(bytes);
9079 return posix_error();
9080 }
9081
9082 posix_putenv_garbage_setitem(name, bytes);
9083 Py_RETURN_NONE;
9084}
9085#endif /* MS_WINDOWS */
9086#endif /* HAVE_PUTENV */
9087
9088
9089#ifdef HAVE_UNSETENV
9090/*[clinic input]
9091os.unsetenv
9092 name: FSConverter
9093 /
9094
9095Delete an environment variable.
9096[clinic start generated code]*/
9097
Larry Hastings2f936352014-08-05 14:04:04 +10009098static PyObject *
9099os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009100/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009101{
Victor Stinner984890f2011-11-24 13:53:38 +01009102#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009103 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009104#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009105
Victor Stinner984890f2011-11-24 13:53:38 +01009106#ifdef HAVE_BROKEN_UNSETENV
9107 unsetenv(PyBytes_AS_STRING(name));
9108#else
Victor Stinner65170952011-11-22 22:16:17 +01009109 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009110 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009111 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009112#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009113
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 /* Remove the key from posix_putenv_garbage;
9115 * this will cause it to be collected. This has to
9116 * happen after the real unsetenv() call because the
9117 * old value was still accessible until then.
9118 */
Victor Stinner65170952011-11-22 22:16:17 +01009119 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 /* really not much we can do; just leak */
9121 PyErr_Clear();
9122 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009123 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009124}
Larry Hastings2f936352014-08-05 14:04:04 +10009125#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009126
Larry Hastings2f936352014-08-05 14:04:04 +10009127
9128/*[clinic input]
9129os.strerror
9130
9131 code: int
9132 /
9133
9134Translate an error code to a message string.
9135[clinic start generated code]*/
9136
Larry Hastings2f936352014-08-05 14:04:04 +10009137static PyObject *
9138os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009139/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009140{
9141 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 if (message == NULL) {
9143 PyErr_SetString(PyExc_ValueError,
9144 "strerror() argument out of range");
9145 return NULL;
9146 }
Victor Stinner1b579672011-12-17 05:47:23 +01009147 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009148}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009149
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009150
Guido van Rossumc9641791998-08-04 15:26:23 +00009151#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009152#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009153/*[clinic input]
9154os.WCOREDUMP -> bool
9155
9156 status: int
9157 /
9158
9159Return True if the process returning status was dumped to a core file.
9160[clinic start generated code]*/
9161
Larry Hastings2f936352014-08-05 14:04:04 +10009162static int
9163os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009164/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009165{
9166 WAIT_TYPE wait_status;
9167 WAIT_STATUS_INT(wait_status) = status;
9168 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009169}
9170#endif /* WCOREDUMP */
9171
Larry Hastings2f936352014-08-05 14:04:04 +10009172
Fred Drake106c1a02002-04-23 15:58:02 +00009173#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009174/*[clinic input]
9175os.WIFCONTINUED -> bool
9176
9177 status: int
9178
9179Return True if a particular process was continued from a job control stop.
9180
9181Return True if the process returning status was continued from a
9182job control stop.
9183[clinic start generated code]*/
9184
Larry Hastings2f936352014-08-05 14:04:04 +10009185static int
9186os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009187/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009188{
9189 WAIT_TYPE wait_status;
9190 WAIT_STATUS_INT(wait_status) = status;
9191 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009192}
9193#endif /* WIFCONTINUED */
9194
Larry Hastings2f936352014-08-05 14:04:04 +10009195
Guido van Rossumc9641791998-08-04 15:26:23 +00009196#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009197/*[clinic input]
9198os.WIFSTOPPED -> bool
9199
9200 status: int
9201
9202Return True if the process returning status was stopped.
9203[clinic start generated code]*/
9204
Larry Hastings2f936352014-08-05 14:04:04 +10009205static int
9206os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009207/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009208{
9209 WAIT_TYPE wait_status;
9210 WAIT_STATUS_INT(wait_status) = status;
9211 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009212}
9213#endif /* WIFSTOPPED */
9214
Larry Hastings2f936352014-08-05 14:04:04 +10009215
Guido van Rossumc9641791998-08-04 15:26:23 +00009216#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009217/*[clinic input]
9218os.WIFSIGNALED -> bool
9219
9220 status: int
9221
9222Return True if the process returning status was terminated by a signal.
9223[clinic start generated code]*/
9224
Larry Hastings2f936352014-08-05 14:04:04 +10009225static int
9226os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009227/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009228{
9229 WAIT_TYPE wait_status;
9230 WAIT_STATUS_INT(wait_status) = status;
9231 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009232}
9233#endif /* WIFSIGNALED */
9234
Larry Hastings2f936352014-08-05 14:04:04 +10009235
Guido van Rossumc9641791998-08-04 15:26:23 +00009236#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009237/*[clinic input]
9238os.WIFEXITED -> bool
9239
9240 status: int
9241
9242Return True if the process returning status exited via the exit() system call.
9243[clinic start generated code]*/
9244
Larry Hastings2f936352014-08-05 14:04:04 +10009245static int
9246os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009247/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009248{
9249 WAIT_TYPE wait_status;
9250 WAIT_STATUS_INT(wait_status) = status;
9251 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009252}
9253#endif /* WIFEXITED */
9254
Larry Hastings2f936352014-08-05 14:04:04 +10009255
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009256#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009257/*[clinic input]
9258os.WEXITSTATUS -> int
9259
9260 status: int
9261
9262Return the process return code from status.
9263[clinic start generated code]*/
9264
Larry Hastings2f936352014-08-05 14:04:04 +10009265static int
9266os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009267/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009268{
9269 WAIT_TYPE wait_status;
9270 WAIT_STATUS_INT(wait_status) = status;
9271 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009272}
9273#endif /* WEXITSTATUS */
9274
Larry Hastings2f936352014-08-05 14:04:04 +10009275
Guido van Rossumc9641791998-08-04 15:26:23 +00009276#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009277/*[clinic input]
9278os.WTERMSIG -> int
9279
9280 status: int
9281
9282Return the signal that terminated the process that provided the status value.
9283[clinic start generated code]*/
9284
Larry Hastings2f936352014-08-05 14:04:04 +10009285static int
9286os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009287/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009288{
9289 WAIT_TYPE wait_status;
9290 WAIT_STATUS_INT(wait_status) = status;
9291 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009292}
9293#endif /* WTERMSIG */
9294
Larry Hastings2f936352014-08-05 14:04:04 +10009295
Guido van Rossumc9641791998-08-04 15:26:23 +00009296#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009297/*[clinic input]
9298os.WSTOPSIG -> int
9299
9300 status: int
9301
9302Return the signal that stopped the process that provided the status value.
9303[clinic start generated code]*/
9304
Larry Hastings2f936352014-08-05 14:04:04 +10009305static int
9306os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009307/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009308{
9309 WAIT_TYPE wait_status;
9310 WAIT_STATUS_INT(wait_status) = status;
9311 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009312}
9313#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009314#endif /* HAVE_SYS_WAIT_H */
9315
9316
Thomas Wouters477c8d52006-05-27 19:21:47 +00009317#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009318#ifdef _SCO_DS
9319/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9320 needed definitions in sys/statvfs.h */
9321#define _SVID3
9322#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009323#include <sys/statvfs.h>
9324
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009325static PyObject*
9326_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9328 if (v == NULL)
9329 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009330
9331#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9333 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9334 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9335 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9336 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9337 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9338 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9339 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9340 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9341 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009342#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9344 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9345 PyStructSequence_SET_ITEM(v, 2,
9346 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9347 PyStructSequence_SET_ITEM(v, 3,
9348 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9349 PyStructSequence_SET_ITEM(v, 4,
9350 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9351 PyStructSequence_SET_ITEM(v, 5,
9352 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9353 PyStructSequence_SET_ITEM(v, 6,
9354 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9355 PyStructSequence_SET_ITEM(v, 7,
9356 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9357 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9358 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009359#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009360 if (PyErr_Occurred()) {
9361 Py_DECREF(v);
9362 return NULL;
9363 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009364
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009366}
9367
Larry Hastings2f936352014-08-05 14:04:04 +10009368
9369/*[clinic input]
9370os.fstatvfs
9371 fd: int
9372 /
9373
9374Perform an fstatvfs system call on the given fd.
9375
9376Equivalent to statvfs(fd).
9377[clinic start generated code]*/
9378
Larry Hastings2f936352014-08-05 14:04:04 +10009379static PyObject *
9380os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009381/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009382{
9383 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009384 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009386
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009387 do {
9388 Py_BEGIN_ALLOW_THREADS
9389 result = fstatvfs(fd, &st);
9390 Py_END_ALLOW_THREADS
9391 } while (result != 0 && errno == EINTR &&
9392 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009393 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009394 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009395
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009397}
Larry Hastings2f936352014-08-05 14:04:04 +10009398#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009399
9400
Thomas Wouters477c8d52006-05-27 19:21:47 +00009401#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009402#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009403/*[clinic input]
9404os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009405
Larry Hastings2f936352014-08-05 14:04:04 +10009406 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9407
9408Perform a statvfs system call on the given path.
9409
9410path may always be specified as a string.
9411On some platforms, path may also be specified as an open file descriptor.
9412 If this functionality is unavailable, using it raises an exception.
9413[clinic start generated code]*/
9414
Larry Hastings2f936352014-08-05 14:04:04 +10009415static PyObject *
9416os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009417/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009418{
9419 int result;
9420 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009421
9422 Py_BEGIN_ALLOW_THREADS
9423#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009424 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009425#ifdef __APPLE__
9426 /* handle weak-linking on Mac OS X 10.3 */
9427 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009428 fd_specified("statvfs", path->fd);
9429 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009430 }
9431#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009432 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009433 }
9434 else
9435#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009436 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009437 Py_END_ALLOW_THREADS
9438
9439 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009440 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009441 }
9442
Larry Hastings2f936352014-08-05 14:04:04 +10009443 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009444}
Larry Hastings2f936352014-08-05 14:04:04 +10009445#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9446
Guido van Rossum94f6f721999-01-06 18:42:14 +00009447
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009448#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009449/*[clinic input]
9450os._getdiskusage
9451
9452 path: Py_UNICODE
9453
9454Return disk usage statistics about the given path as a (total, free) tuple.
9455[clinic start generated code]*/
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457static PyObject *
9458os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009459/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009460{
9461 BOOL retval;
9462 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009463
9464 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009465 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009466 Py_END_ALLOW_THREADS
9467 if (retval == 0)
9468 return PyErr_SetFromWindowsErr(0);
9469
9470 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9471}
Larry Hastings2f936352014-08-05 14:04:04 +10009472#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009473
9474
Fred Drakec9680921999-12-13 16:37:25 +00009475/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9476 * It maps strings representing configuration variable names to
9477 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009478 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009479 * rarely-used constants. There are three separate tables that use
9480 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009481 *
9482 * This code is always included, even if none of the interfaces that
9483 * need it are included. The #if hackery needed to avoid it would be
9484 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009485 */
9486struct constdef {
9487 char *name;
9488 long value;
9489};
9490
Fred Drake12c6e2d1999-12-14 21:25:03 +00009491static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009492conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009493 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009494{
Christian Heimes217cfd12007-12-02 14:31:20 +00009495 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009496 *valuep = PyLong_AS_LONG(arg);
9497 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009498 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009499 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009500 /* look up the value in the table using a binary search */
9501 size_t lo = 0;
9502 size_t mid;
9503 size_t hi = tablesize;
9504 int cmp;
9505 const char *confname;
9506 if (!PyUnicode_Check(arg)) {
9507 PyErr_SetString(PyExc_TypeError,
9508 "configuration names must be strings or integers");
9509 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009511 confname = _PyUnicode_AsString(arg);
9512 if (confname == NULL)
9513 return 0;
9514 while (lo < hi) {
9515 mid = (lo + hi) / 2;
9516 cmp = strcmp(confname, table[mid].name);
9517 if (cmp < 0)
9518 hi = mid;
9519 else if (cmp > 0)
9520 lo = mid + 1;
9521 else {
9522 *valuep = table[mid].value;
9523 return 1;
9524 }
9525 }
9526 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9527 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009529}
9530
9531
9532#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9533static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009534#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
Fred Drakec9680921999-12-13 16:37:25 +00009540#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009585#ifdef _PC_ACL_ENABLED
9586 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9587#endif
9588#ifdef _PC_MIN_HOLE_SIZE
9589 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9590#endif
9591#ifdef _PC_ALLOC_SIZE_MIN
9592 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9593#endif
9594#ifdef _PC_REC_INCR_XFER_SIZE
9595 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9596#endif
9597#ifdef _PC_REC_MAX_XFER_SIZE
9598 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9599#endif
9600#ifdef _PC_REC_MIN_XFER_SIZE
9601 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9602#endif
9603#ifdef _PC_REC_XFER_ALIGN
9604 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9605#endif
9606#ifdef _PC_SYMLINK_MAX
9607 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9608#endif
9609#ifdef _PC_XATTR_ENABLED
9610 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9611#endif
9612#ifdef _PC_XATTR_EXISTS
9613 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9614#endif
9615#ifdef _PC_TIMESTAMP_RESOLUTION
9616 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9617#endif
Fred Drakec9680921999-12-13 16:37:25 +00009618};
9619
Fred Drakec9680921999-12-13 16:37:25 +00009620static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009621conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009622{
9623 return conv_confname(arg, valuep, posix_constants_pathconf,
9624 sizeof(posix_constants_pathconf)
9625 / sizeof(struct constdef));
9626}
9627#endif
9628
Larry Hastings2f936352014-08-05 14:04:04 +10009629
Fred Drakec9680921999-12-13 16:37:25 +00009630#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009631/*[clinic input]
9632os.fpathconf -> long
9633
9634 fd: int
9635 name: path_confname
9636 /
9637
9638Return the configuration limit name for the file descriptor fd.
9639
9640If there is no limit, return -1.
9641[clinic start generated code]*/
9642
Larry Hastings2f936352014-08-05 14:04:04 +10009643static long
9644os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009645/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009646{
9647 long limit;
9648
9649 errno = 0;
9650 limit = fpathconf(fd, name);
9651 if (limit == -1 && errno != 0)
9652 posix_error();
9653
9654 return limit;
9655}
9656#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009657
9658
9659#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009660/*[clinic input]
9661os.pathconf -> long
9662 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9663 name: path_confname
9664
9665Return the configuration limit name for the file or directory path.
9666
9667If there is no limit, return -1.
9668On some platforms, path may also be specified as an open file descriptor.
9669 If this functionality is unavailable, using it raises an exception.
9670[clinic start generated code]*/
9671
Larry Hastings2f936352014-08-05 14:04:04 +10009672static long
9673os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009674/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009675{
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009677
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009679#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009680 if (path->fd != -1)
9681 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009682 else
9683#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009684 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 if (limit == -1 && errno != 0) {
9686 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009687 /* could be a path or name problem */
9688 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009689 else
Larry Hastings2f936352014-08-05 14:04:04 +10009690 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 }
Larry Hastings2f936352014-08-05 14:04:04 +10009692
9693 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009694}
Larry Hastings2f936352014-08-05 14:04:04 +10009695#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009696
9697#ifdef HAVE_CONFSTR
9698static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009699#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009701#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009702#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009704#endif
9705#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009707#endif
Fred Draked86ed291999-12-15 15:34:33 +00009708#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009710#endif
9711#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009713#endif
9714#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
9717#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009719#endif
Fred Drakec9680921999-12-13 16:37:25 +00009720#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
Fred Draked86ed291999-12-15 15:34:33 +00009744#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009746#endif
Fred Drakec9680921999-12-13 16:37:25 +00009747#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
Fred Draked86ed291999-12-15 15:34:33 +00009750#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009752#endif
9753#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009755#endif
9756#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009758#endif
9759#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
Fred Drakec9680921999-12-13 16:37:25 +00009762#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
Fred Draked86ed291999-12-15 15:34:33 +00009810#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009812#endif
9813#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009815#endif
9816#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009818#endif
9819#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009821#endif
9822#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009824#endif
9825#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009827#endif
9828#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009830#endif
9831#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
9834#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009836#endif
9837#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
9840#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009842#endif
9843#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
9846#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009848#endif
Fred Drakec9680921999-12-13 16:37:25 +00009849};
9850
9851static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009852conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009853{
9854 return conv_confname(arg, valuep, posix_constants_confstr,
9855 sizeof(posix_constants_confstr)
9856 / sizeof(struct constdef));
9857}
9858
Larry Hastings2f936352014-08-05 14:04:04 +10009859
9860/*[clinic input]
9861os.confstr
9862
9863 name: confstr_confname
9864 /
9865
9866Return a string-valued system configuration variable.
9867[clinic start generated code]*/
9868
Larry Hastings2f936352014-08-05 14:04:04 +10009869static PyObject *
9870os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009871/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009872{
9873 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009874 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009875 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009876
Victor Stinnercb043522010-09-10 23:49:04 +00009877 errno = 0;
9878 len = confstr(name, buffer, sizeof(buffer));
9879 if (len == 0) {
9880 if (errno) {
9881 posix_error();
9882 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009883 }
9884 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009885 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009886 }
9887 }
Victor Stinnercb043522010-09-10 23:49:04 +00009888
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009889 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009890 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009891 char *buf = PyMem_Malloc(len);
9892 if (buf == NULL)
9893 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009894 len2 = confstr(name, buf, len);
9895 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009896 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009897 PyMem_Free(buf);
9898 }
9899 else
9900 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009901 return result;
9902}
Larry Hastings2f936352014-08-05 14:04:04 +10009903#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009904
9905
9906#ifdef HAVE_SYSCONF
9907static struct constdef posix_constants_sysconf[] = {
9908#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
Fred Draked86ed291999-12-15 15:34:33 +00009938#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
9941#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009943#endif
Fred Drakec9680921999-12-13 16:37:25 +00009944#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
Fred Drakec9680921999-12-13 16:37:25 +00009947#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
Fred Draked86ed291999-12-15 15:34:33 +00009962#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009964#endif
Fred Drakec9680921999-12-13 16:37:25 +00009965#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
Fred Draked86ed291999-12-15 15:34:33 +00009980#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009982#endif
Fred Drakec9680921999-12-13 16:37:25 +00009983#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
Fred Draked86ed291999-12-15 15:34:33 +000010052#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
Fred Drakec9680921999-12-13 16:37:25 +000010055#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
Fred Draked86ed291999-12-15 15:34:33 +000010064#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010066#endif
Fred Drakec9680921999-12-13 16:37:25 +000010067#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
Fred Draked86ed291999-12-15 15:34:33 +000010070#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010072#endif
10073#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010075#endif
Fred Drakec9680921999-12-13 16:37:25 +000010076#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
Fred Draked86ed291999-12-15 15:34:33 +000010088#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010090#endif
Fred Drakec9680921999-12-13 16:37:25 +000010091#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
Fred Draked86ed291999-12-15 15:34:33 +000010112#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010114#endif
Fred Drakec9680921999-12-13 16:37:25 +000010115#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
Fred Draked86ed291999-12-15 15:34:33 +000010121#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010123#endif
Fred Drakec9680921999-12-13 16:37:25 +000010124#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
Fred Draked86ed291999-12-15 15:34:33 +000010151#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010153#endif
10154#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010156#endif
Fred Drakec9680921999-12-13 16:37:25 +000010157#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
Fred Draked86ed291999-12-15 15:34:33 +000010262#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010264#endif
Fred Drakec9680921999-12-13 16:37:25 +000010265#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400};
10401
10402static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010403conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010404{
10405 return conv_confname(arg, valuep, posix_constants_sysconf,
10406 sizeof(posix_constants_sysconf)
10407 / sizeof(struct constdef));
10408}
10409
Larry Hastings2f936352014-08-05 14:04:04 +100010410
10411/*[clinic input]
10412os.sysconf -> long
10413 name: sysconf_confname
10414 /
10415
10416Return an integer-valued system configuration variable.
10417[clinic start generated code]*/
10418
Larry Hastings2f936352014-08-05 14:04:04 +100010419static long
10420os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010421/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010422{
10423 long value;
10424
10425 errno = 0;
10426 value = sysconf(name);
10427 if (value == -1 && errno != 0)
10428 posix_error();
10429 return value;
10430}
10431#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010432
10433
Fred Drakebec628d1999-12-15 18:31:10 +000010434/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010435 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010436 * the exported dictionaries that are used to publish information about the
10437 * names available on the host platform.
10438 *
10439 * Sorting the table at runtime ensures that the table is properly ordered
10440 * when used, even for platforms we're not able to test on. It also makes
10441 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010442 */
Fred Drakebec628d1999-12-15 18:31:10 +000010443
10444static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010445cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010446{
10447 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010449 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010451
10452 return strcmp(c1->name, c2->name);
10453}
10454
10455static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010456setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010458{
Fred Drakebec628d1999-12-15 18:31:10 +000010459 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010460 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010461
10462 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10463 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010464 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010466
Barry Warsaw3155db32000-04-13 15:20:40 +000010467 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 PyObject *o = PyLong_FromLong(table[i].value);
10469 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10470 Py_XDECREF(o);
10471 Py_DECREF(d);
10472 return -1;
10473 }
10474 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010475 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010476 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010477}
10478
Fred Drakebec628d1999-12-15 18:31:10 +000010479/* Return -1 on failure, 0 on success. */
10480static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010481setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010482{
10483#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010484 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010485 sizeof(posix_constants_pathconf)
10486 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010487 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010488 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010489#endif
10490#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010491 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010492 sizeof(posix_constants_confstr)
10493 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010494 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010495 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010496#endif
10497#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010498 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010499 sizeof(posix_constants_sysconf)
10500 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010501 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010502 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010503#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010504 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010505}
Fred Draked86ed291999-12-15 15:34:33 +000010506
10507
Larry Hastings2f936352014-08-05 14:04:04 +100010508/*[clinic input]
10509os.abort
10510
10511Abort the interpreter immediately.
10512
10513This function 'dumps core' or otherwise fails in the hardest way possible
10514on the hosting operating system. This function never returns.
10515[clinic start generated code]*/
10516
Larry Hastings2f936352014-08-05 14:04:04 +100010517static PyObject *
10518os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010519/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010520{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010521 abort();
10522 /*NOTREACHED*/
10523 Py_FatalError("abort() called from Python code didn't abort!");
10524 return NULL;
10525}
Fred Drakebec628d1999-12-15 18:31:10 +000010526
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010527#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010528/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010529PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010530"startfile(filepath [, operation])\n\
10531\n\
10532Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010533\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010534When \"operation\" is not specified or \"open\", this acts like\n\
10535double-clicking the file in Explorer, or giving the file name as an\n\
10536argument to the DOS \"start\" command: the file is opened with whatever\n\
10537application (if any) its extension is associated.\n\
10538When another \"operation\" is given, it specifies what should be done with\n\
10539the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010540\n\
10541startfile returns as soon as the associated application is launched.\n\
10542There is no option to wait for the application to close, and no way\n\
10543to retrieve the application's exit status.\n\
10544\n\
10545The filepath is relative to the current directory. If you want to use\n\
10546an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010547the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010548
Steve Dower7d0e0c92015-01-24 08:18:24 -080010549/* Grab ShellExecute dynamically from shell32 */
10550static int has_ShellExecute = -1;
10551static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10552 LPCSTR, INT);
10553static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10554 LPCWSTR, INT);
10555static int
10556check_ShellExecute()
10557{
10558 HINSTANCE hShell32;
10559
10560 /* only recheck */
10561 if (-1 == has_ShellExecute) {
10562 Py_BEGIN_ALLOW_THREADS
10563 hShell32 = LoadLibraryW(L"SHELL32");
10564 Py_END_ALLOW_THREADS
10565 if (hShell32) {
10566 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10567 "ShellExecuteA");
10568 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10569 "ShellExecuteW");
10570 has_ShellExecute = Py_ShellExecuteA &&
10571 Py_ShellExecuteW;
10572 } else {
10573 has_ShellExecute = 0;
10574 }
10575 }
10576 return has_ShellExecute;
10577}
10578
10579
Tim Petersf58a7aa2000-09-22 10:05:54 +000010580static PyObject *
10581win32_startfile(PyObject *self, PyObject *args)
10582{
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 PyObject *ofilepath;
10584 char *filepath;
10585 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010586 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010588
Victor Stinnereb5657a2011-09-30 01:44:27 +020010589 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010590
10591 if(!check_ShellExecute()) {
10592 /* If the OS doesn't have ShellExecute, return a
10593 NotImplementedError. */
10594 return PyErr_Format(PyExc_NotImplementedError,
10595 "startfile not available on this platform");
10596 }
10597
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 if (!PyArg_ParseTuple(args, "U|s:startfile",
10599 &unipath, &operation)) {
10600 PyErr_Clear();
10601 goto normal;
10602 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010603
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010605 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010607 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 PyErr_Clear();
10609 operation = NULL;
10610 goto normal;
10611 }
10612 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010613
Victor Stinnereb5657a2011-09-30 01:44:27 +020010614 wpath = PyUnicode_AsUnicode(unipath);
10615 if (wpath == NULL)
10616 goto normal;
10617 if (uoperation) {
10618 woperation = PyUnicode_AsUnicode(uoperation);
10619 if (woperation == NULL)
10620 goto normal;
10621 }
10622 else
10623 woperation = NULL;
10624
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010626 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10627 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 Py_END_ALLOW_THREADS
10629
Victor Stinnereb5657a2011-09-30 01:44:27 +020010630 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010632 win32_error_object("startfile", unipath);
10633 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 }
10635 Py_INCREF(Py_None);
10636 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010637
10638normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10640 PyUnicode_FSConverter, &ofilepath,
10641 &operation))
10642 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010643 if (win32_warn_bytes_api()) {
10644 Py_DECREF(ofilepath);
10645 return NULL;
10646 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 filepath = PyBytes_AsString(ofilepath);
10648 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010649 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10650 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 Py_END_ALLOW_THREADS
10652 if (rc <= (HINSTANCE)32) {
10653 PyObject *errval = win32_error("startfile", filepath);
10654 Py_DECREF(ofilepath);
10655 return errval;
10656 }
10657 Py_DECREF(ofilepath);
10658 Py_INCREF(Py_None);
10659 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010660}
Larry Hastings2f936352014-08-05 14:04:04 +100010661#endif /* MS_WINDOWS */
10662
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010663
Martin v. Löwis438b5342002-12-27 10:16:42 +000010664#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010665/*[clinic input]
10666os.getloadavg
10667
10668Return average recent system load information.
10669
10670Return the number of processes in the system run queue averaged over
10671the last 1, 5, and 15 minutes as a tuple of three floats.
10672Raises OSError if the load average was unobtainable.
10673[clinic start generated code]*/
10674
Larry Hastings2f936352014-08-05 14:04:04 +100010675static PyObject *
10676os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010677/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010678{
10679 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010680 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010681 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10682 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010683 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010684 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010685}
Larry Hastings2f936352014-08-05 14:04:04 +100010686#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010687
Larry Hastings2f936352014-08-05 14:04:04 +100010688
10689/*[clinic input]
10690os.device_encoding
10691 fd: int
10692
10693Return a string describing the encoding of a terminal's file descriptor.
10694
10695The file descriptor must be attached to a terminal.
10696If the device is not a terminal, return None.
10697[clinic start generated code]*/
10698
Larry Hastings2f936352014-08-05 14:04:04 +100010699static PyObject *
10700os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010701/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010702{
Brett Cannonefb00c02012-02-29 18:31:31 -050010703 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010704}
10705
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010706
Larry Hastings2f936352014-08-05 14:04:04 +100010707#ifdef HAVE_SETRESUID
10708/*[clinic input]
10709os.setresuid
10710
10711 ruid: uid_t
10712 euid: uid_t
10713 suid: uid_t
10714 /
10715
10716Set the current process's real, effective, and saved user ids.
10717[clinic start generated code]*/
10718
Larry Hastings2f936352014-08-05 14:04:04 +100010719static PyObject *
10720os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010721/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010722{
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 if (setresuid(ruid, euid, suid) < 0)
10724 return posix_error();
10725 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010726}
Larry Hastings2f936352014-08-05 14:04:04 +100010727#endif /* HAVE_SETRESUID */
10728
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010729
10730#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010731/*[clinic input]
10732os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010733
Larry Hastings2f936352014-08-05 14:04:04 +100010734 rgid: gid_t
10735 egid: gid_t
10736 sgid: gid_t
10737 /
10738
10739Set the current process's real, effective, and saved group ids.
10740[clinic start generated code]*/
10741
Larry Hastings2f936352014-08-05 14:04:04 +100010742static PyObject *
10743os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010744/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010745{
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 if (setresgid(rgid, egid, sgid) < 0)
10747 return posix_error();
10748 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010749}
Larry Hastings2f936352014-08-05 14:04:04 +100010750#endif /* HAVE_SETRESGID */
10751
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010752
10753#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010754/*[clinic input]
10755os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010756
Larry Hastings2f936352014-08-05 14:04:04 +100010757Return a tuple of the current process's real, effective, and saved user ids.
10758[clinic start generated code]*/
10759
Larry Hastings2f936352014-08-05 14:04:04 +100010760static PyObject *
10761os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010762/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010763{
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 if (getresuid(&ruid, &euid, &suid) < 0)
10766 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010767 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10768 _PyLong_FromUid(euid),
10769 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010770}
Larry Hastings2f936352014-08-05 14:04:04 +100010771#endif /* HAVE_GETRESUID */
10772
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010773
10774#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010775/*[clinic input]
10776os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010777
Larry Hastings2f936352014-08-05 14:04:04 +100010778Return a tuple of the current process's real, effective, and saved group ids.
10779[clinic start generated code]*/
10780
Larry Hastings2f936352014-08-05 14:04:04 +100010781static PyObject *
10782os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010783/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010784{
10785 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 if (getresgid(&rgid, &egid, &sgid) < 0)
10787 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010788 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10789 _PyLong_FromGid(egid),
10790 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010791}
Larry Hastings2f936352014-08-05 14:04:04 +100010792#endif /* HAVE_GETRESGID */
10793
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010794
Benjamin Peterson9428d532011-09-14 11:45:52 -040010795#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010796/*[clinic input]
10797os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010798
Larry Hastings2f936352014-08-05 14:04:04 +100010799 path: path_t(allow_fd=True)
10800 attribute: path_t
10801 *
10802 follow_symlinks: bool = True
10803
10804Return the value of extended attribute attribute on path.
10805
10806path may be either a string or an open file descriptor.
10807If follow_symlinks is False, and the last element of the path is a symbolic
10808 link, getxattr will examine the symbolic link itself instead of the file
10809 the link points to.
10810
10811[clinic start generated code]*/
10812
Larry Hastings2f936352014-08-05 14:04:04 +100010813static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010814os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10815 int follow_symlinks)
10816/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010817{
10818 Py_ssize_t i;
10819 PyObject *buffer = NULL;
10820
10821 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10822 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 for (i = 0; ; i++) {
10825 void *ptr;
10826 ssize_t result;
10827 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10828 Py_ssize_t buffer_size = buffer_sizes[i];
10829 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010830 path_error(path);
10831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010832 }
10833 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10834 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010835 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010836 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010837
Larry Hastings9cf065c2012-06-22 16:30:09 -070010838 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010839 if (path->fd >= 0)
10840 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010842 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 else
Larry Hastings2f936352014-08-05 14:04:04 +100010844 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010845 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010846
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847 if (result < 0) {
10848 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010849 if (errno == ERANGE)
10850 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010851 path_error(path);
10852 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010854
Larry Hastings9cf065c2012-06-22 16:30:09 -070010855 if (result != buffer_size) {
10856 /* Can only shrink. */
10857 _PyBytes_Resize(&buffer, result);
10858 }
10859 break;
10860 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010861
Larry Hastings9cf065c2012-06-22 16:30:09 -070010862 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010863}
10864
Larry Hastings2f936352014-08-05 14:04:04 +100010865
10866/*[clinic input]
10867os.setxattr
10868
10869 path: path_t(allow_fd=True)
10870 attribute: path_t
10871 value: Py_buffer
10872 flags: int = 0
10873 *
10874 follow_symlinks: bool = True
10875
10876Set extended attribute attribute on path to value.
10877
10878path may be either a string or an open file descriptor.
10879If follow_symlinks is False, and the last element of the path is a symbolic
10880 link, setxattr will modify the symbolic link itself instead of the file
10881 the link points to.
10882
10883[clinic start generated code]*/
10884
Benjamin Peterson799bd802011-08-31 22:15:17 -040010885static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010886os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10887 Py_buffer *value, int flags, int follow_symlinks)
10888/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010889{
Larry Hastings2f936352014-08-05 14:04:04 +100010890 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010891
Larry Hastings2f936352014-08-05 14:04:04 +100010892 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010893 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010894
Benjamin Peterson799bd802011-08-31 22:15:17 -040010895 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010896 if (path->fd > -1)
10897 result = fsetxattr(path->fd, attribute->narrow,
10898 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010900 result = setxattr(path->narrow, attribute->narrow,
10901 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010902 else
Larry Hastings2f936352014-08-05 14:04:04 +100010903 result = lsetxattr(path->narrow, attribute->narrow,
10904 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010905 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010906
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010908 path_error(path);
10909 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010911
Larry Hastings2f936352014-08-05 14:04:04 +100010912 Py_RETURN_NONE;
10913}
10914
10915
10916/*[clinic input]
10917os.removexattr
10918
10919 path: path_t(allow_fd=True)
10920 attribute: path_t
10921 *
10922 follow_symlinks: bool = True
10923
10924Remove extended attribute attribute on path.
10925
10926path may be either a string or an open file descriptor.
10927If follow_symlinks is False, and the last element of the path is a symbolic
10928 link, removexattr will modify the symbolic link itself instead of the file
10929 the link points to.
10930
10931[clinic start generated code]*/
10932
Larry Hastings2f936352014-08-05 14:04:04 +100010933static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010934os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10935 int follow_symlinks)
10936/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010937{
10938 ssize_t result;
10939
10940 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10941 return NULL;
10942
10943 Py_BEGIN_ALLOW_THREADS;
10944 if (path->fd > -1)
10945 result = fremovexattr(path->fd, attribute->narrow);
10946 else if (follow_symlinks)
10947 result = removexattr(path->narrow, attribute->narrow);
10948 else
10949 result = lremovexattr(path->narrow, attribute->narrow);
10950 Py_END_ALLOW_THREADS;
10951
10952 if (result) {
10953 return path_error(path);
10954 }
10955
10956 Py_RETURN_NONE;
10957}
10958
10959
10960/*[clinic input]
10961os.listxattr
10962
10963 path: path_t(allow_fd=True, nullable=True) = None
10964 *
10965 follow_symlinks: bool = True
10966
10967Return a list of extended attributes on path.
10968
10969path may be either None, a string, or an open file descriptor.
10970if path is None, listxattr will examine the current directory.
10971If follow_symlinks is False, and the last element of the path is a symbolic
10972 link, listxattr will examine the symbolic link itself instead of the file
10973 the link points to.
10974[clinic start generated code]*/
10975
Larry Hastings2f936352014-08-05 14:04:04 +100010976static PyObject *
10977os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010978/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010979{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010980 Py_ssize_t i;
10981 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010982 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010983 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010984
Larry Hastings2f936352014-08-05 14:04:04 +100010985 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010987
Larry Hastings2f936352014-08-05 14:04:04 +100010988 name = path->narrow ? path->narrow : ".";
10989
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 for (i = 0; ; i++) {
10991 char *start, *trace, *end;
10992 ssize_t length;
10993 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10994 Py_ssize_t buffer_size = buffer_sizes[i];
10995 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010996 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010997 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 break;
10999 }
11000 buffer = PyMem_MALLOC(buffer_size);
11001 if (!buffer) {
11002 PyErr_NoMemory();
11003 break;
11004 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011005
Larry Hastings9cf065c2012-06-22 16:30:09 -070011006 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011007 if (path->fd > -1)
11008 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 else if (follow_symlinks)
11010 length = listxattr(name, buffer, buffer_size);
11011 else
11012 length = llistxattr(name, buffer, buffer_size);
11013 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011014
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011016 if (errno == ERANGE) {
11017 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011018 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011019 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011020 }
Larry Hastings2f936352014-08-05 14:04:04 +100011021 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011022 break;
11023 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011024
Larry Hastings9cf065c2012-06-22 16:30:09 -070011025 result = PyList_New(0);
11026 if (!result) {
11027 goto exit;
11028 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 end = buffer + length;
11031 for (trace = start = buffer; trace != end; trace++) {
11032 if (!*trace) {
11033 int error;
11034 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11035 trace - start);
11036 if (!attribute) {
11037 Py_DECREF(result);
11038 result = NULL;
11039 goto exit;
11040 }
11041 error = PyList_Append(result, attribute);
11042 Py_DECREF(attribute);
11043 if (error) {
11044 Py_DECREF(result);
11045 result = NULL;
11046 goto exit;
11047 }
11048 start = trace + 1;
11049 }
11050 }
11051 break;
11052 }
11053exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011054 if (buffer)
11055 PyMem_FREE(buffer);
11056 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011057}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011058#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011059
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011060
Larry Hastings2f936352014-08-05 14:04:04 +100011061/*[clinic input]
11062os.urandom
11063
11064 size: Py_ssize_t
11065 /
11066
11067Return a bytes object containing random bytes suitable for cryptographic use.
11068[clinic start generated code]*/
11069
Larry Hastings2f936352014-08-05 14:04:04 +100011070static PyObject *
11071os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011072/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011073{
11074 PyObject *bytes;
11075 int result;
11076
Georg Brandl2fb477c2012-02-21 00:33:36 +010011077 if (size < 0)
11078 return PyErr_Format(PyExc_ValueError,
11079 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011080 bytes = PyBytes_FromStringAndSize(NULL, size);
11081 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011082 return NULL;
11083
Larry Hastings2f936352014-08-05 14:04:04 +100011084 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11085 PyBytes_GET_SIZE(bytes));
11086 if (result == -1) {
11087 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011088 return NULL;
11089 }
Larry Hastings2f936352014-08-05 14:04:04 +100011090 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011091}
11092
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011093/* Terminal size querying */
11094
11095static PyTypeObject TerminalSizeType;
11096
11097PyDoc_STRVAR(TerminalSize_docstring,
11098 "A tuple of (columns, lines) for holding terminal window size");
11099
11100static PyStructSequence_Field TerminalSize_fields[] = {
11101 {"columns", "width of the terminal window in characters"},
11102 {"lines", "height of the terminal window in characters"},
11103 {NULL, NULL}
11104};
11105
11106static PyStructSequence_Desc TerminalSize_desc = {
11107 "os.terminal_size",
11108 TerminalSize_docstring,
11109 TerminalSize_fields,
11110 2,
11111};
11112
11113#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011114/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011115PyDoc_STRVAR(termsize__doc__,
11116 "Return the size of the terminal window as (columns, lines).\n" \
11117 "\n" \
11118 "The optional argument fd (default standard output) specifies\n" \
11119 "which file descriptor should be queried.\n" \
11120 "\n" \
11121 "If the file descriptor is not connected to a terminal, an OSError\n" \
11122 "is thrown.\n" \
11123 "\n" \
11124 "This function will only be defined if an implementation is\n" \
11125 "available for this system.\n" \
11126 "\n" \
11127 "shutil.get_terminal_size is the high-level function which should \n" \
11128 "normally be used, os.get_terminal_size is the low-level implementation.");
11129
11130static PyObject*
11131get_terminal_size(PyObject *self, PyObject *args)
11132{
11133 int columns, lines;
11134 PyObject *termsize;
11135
11136 int fd = fileno(stdout);
11137 /* Under some conditions stdout may not be connected and
11138 * fileno(stdout) may point to an invalid file descriptor. For example
11139 * GUI apps don't have valid standard streams by default.
11140 *
11141 * If this happens, and the optional fd argument is not present,
11142 * the ioctl below will fail returning EBADF. This is what we want.
11143 */
11144
11145 if (!PyArg_ParseTuple(args, "|i", &fd))
11146 return NULL;
11147
11148#ifdef TERMSIZE_USE_IOCTL
11149 {
11150 struct winsize w;
11151 if (ioctl(fd, TIOCGWINSZ, &w))
11152 return PyErr_SetFromErrno(PyExc_OSError);
11153 columns = w.ws_col;
11154 lines = w.ws_row;
11155 }
11156#endif /* TERMSIZE_USE_IOCTL */
11157
11158#ifdef TERMSIZE_USE_CONIO
11159 {
11160 DWORD nhandle;
11161 HANDLE handle;
11162 CONSOLE_SCREEN_BUFFER_INFO csbi;
11163 switch (fd) {
11164 case 0: nhandle = STD_INPUT_HANDLE;
11165 break;
11166 case 1: nhandle = STD_OUTPUT_HANDLE;
11167 break;
11168 case 2: nhandle = STD_ERROR_HANDLE;
11169 break;
11170 default:
11171 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11172 }
11173 handle = GetStdHandle(nhandle);
11174 if (handle == NULL)
11175 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11176 if (handle == INVALID_HANDLE_VALUE)
11177 return PyErr_SetFromWindowsErr(0);
11178
11179 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11180 return PyErr_SetFromWindowsErr(0);
11181
11182 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11183 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11184 }
11185#endif /* TERMSIZE_USE_CONIO */
11186
11187 termsize = PyStructSequence_New(&TerminalSizeType);
11188 if (termsize == NULL)
11189 return NULL;
11190 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11191 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11192 if (PyErr_Occurred()) {
11193 Py_DECREF(termsize);
11194 return NULL;
11195 }
11196 return termsize;
11197}
11198#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11199
Larry Hastings2f936352014-08-05 14:04:04 +100011200
11201/*[clinic input]
11202os.cpu_count
11203
11204Return the number of CPUs in the system; return None if indeterminable.
11205[clinic start generated code]*/
11206
Larry Hastings2f936352014-08-05 14:04:04 +100011207static PyObject *
11208os_cpu_count_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011209/*[clinic end generated code: output=c59ee7f6bce832b8 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011210{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011211 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011212#ifdef MS_WINDOWS
11213 SYSTEM_INFO sysinfo;
11214 GetSystemInfo(&sysinfo);
11215 ncpu = sysinfo.dwNumberOfProcessors;
11216#elif defined(__hpux)
11217 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11218#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11219 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011220#elif defined(__DragonFly__) || \
11221 defined(__OpenBSD__) || \
11222 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011223 defined(__NetBSD__) || \
11224 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011225 int mib[2];
11226 size_t len = sizeof(ncpu);
11227 mib[0] = CTL_HW;
11228 mib[1] = HW_NCPU;
11229 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11230 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011231#endif
11232 if (ncpu >= 1)
11233 return PyLong_FromLong(ncpu);
11234 else
11235 Py_RETURN_NONE;
11236}
11237
Victor Stinnerdaf45552013-08-28 00:53:59 +020011238
Larry Hastings2f936352014-08-05 14:04:04 +100011239/*[clinic input]
11240os.get_inheritable -> bool
11241
11242 fd: int
11243 /
11244
11245Get the close-on-exe flag of the specified file descriptor.
11246[clinic start generated code]*/
11247
Larry Hastings2f936352014-08-05 14:04:04 +100011248static int
11249os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011250/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011251{
Steve Dower8fc89802015-04-12 00:26:27 -040011252 int return_value;
11253 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011254 posix_error();
11255 return -1;
11256 }
11257
Steve Dower8fc89802015-04-12 00:26:27 -040011258 _Py_BEGIN_SUPPRESS_IPH
11259 return_value = _Py_get_inheritable(fd);
11260 _Py_END_SUPPRESS_IPH
11261 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011262}
11263
11264
11265/*[clinic input]
11266os.set_inheritable
11267 fd: int
11268 inheritable: int
11269 /
11270
11271Set the inheritable flag of the specified file descriptor.
11272[clinic start generated code]*/
11273
Larry Hastings2f936352014-08-05 14:04:04 +100011274static PyObject *
11275os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011276/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011277{
Steve Dower8fc89802015-04-12 00:26:27 -040011278 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011279 if (!_PyVerify_fd(fd))
11280 return posix_error();
11281
Steve Dower8fc89802015-04-12 00:26:27 -040011282 _Py_BEGIN_SUPPRESS_IPH
11283 result = _Py_set_inheritable(fd, inheritable, NULL);
11284 _Py_END_SUPPRESS_IPH
11285 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011286 return NULL;
11287 Py_RETURN_NONE;
11288}
11289
11290
11291#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011292/*[clinic input]
11293os.get_handle_inheritable -> bool
11294 handle: Py_intptr_t
11295 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011296
Larry Hastings2f936352014-08-05 14:04:04 +100011297Get the close-on-exe flag of the specified file descriptor.
11298[clinic start generated code]*/
11299
Larry Hastings2f936352014-08-05 14:04:04 +100011300static int
11301os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011302/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011303{
11304 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011305
11306 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11307 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011308 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011309 }
11310
Larry Hastings2f936352014-08-05 14:04:04 +100011311 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011312}
11313
Victor Stinnerdaf45552013-08-28 00:53:59 +020011314
Larry Hastings2f936352014-08-05 14:04:04 +100011315/*[clinic input]
11316os.set_handle_inheritable
11317 handle: Py_intptr_t
11318 inheritable: bool
11319 /
11320
11321Set the inheritable flag of the specified handle.
11322[clinic start generated code]*/
11323
Larry Hastings2f936352014-08-05 14:04:04 +100011324static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011325os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11326 int inheritable)
11327/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011328{
11329 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011330 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11331 PyErr_SetFromWindowsErr(0);
11332 return NULL;
11333 }
11334 Py_RETURN_NONE;
11335}
Larry Hastings2f936352014-08-05 14:04:04 +100011336#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011337
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011338#ifndef MS_WINDOWS
11339PyDoc_STRVAR(get_blocking__doc__,
11340 "get_blocking(fd) -> bool\n" \
11341 "\n" \
11342 "Get the blocking mode of the file descriptor:\n" \
11343 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11344
11345static PyObject*
11346posix_get_blocking(PyObject *self, PyObject *args)
11347{
11348 int fd;
11349 int blocking;
11350
11351 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11352 return NULL;
11353
11354 if (!_PyVerify_fd(fd))
11355 return posix_error();
11356
Steve Dower8fc89802015-04-12 00:26:27 -040011357 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011358 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011359 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011360 if (blocking < 0)
11361 return NULL;
11362 return PyBool_FromLong(blocking);
11363}
11364
11365PyDoc_STRVAR(set_blocking__doc__,
11366 "set_blocking(fd, blocking)\n" \
11367 "\n" \
11368 "Set the blocking mode of the specified file descriptor.\n" \
11369 "Set the O_NONBLOCK flag if blocking is False,\n" \
11370 "clear the O_NONBLOCK flag otherwise.");
11371
11372static PyObject*
11373posix_set_blocking(PyObject *self, PyObject *args)
11374{
Steve Dower8fc89802015-04-12 00:26:27 -040011375 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011376
11377 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11378 return NULL;
11379
11380 if (!_PyVerify_fd(fd))
11381 return posix_error();
11382
Steve Dower8fc89802015-04-12 00:26:27 -040011383 _Py_BEGIN_SUPPRESS_IPH
11384 result = _Py_set_blocking(fd, blocking);
11385 _Py_END_SUPPRESS_IPH
11386 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011387 return NULL;
11388 Py_RETURN_NONE;
11389}
11390#endif /* !MS_WINDOWS */
11391
11392
Victor Stinner6036e442015-03-08 01:58:04 +010011393PyDoc_STRVAR(posix_scandir__doc__,
11394"scandir(path='.') -> iterator of DirEntry objects for given path");
11395
11396static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11397
11398typedef struct {
11399 PyObject_HEAD
11400 PyObject *name;
11401 PyObject *path;
11402 PyObject *stat;
11403 PyObject *lstat;
11404#ifdef MS_WINDOWS
11405 struct _Py_stat_struct win32_lstat;
11406 __int64 win32_file_index;
11407 int got_file_index;
11408#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011409#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011410 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011411#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011412 ino_t d_ino;
11413#endif
11414} DirEntry;
11415
11416static void
11417DirEntry_dealloc(DirEntry *entry)
11418{
11419 Py_XDECREF(entry->name);
11420 Py_XDECREF(entry->path);
11421 Py_XDECREF(entry->stat);
11422 Py_XDECREF(entry->lstat);
11423 Py_TYPE(entry)->tp_free((PyObject *)entry);
11424}
11425
11426/* Forward reference */
11427static int
11428DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11429
11430/* Set exception and return -1 on error, 0 for False, 1 for True */
11431static int
11432DirEntry_is_symlink(DirEntry *self)
11433{
11434#ifdef MS_WINDOWS
11435 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011436#elif defined(HAVE_DIRENT_D_TYPE)
11437 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011438 if (self->d_type != DT_UNKNOWN)
11439 return self->d_type == DT_LNK;
11440 else
11441 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011442#else
11443 /* POSIX without d_type */
11444 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011445#endif
11446}
11447
11448static PyObject *
11449DirEntry_py_is_symlink(DirEntry *self)
11450{
11451 int result;
11452
11453 result = DirEntry_is_symlink(self);
11454 if (result == -1)
11455 return NULL;
11456 return PyBool_FromLong(result);
11457}
11458
11459static PyObject *
11460DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11461{
11462 int result;
11463 struct _Py_stat_struct st;
11464
11465#ifdef MS_WINDOWS
11466 wchar_t *path;
11467
11468 path = PyUnicode_AsUnicode(self->path);
11469 if (!path)
11470 return NULL;
11471
11472 if (follow_symlinks)
11473 result = win32_stat_w(path, &st);
11474 else
11475 result = win32_lstat_w(path, &st);
11476
11477 if (result != 0) {
11478 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11479 0, self->path);
11480 }
11481#else /* POSIX */
11482 PyObject *bytes;
11483 char *path;
11484
11485 if (!PyUnicode_FSConverter(self->path, &bytes))
11486 return NULL;
11487 path = PyBytes_AS_STRING(bytes);
11488
11489 if (follow_symlinks)
11490 result = STAT(path, &st);
11491 else
11492 result = LSTAT(path, &st);
11493 Py_DECREF(bytes);
11494
11495 if (result != 0)
11496 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11497#endif
11498
11499 return _pystat_fromstructstat(&st);
11500}
11501
11502static PyObject *
11503DirEntry_get_lstat(DirEntry *self)
11504{
11505 if (!self->lstat) {
11506#ifdef MS_WINDOWS
11507 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11508#else /* POSIX */
11509 self->lstat = DirEntry_fetch_stat(self, 0);
11510#endif
11511 }
11512 Py_XINCREF(self->lstat);
11513 return self->lstat;
11514}
11515
11516static PyObject *
11517DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11518{
11519 if (!follow_symlinks)
11520 return DirEntry_get_lstat(self);
11521
11522 if (!self->stat) {
11523 int result = DirEntry_is_symlink(self);
11524 if (result == -1)
11525 return NULL;
11526 else if (result)
11527 self->stat = DirEntry_fetch_stat(self, 1);
11528 else
11529 self->stat = DirEntry_get_lstat(self);
11530 }
11531
11532 Py_XINCREF(self->stat);
11533 return self->stat;
11534}
11535
11536static PyObject *
11537DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11538{
11539 int follow_symlinks = 1;
11540
11541 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11542 follow_symlinks_keywords, &follow_symlinks))
11543 return NULL;
11544
11545 return DirEntry_get_stat(self, follow_symlinks);
11546}
11547
11548/* Set exception and return -1 on error, 0 for False, 1 for True */
11549static int
11550DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11551{
11552 PyObject *stat = NULL;
11553 PyObject *st_mode = NULL;
11554 long mode;
11555 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011556#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011557 int is_symlink;
11558 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011559#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011560#ifdef MS_WINDOWS
11561 unsigned long dir_bits;
11562#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011563 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011564
11565#ifdef MS_WINDOWS
11566 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11567 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011568#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011569 is_symlink = self->d_type == DT_LNK;
11570 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11571#endif
11572
Victor Stinner35a97c02015-03-08 02:59:09 +010011573#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011574 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011575#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011576 stat = DirEntry_get_stat(self, follow_symlinks);
11577 if (!stat) {
11578 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11579 /* If file doesn't exist (anymore), then return False
11580 (i.e., say it's not a file/directory) */
11581 PyErr_Clear();
11582 return 0;
11583 }
11584 goto error;
11585 }
11586 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11587 if (!st_mode)
11588 goto error;
11589
11590 mode = PyLong_AsLong(st_mode);
11591 if (mode == -1 && PyErr_Occurred())
11592 goto error;
11593 Py_CLEAR(st_mode);
11594 Py_CLEAR(stat);
11595 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011596#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011597 }
11598 else if (is_symlink) {
11599 assert(mode_bits != S_IFLNK);
11600 result = 0;
11601 }
11602 else {
11603 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11604#ifdef MS_WINDOWS
11605 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11606 if (mode_bits == S_IFDIR)
11607 result = dir_bits != 0;
11608 else
11609 result = dir_bits == 0;
11610#else /* POSIX */
11611 if (mode_bits == S_IFDIR)
11612 result = self->d_type == DT_DIR;
11613 else
11614 result = self->d_type == DT_REG;
11615#endif
11616 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011617#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011618
11619 return result;
11620
11621error:
11622 Py_XDECREF(st_mode);
11623 Py_XDECREF(stat);
11624 return -1;
11625}
11626
11627static PyObject *
11628DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11629{
11630 int result;
11631
11632 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11633 if (result == -1)
11634 return NULL;
11635 return PyBool_FromLong(result);
11636}
11637
11638static PyObject *
11639DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11640{
11641 int follow_symlinks = 1;
11642
11643 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11644 follow_symlinks_keywords, &follow_symlinks))
11645 return NULL;
11646
11647 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11648}
11649
11650static PyObject *
11651DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11652{
11653 int follow_symlinks = 1;
11654
11655 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11656 follow_symlinks_keywords, &follow_symlinks))
11657 return NULL;
11658
11659 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11660}
11661
11662static PyObject *
11663DirEntry_inode(DirEntry *self)
11664{
11665#ifdef MS_WINDOWS
11666 if (!self->got_file_index) {
11667 wchar_t *path;
11668 struct _Py_stat_struct stat;
11669
11670 path = PyUnicode_AsUnicode(self->path);
11671 if (!path)
11672 return NULL;
11673
11674 if (win32_lstat_w(path, &stat) != 0) {
11675 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11676 0, self->path);
11677 }
11678
11679 self->win32_file_index = stat.st_ino;
11680 self->got_file_index = 1;
11681 }
11682 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11683#else /* POSIX */
11684#ifdef HAVE_LARGEFILE_SUPPORT
11685 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11686#else
11687 return PyLong_FromLong((long)self->d_ino);
11688#endif
11689#endif
11690}
11691
11692static PyObject *
11693DirEntry_repr(DirEntry *self)
11694{
11695 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11696}
11697
11698static PyMemberDef DirEntry_members[] = {
11699 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11700 "the entry's base filename, relative to scandir() \"path\" argument"},
11701 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11702 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11703 {NULL}
11704};
11705
11706static PyMethodDef DirEntry_methods[] = {
11707 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11708 "return True if the entry is a directory; cached per entry"
11709 },
11710 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11711 "return True if the entry is a file; cached per entry"
11712 },
11713 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11714 "return True if the entry is a symbolic link; cached per entry"
11715 },
11716 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11717 "return stat_result object for the entry; cached per entry"
11718 },
11719 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11720 "return inode of the entry; cached per entry",
11721 },
11722 {NULL}
11723};
11724
Benjamin Peterson5646de42015-04-12 17:56:34 -040011725static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011726 PyVarObject_HEAD_INIT(NULL, 0)
11727 MODNAME ".DirEntry", /* tp_name */
11728 sizeof(DirEntry), /* tp_basicsize */
11729 0, /* tp_itemsize */
11730 /* methods */
11731 (destructor)DirEntry_dealloc, /* tp_dealloc */
11732 0, /* tp_print */
11733 0, /* tp_getattr */
11734 0, /* tp_setattr */
11735 0, /* tp_compare */
11736 (reprfunc)DirEntry_repr, /* tp_repr */
11737 0, /* tp_as_number */
11738 0, /* tp_as_sequence */
11739 0, /* tp_as_mapping */
11740 0, /* tp_hash */
11741 0, /* tp_call */
11742 0, /* tp_str */
11743 0, /* tp_getattro */
11744 0, /* tp_setattro */
11745 0, /* tp_as_buffer */
11746 Py_TPFLAGS_DEFAULT, /* tp_flags */
11747 0, /* tp_doc */
11748 0, /* tp_traverse */
11749 0, /* tp_clear */
11750 0, /* tp_richcompare */
11751 0, /* tp_weaklistoffset */
11752 0, /* tp_iter */
11753 0, /* tp_iternext */
11754 DirEntry_methods, /* tp_methods */
11755 DirEntry_members, /* tp_members */
11756};
11757
11758#ifdef MS_WINDOWS
11759
11760static wchar_t *
11761join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11762{
11763 Py_ssize_t path_len;
11764 Py_ssize_t size;
11765 wchar_t *result;
11766 wchar_t ch;
11767
11768 if (!path_wide) { /* Default arg: "." */
11769 path_wide = L".";
11770 path_len = 1;
11771 }
11772 else {
11773 path_len = wcslen(path_wide);
11774 }
11775
11776 /* The +1's are for the path separator and the NUL */
11777 size = path_len + 1 + wcslen(filename) + 1;
11778 result = PyMem_New(wchar_t, size);
11779 if (!result) {
11780 PyErr_NoMemory();
11781 return NULL;
11782 }
11783 wcscpy(result, path_wide);
11784 if (path_len > 0) {
11785 ch = result[path_len - 1];
11786 if (ch != SEP && ch != ALTSEP && ch != L':')
11787 result[path_len++] = SEP;
11788 wcscpy(result + path_len, filename);
11789 }
11790 return result;
11791}
11792
11793static PyObject *
11794DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11795{
11796 DirEntry *entry;
11797 BY_HANDLE_FILE_INFORMATION file_info;
11798 ULONG reparse_tag;
11799 wchar_t *joined_path;
11800
11801 entry = PyObject_New(DirEntry, &DirEntryType);
11802 if (!entry)
11803 return NULL;
11804 entry->name = NULL;
11805 entry->path = NULL;
11806 entry->stat = NULL;
11807 entry->lstat = NULL;
11808 entry->got_file_index = 0;
11809
11810 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11811 if (!entry->name)
11812 goto error;
11813
11814 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11815 if (!joined_path)
11816 goto error;
11817
11818 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11819 PyMem_Free(joined_path);
11820 if (!entry->path)
11821 goto error;
11822
11823 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11824 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11825
11826 return (PyObject *)entry;
11827
11828error:
11829 Py_DECREF(entry);
11830 return NULL;
11831}
11832
11833#else /* POSIX */
11834
11835static char *
11836join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11837{
11838 Py_ssize_t path_len;
11839 Py_ssize_t size;
11840 char *result;
11841
11842 if (!path_narrow) { /* Default arg: "." */
11843 path_narrow = ".";
11844 path_len = 1;
11845 }
11846 else {
11847 path_len = strlen(path_narrow);
11848 }
11849
11850 if (filename_len == -1)
11851 filename_len = strlen(filename);
11852
11853 /* The +1's are for the path separator and the NUL */
11854 size = path_len + 1 + filename_len + 1;
11855 result = PyMem_New(char, size);
11856 if (!result) {
11857 PyErr_NoMemory();
11858 return NULL;
11859 }
11860 strcpy(result, path_narrow);
11861 if (path_len > 0 && result[path_len - 1] != '/')
11862 result[path_len++] = '/';
11863 strcpy(result + path_len, filename);
11864 return result;
11865}
11866
11867static PyObject *
11868DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011869 ino_t d_ino
11870#ifdef HAVE_DIRENT_D_TYPE
11871 , unsigned char d_type
11872#endif
11873 )
Victor Stinner6036e442015-03-08 01:58:04 +010011874{
11875 DirEntry *entry;
11876 char *joined_path;
11877
11878 entry = PyObject_New(DirEntry, &DirEntryType);
11879 if (!entry)
11880 return NULL;
11881 entry->name = NULL;
11882 entry->path = NULL;
11883 entry->stat = NULL;
11884 entry->lstat = NULL;
11885
11886 joined_path = join_path_filename(path->narrow, name, name_len);
11887 if (!joined_path)
11888 goto error;
11889
11890 if (!path->narrow || !PyBytes_Check(path->object)) {
11891 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11892 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11893 }
11894 else {
11895 entry->name = PyBytes_FromStringAndSize(name, name_len);
11896 entry->path = PyBytes_FromString(joined_path);
11897 }
11898 PyMem_Free(joined_path);
11899 if (!entry->name || !entry->path)
11900 goto error;
11901
Victor Stinner35a97c02015-03-08 02:59:09 +010011902#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011903 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011904#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011905 entry->d_ino = d_ino;
11906
11907 return (PyObject *)entry;
11908
11909error:
11910 Py_XDECREF(entry);
11911 return NULL;
11912}
11913
11914#endif
11915
11916
11917typedef struct {
11918 PyObject_HEAD
11919 path_t path;
11920#ifdef MS_WINDOWS
11921 HANDLE handle;
11922 WIN32_FIND_DATAW file_data;
11923 int first_time;
11924#else /* POSIX */
11925 DIR *dirp;
11926#endif
11927} ScandirIterator;
11928
11929#ifdef MS_WINDOWS
11930
11931static void
11932ScandirIterator_close(ScandirIterator *iterator)
11933{
11934 if (iterator->handle == INVALID_HANDLE_VALUE)
11935 return;
11936
11937 Py_BEGIN_ALLOW_THREADS
11938 FindClose(iterator->handle);
11939 Py_END_ALLOW_THREADS
11940 iterator->handle = INVALID_HANDLE_VALUE;
11941}
11942
11943static PyObject *
11944ScandirIterator_iternext(ScandirIterator *iterator)
11945{
11946 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11947 BOOL success;
11948
11949 /* Happens if the iterator is iterated twice */
11950 if (iterator->handle == INVALID_HANDLE_VALUE) {
11951 PyErr_SetNone(PyExc_StopIteration);
11952 return NULL;
11953 }
11954
11955 while (1) {
11956 if (!iterator->first_time) {
11957 Py_BEGIN_ALLOW_THREADS
11958 success = FindNextFileW(iterator->handle, file_data);
11959 Py_END_ALLOW_THREADS
11960 if (!success) {
11961 if (GetLastError() != ERROR_NO_MORE_FILES)
11962 return path_error(&iterator->path);
11963 /* No more files found in directory, stop iterating */
11964 break;
11965 }
11966 }
11967 iterator->first_time = 0;
11968
11969 /* Skip over . and .. */
11970 if (wcscmp(file_data->cFileName, L".") != 0 &&
11971 wcscmp(file_data->cFileName, L"..") != 0)
11972 return DirEntry_from_find_data(&iterator->path, file_data);
11973
11974 /* Loop till we get a non-dot directory or finish iterating */
11975 }
11976
11977 ScandirIterator_close(iterator);
11978
11979 PyErr_SetNone(PyExc_StopIteration);
11980 return NULL;
11981}
11982
11983#else /* POSIX */
11984
11985static void
11986ScandirIterator_close(ScandirIterator *iterator)
11987{
11988 if (!iterator->dirp)
11989 return;
11990
11991 Py_BEGIN_ALLOW_THREADS
11992 closedir(iterator->dirp);
11993 Py_END_ALLOW_THREADS
11994 iterator->dirp = NULL;
11995 return;
11996}
11997
11998static PyObject *
11999ScandirIterator_iternext(ScandirIterator *iterator)
12000{
12001 struct dirent *direntp;
12002 Py_ssize_t name_len;
12003 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010012004
12005 /* Happens if the iterator is iterated twice */
12006 if (!iterator->dirp) {
12007 PyErr_SetNone(PyExc_StopIteration);
12008 return NULL;
12009 }
12010
12011 while (1) {
12012 errno = 0;
12013 Py_BEGIN_ALLOW_THREADS
12014 direntp = readdir(iterator->dirp);
12015 Py_END_ALLOW_THREADS
12016
12017 if (!direntp) {
12018 if (errno != 0)
12019 return path_error(&iterator->path);
12020 /* No more files found in directory, stop iterating */
12021 break;
12022 }
12023
12024 /* Skip over . and .. */
12025 name_len = NAMLEN(direntp);
12026 is_dot = direntp->d_name[0] == '.' &&
12027 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12028 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010012029 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012030 name_len, direntp->d_ino
12031#ifdef HAVE_DIRENT_D_TYPE
12032 , direntp->d_type
12033#endif
12034 );
Victor Stinner6036e442015-03-08 01:58:04 +010012035 }
12036
12037 /* Loop till we get a non-dot directory or finish iterating */
12038 }
12039
12040 ScandirIterator_close(iterator);
12041
12042 PyErr_SetNone(PyExc_StopIteration);
12043 return NULL;
12044}
12045
12046#endif
12047
12048static void
12049ScandirIterator_dealloc(ScandirIterator *iterator)
12050{
12051 ScandirIterator_close(iterator);
12052 Py_XDECREF(iterator->path.object);
12053 path_cleanup(&iterator->path);
12054 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12055}
12056
Benjamin Peterson5646de42015-04-12 17:56:34 -040012057static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012058 PyVarObject_HEAD_INIT(NULL, 0)
12059 MODNAME ".ScandirIterator", /* tp_name */
12060 sizeof(ScandirIterator), /* tp_basicsize */
12061 0, /* tp_itemsize */
12062 /* methods */
12063 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12064 0, /* tp_print */
12065 0, /* tp_getattr */
12066 0, /* tp_setattr */
12067 0, /* tp_compare */
12068 0, /* tp_repr */
12069 0, /* tp_as_number */
12070 0, /* tp_as_sequence */
12071 0, /* tp_as_mapping */
12072 0, /* tp_hash */
12073 0, /* tp_call */
12074 0, /* tp_str */
12075 0, /* tp_getattro */
12076 0, /* tp_setattro */
12077 0, /* tp_as_buffer */
12078 Py_TPFLAGS_DEFAULT, /* tp_flags */
12079 0, /* tp_doc */
12080 0, /* tp_traverse */
12081 0, /* tp_clear */
12082 0, /* tp_richcompare */
12083 0, /* tp_weaklistoffset */
12084 PyObject_SelfIter, /* tp_iter */
12085 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12086};
12087
12088static PyObject *
12089posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12090{
12091 ScandirIterator *iterator;
12092 static char *keywords[] = {"path", NULL};
12093#ifdef MS_WINDOWS
12094 wchar_t *path_strW;
12095#else
12096 char *path;
12097#endif
12098
12099 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12100 if (!iterator)
12101 return NULL;
12102 memset(&iterator->path, 0, sizeof(path_t));
12103 iterator->path.function_name = "scandir";
12104 iterator->path.nullable = 1;
12105
12106#ifdef MS_WINDOWS
12107 iterator->handle = INVALID_HANDLE_VALUE;
12108#else
12109 iterator->dirp = NULL;
12110#endif
12111
12112 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12113 path_converter, &iterator->path))
12114 goto error;
12115
12116 /* path_converter doesn't keep path.object around, so do it
12117 manually for the lifetime of the iterator here (the refcount
12118 is decremented in ScandirIterator_dealloc)
12119 */
12120 Py_XINCREF(iterator->path.object);
12121
12122#ifdef MS_WINDOWS
12123 if (iterator->path.narrow) {
12124 PyErr_SetString(PyExc_TypeError,
12125 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12126 goto error;
12127 }
12128 iterator->first_time = 1;
12129
12130 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12131 if (!path_strW)
12132 goto error;
12133
12134 Py_BEGIN_ALLOW_THREADS
12135 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12136 Py_END_ALLOW_THREADS
12137
12138 PyMem_Free(path_strW);
12139
12140 if (iterator->handle == INVALID_HANDLE_VALUE) {
12141 path_error(&iterator->path);
12142 goto error;
12143 }
12144#else /* POSIX */
12145 if (iterator->path.narrow)
12146 path = iterator->path.narrow;
12147 else
12148 path = ".";
12149
12150 errno = 0;
12151 Py_BEGIN_ALLOW_THREADS
12152 iterator->dirp = opendir(path);
12153 Py_END_ALLOW_THREADS
12154
12155 if (!iterator->dirp) {
12156 path_error(&iterator->path);
12157 goto error;
12158 }
12159#endif
12160
12161 return (PyObject *)iterator;
12162
12163error:
12164 Py_DECREF(iterator);
12165 return NULL;
12166}
12167
12168
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012169#include "clinic/posixmodule.c.h"
12170
Larry Hastings7726ac92014-01-31 22:03:12 -080012171/*[clinic input]
12172dump buffer
12173[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012174/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012175
Larry Hastings31826802013-10-19 00:09:25 -070012176
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012177static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012178
12179 OS_STAT_METHODDEF
12180 OS_ACCESS_METHODDEF
12181 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012182 OS_CHDIR_METHODDEF
12183 OS_CHFLAGS_METHODDEF
12184 OS_CHMOD_METHODDEF
12185 OS_FCHMOD_METHODDEF
12186 OS_LCHMOD_METHODDEF
12187 OS_CHOWN_METHODDEF
12188 OS_FCHOWN_METHODDEF
12189 OS_LCHOWN_METHODDEF
12190 OS_LCHFLAGS_METHODDEF
12191 OS_CHROOT_METHODDEF
12192 OS_CTERMID_METHODDEF
12193 OS_GETCWD_METHODDEF
12194 OS_GETCWDB_METHODDEF
12195 OS_LINK_METHODDEF
12196 OS_LISTDIR_METHODDEF
12197 OS_LSTAT_METHODDEF
12198 OS_MKDIR_METHODDEF
12199 OS_NICE_METHODDEF
12200 OS_GETPRIORITY_METHODDEF
12201 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012202#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012203 {"readlink", (PyCFunction)posix_readlink,
12204 METH_VARARGS | METH_KEYWORDS,
12205 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012206#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012207#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012208 {"readlink", (PyCFunction)win_readlink,
12209 METH_VARARGS | METH_KEYWORDS,
12210 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012211#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012212 OS_RENAME_METHODDEF
12213 OS_REPLACE_METHODDEF
12214 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012215 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012216 OS_SYMLINK_METHODDEF
12217 OS_SYSTEM_METHODDEF
12218 OS_UMASK_METHODDEF
12219 OS_UNAME_METHODDEF
12220 OS_UNLINK_METHODDEF
12221 OS_REMOVE_METHODDEF
12222 OS_UTIME_METHODDEF
12223 OS_TIMES_METHODDEF
12224 OS__EXIT_METHODDEF
12225 OS_EXECV_METHODDEF
12226 OS_EXECVE_METHODDEF
12227 OS_SPAWNV_METHODDEF
12228 OS_SPAWNVE_METHODDEF
12229 OS_FORK1_METHODDEF
12230 OS_FORK_METHODDEF
12231 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12232 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12233 OS_SCHED_GETPARAM_METHODDEF
12234 OS_SCHED_GETSCHEDULER_METHODDEF
12235 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12236 OS_SCHED_SETPARAM_METHODDEF
12237 OS_SCHED_SETSCHEDULER_METHODDEF
12238 OS_SCHED_YIELD_METHODDEF
12239 OS_SCHED_SETAFFINITY_METHODDEF
12240 OS_SCHED_GETAFFINITY_METHODDEF
12241 OS_OPENPTY_METHODDEF
12242 OS_FORKPTY_METHODDEF
12243 OS_GETEGID_METHODDEF
12244 OS_GETEUID_METHODDEF
12245 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012246#ifdef HAVE_GETGROUPLIST
12247 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12248#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012249 OS_GETGROUPS_METHODDEF
12250 OS_GETPID_METHODDEF
12251 OS_GETPGRP_METHODDEF
12252 OS_GETPPID_METHODDEF
12253 OS_GETUID_METHODDEF
12254 OS_GETLOGIN_METHODDEF
12255 OS_KILL_METHODDEF
12256 OS_KILLPG_METHODDEF
12257 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012258#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012259 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012260#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012261 OS_SETUID_METHODDEF
12262 OS_SETEUID_METHODDEF
12263 OS_SETREUID_METHODDEF
12264 OS_SETGID_METHODDEF
12265 OS_SETEGID_METHODDEF
12266 OS_SETREGID_METHODDEF
12267 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012268#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012269 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012270#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012271 OS_GETPGID_METHODDEF
12272 OS_SETPGRP_METHODDEF
12273 OS_WAIT_METHODDEF
12274 OS_WAIT3_METHODDEF
12275 OS_WAIT4_METHODDEF
12276 OS_WAITID_METHODDEF
12277 OS_WAITPID_METHODDEF
12278 OS_GETSID_METHODDEF
12279 OS_SETSID_METHODDEF
12280 OS_SETPGID_METHODDEF
12281 OS_TCGETPGRP_METHODDEF
12282 OS_TCSETPGRP_METHODDEF
12283 OS_OPEN_METHODDEF
12284 OS_CLOSE_METHODDEF
12285 OS_CLOSERANGE_METHODDEF
12286 OS_DEVICE_ENCODING_METHODDEF
12287 OS_DUP_METHODDEF
12288 OS_DUP2_METHODDEF
12289 OS_LOCKF_METHODDEF
12290 OS_LSEEK_METHODDEF
12291 OS_READ_METHODDEF
12292 OS_READV_METHODDEF
12293 OS_PREAD_METHODDEF
12294 OS_WRITE_METHODDEF
12295 OS_WRITEV_METHODDEF
12296 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012297#ifdef HAVE_SENDFILE
12298 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12299 posix_sendfile__doc__},
12300#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012301 OS_FSTAT_METHODDEF
12302 OS_ISATTY_METHODDEF
12303 OS_PIPE_METHODDEF
12304 OS_PIPE2_METHODDEF
12305 OS_MKFIFO_METHODDEF
12306 OS_MKNOD_METHODDEF
12307 OS_MAJOR_METHODDEF
12308 OS_MINOR_METHODDEF
12309 OS_MAKEDEV_METHODDEF
12310 OS_FTRUNCATE_METHODDEF
12311 OS_TRUNCATE_METHODDEF
12312 OS_POSIX_FALLOCATE_METHODDEF
12313 OS_POSIX_FADVISE_METHODDEF
12314 OS_PUTENV_METHODDEF
12315 OS_UNSETENV_METHODDEF
12316 OS_STRERROR_METHODDEF
12317 OS_FCHDIR_METHODDEF
12318 OS_FSYNC_METHODDEF
12319 OS_SYNC_METHODDEF
12320 OS_FDATASYNC_METHODDEF
12321 OS_WCOREDUMP_METHODDEF
12322 OS_WIFCONTINUED_METHODDEF
12323 OS_WIFSTOPPED_METHODDEF
12324 OS_WIFSIGNALED_METHODDEF
12325 OS_WIFEXITED_METHODDEF
12326 OS_WEXITSTATUS_METHODDEF
12327 OS_WTERMSIG_METHODDEF
12328 OS_WSTOPSIG_METHODDEF
12329 OS_FSTATVFS_METHODDEF
12330 OS_STATVFS_METHODDEF
12331 OS_CONFSTR_METHODDEF
12332 OS_SYSCONF_METHODDEF
12333 OS_FPATHCONF_METHODDEF
12334 OS_PATHCONF_METHODDEF
12335 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012336 OS__GETFULLPATHNAME_METHODDEF
12337 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012338 OS__GETDISKUSAGE_METHODDEF
12339 OS__GETFINALPATHNAME_METHODDEF
12340 OS__GETVOLUMEPATHNAME_METHODDEF
12341 OS_GETLOADAVG_METHODDEF
12342 OS_URANDOM_METHODDEF
12343 OS_SETRESUID_METHODDEF
12344 OS_SETRESGID_METHODDEF
12345 OS_GETRESUID_METHODDEF
12346 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012347
Larry Hastings2f936352014-08-05 14:04:04 +100012348 OS_GETXATTR_METHODDEF
12349 OS_SETXATTR_METHODDEF
12350 OS_REMOVEXATTR_METHODDEF
12351 OS_LISTXATTR_METHODDEF
12352
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012353#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12354 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12355#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012356 OS_CPU_COUNT_METHODDEF
12357 OS_GET_INHERITABLE_METHODDEF
12358 OS_SET_INHERITABLE_METHODDEF
12359 OS_GET_HANDLE_INHERITABLE_METHODDEF
12360 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012361#ifndef MS_WINDOWS
12362 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12363 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12364#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012365 {"scandir", (PyCFunction)posix_scandir,
12366 METH_VARARGS | METH_KEYWORDS,
12367 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012368 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012369};
12370
12371
Brian Curtin52173d42010-12-02 18:29:18 +000012372#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012373static int
Brian Curtin52173d42010-12-02 18:29:18 +000012374enable_symlink()
12375{
12376 HANDLE tok;
12377 TOKEN_PRIVILEGES tok_priv;
12378 LUID luid;
12379 int meth_idx = 0;
12380
12381 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012382 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012383
12384 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012385 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012386
12387 tok_priv.PrivilegeCount = 1;
12388 tok_priv.Privileges[0].Luid = luid;
12389 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12390
12391 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12392 sizeof(TOKEN_PRIVILEGES),
12393 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012394 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012395
Brian Curtin3b4499c2010-12-28 14:31:47 +000012396 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12397 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012398}
12399#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12400
Barry Warsaw4a342091996-12-19 23:50:02 +000012401static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012402all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012403{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012404#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012405 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012406#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012407#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012409#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012410#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012413#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012415#endif
Fred Drakec9680921999-12-13 16:37:25 +000012416#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012418#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012419#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012421#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012422#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012424#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012427#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012428#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012430#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#endif
12434#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012436#endif
12437#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#endif
12440#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012442#endif
12443#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012445#endif
12446#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012448#endif
12449#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012450 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012451#endif
12452#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012453 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012454#endif
12455#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012456 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012457#endif
12458#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012460#endif
12461#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012462 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012463#endif
12464#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012466#endif
12467#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012469#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012470#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012472#endif
12473#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012475#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012476#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012478#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012479#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012481#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012482#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012484#endif
12485#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012487#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012488#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012490#endif
12491#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012493#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012494#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012495 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012496#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012497#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012498 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012499#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012500#ifdef O_TMPFILE
12501 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12502#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012503#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012504 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012505#endif
12506#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012507 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012508#endif
12509#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012512#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012513 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012514#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012515#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012517#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012518
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012519
Jesus Cea94363612012-06-22 18:32:07 +020012520#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012522#endif
12523#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012525#endif
12526
Tim Peters5aa91602002-01-30 05:46:57 +000012527/* MS Windows */
12528#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012531#endif
12532#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Optimize for short life (keep in memory). */
12534 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012535 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012536#endif
12537#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012538 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012540#endif
12541#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012542 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012544#endif
12545#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012548#endif
12549
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012550/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012551#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 /* Send a SIGIO signal whenever input or output
12553 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012555#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012556#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012557 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012559#endif
12560#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012561 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012563#endif
12564#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012567#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012568#ifdef O_NOLINKS
12569 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012571#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012572#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012575#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012576
Victor Stinner8c62be82010-05-06 00:08:46 +000012577 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012607#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012608#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012610#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012611#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012613#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012614#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012616#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012617#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012619#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012620#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012622#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012623#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012625#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012626#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012628#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012629
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012630 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012631#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012633#endif /* ST_RDONLY */
12634#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012636#endif /* ST_NOSUID */
12637
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012638 /* GNU extensions */
12639#ifdef ST_NODEV
12640 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12641#endif /* ST_NODEV */
12642#ifdef ST_NOEXEC
12643 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12644#endif /* ST_NOEXEC */
12645#ifdef ST_SYNCHRONOUS
12646 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12647#endif /* ST_SYNCHRONOUS */
12648#ifdef ST_MANDLOCK
12649 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12650#endif /* ST_MANDLOCK */
12651#ifdef ST_WRITE
12652 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12653#endif /* ST_WRITE */
12654#ifdef ST_APPEND
12655 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12656#endif /* ST_APPEND */
12657#ifdef ST_NOATIME
12658 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12659#endif /* ST_NOATIME */
12660#ifdef ST_NODIRATIME
12661 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12662#endif /* ST_NODIRATIME */
12663#ifdef ST_RELATIME
12664 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12665#endif /* ST_RELATIME */
12666
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012667 /* FreeBSD sendfile() constants */
12668#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012670#endif
12671#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012673#endif
12674#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012676#endif
12677
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678 /* constants for posix_fadvise */
12679#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697
12698 /* constants for waitid */
12699#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12701 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12702 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012703#endif
12704#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012706#endif
12707#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012709#endif
12710#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012712#endif
12713#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012715#endif
12716#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012718#endif
12719#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012721#endif
12722#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012724#endif
12725
12726 /* constants for lockf */
12727#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729#endif
12730#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739
Guido van Rossum246bc171999-02-01 23:54:31 +000012740#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12742 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12743 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12744 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12745 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012746#endif
12747
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012748#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12750 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12751 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012752#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012754#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012755#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012757#endif
12758#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012760#endif
12761#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012763#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012764#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012766#endif
12767#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012769#endif
12770#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012772#endif
12773#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012775#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012776#endif
12777
Benjamin Peterson9428d532011-09-14 11:45:52 -040012778#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12780 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12781 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012782#endif
12783
Victor Stinner8b905bd2011-10-25 13:34:04 +020012784#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012786#endif
12787#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012789#endif
12790#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012792#endif
12793#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012795#endif
12796#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012798#endif
12799#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012801#endif
12802#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012804#endif
12805
Victor Stinner8c62be82010-05-06 00:08:46 +000012806 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012807}
12808
12809
Martin v. Löwis1a214512008-06-11 05:26:20 +000012810static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012811 PyModuleDef_HEAD_INIT,
12812 MODNAME,
12813 posix__doc__,
12814 -1,
12815 posix_methods,
12816 NULL,
12817 NULL,
12818 NULL,
12819 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012820};
12821
12822
Larry Hastings9cf065c2012-06-22 16:30:09 -070012823static char *have_functions[] = {
12824
12825#ifdef HAVE_FACCESSAT
12826 "HAVE_FACCESSAT",
12827#endif
12828
12829#ifdef HAVE_FCHDIR
12830 "HAVE_FCHDIR",
12831#endif
12832
12833#ifdef HAVE_FCHMOD
12834 "HAVE_FCHMOD",
12835#endif
12836
12837#ifdef HAVE_FCHMODAT
12838 "HAVE_FCHMODAT",
12839#endif
12840
12841#ifdef HAVE_FCHOWN
12842 "HAVE_FCHOWN",
12843#endif
12844
Larry Hastings00964ed2013-08-12 13:49:30 -040012845#ifdef HAVE_FCHOWNAT
12846 "HAVE_FCHOWNAT",
12847#endif
12848
Larry Hastings9cf065c2012-06-22 16:30:09 -070012849#ifdef HAVE_FEXECVE
12850 "HAVE_FEXECVE",
12851#endif
12852
12853#ifdef HAVE_FDOPENDIR
12854 "HAVE_FDOPENDIR",
12855#endif
12856
Georg Brandl306336b2012-06-24 12:55:33 +020012857#ifdef HAVE_FPATHCONF
12858 "HAVE_FPATHCONF",
12859#endif
12860
Larry Hastings9cf065c2012-06-22 16:30:09 -070012861#ifdef HAVE_FSTATAT
12862 "HAVE_FSTATAT",
12863#endif
12864
12865#ifdef HAVE_FSTATVFS
12866 "HAVE_FSTATVFS",
12867#endif
12868
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012869#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012870 "HAVE_FTRUNCATE",
12871#endif
12872
Larry Hastings9cf065c2012-06-22 16:30:09 -070012873#ifdef HAVE_FUTIMENS
12874 "HAVE_FUTIMENS",
12875#endif
12876
12877#ifdef HAVE_FUTIMES
12878 "HAVE_FUTIMES",
12879#endif
12880
12881#ifdef HAVE_FUTIMESAT
12882 "HAVE_FUTIMESAT",
12883#endif
12884
12885#ifdef HAVE_LINKAT
12886 "HAVE_LINKAT",
12887#endif
12888
12889#ifdef HAVE_LCHFLAGS
12890 "HAVE_LCHFLAGS",
12891#endif
12892
12893#ifdef HAVE_LCHMOD
12894 "HAVE_LCHMOD",
12895#endif
12896
12897#ifdef HAVE_LCHOWN
12898 "HAVE_LCHOWN",
12899#endif
12900
12901#ifdef HAVE_LSTAT
12902 "HAVE_LSTAT",
12903#endif
12904
12905#ifdef HAVE_LUTIMES
12906 "HAVE_LUTIMES",
12907#endif
12908
12909#ifdef HAVE_MKDIRAT
12910 "HAVE_MKDIRAT",
12911#endif
12912
12913#ifdef HAVE_MKFIFOAT
12914 "HAVE_MKFIFOAT",
12915#endif
12916
12917#ifdef HAVE_MKNODAT
12918 "HAVE_MKNODAT",
12919#endif
12920
12921#ifdef HAVE_OPENAT
12922 "HAVE_OPENAT",
12923#endif
12924
12925#ifdef HAVE_READLINKAT
12926 "HAVE_READLINKAT",
12927#endif
12928
12929#ifdef HAVE_RENAMEAT
12930 "HAVE_RENAMEAT",
12931#endif
12932
12933#ifdef HAVE_SYMLINKAT
12934 "HAVE_SYMLINKAT",
12935#endif
12936
12937#ifdef HAVE_UNLINKAT
12938 "HAVE_UNLINKAT",
12939#endif
12940
12941#ifdef HAVE_UTIMENSAT
12942 "HAVE_UTIMENSAT",
12943#endif
12944
12945#ifdef MS_WINDOWS
12946 "MS_WINDOWS",
12947#endif
12948
12949 NULL
12950};
12951
12952
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012953PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012954INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012955{
Victor Stinner8c62be82010-05-06 00:08:46 +000012956 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012957 PyObject *list;
12958 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012959
Brian Curtin52173d42010-12-02 18:29:18 +000012960#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012961 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012962#endif
12963
Victor Stinner8c62be82010-05-06 00:08:46 +000012964 m = PyModule_Create(&posixmodule);
12965 if (m == NULL)
12966 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012967
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 /* Initialize environ dictionary */
12969 v = convertenviron();
12970 Py_XINCREF(v);
12971 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12972 return NULL;
12973 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012974
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 if (all_ins(m))
12976 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012977
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 if (setup_confname_tables(m))
12979 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012980
Victor Stinner8c62be82010-05-06 00:08:46 +000012981 Py_INCREF(PyExc_OSError);
12982 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012983
Guido van Rossumb3d39562000-01-31 18:41:26 +000012984#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012985 if (posix_putenv_garbage == NULL)
12986 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012987#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012988
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012990#if defined(HAVE_WAITID) && !defined(__APPLE__)
12991 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012992 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12993 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012994#endif
12995
Christian Heimes25827622013-10-12 01:27:08 +020012996 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12998 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12999 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013000 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13001 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 structseq_new = StatResultType.tp_new;
13003 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013004
Christian Heimes25827622013-10-12 01:27:08 +020013005 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013006 if (PyStructSequence_InitType2(&StatVFSResultType,
13007 &statvfs_result_desc) < 0)
13008 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013009#ifdef NEED_TICKS_PER_SECOND
13010# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013011 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013012# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013014# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013015 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013016# endif
13017#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013018
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013019#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013020 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013021 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13022 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013023 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013024#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013025
13026 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013027 if (PyStructSequence_InitType2(&TerminalSizeType,
13028 &TerminalSize_desc) < 0)
13029 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013030
13031 /* initialize scandir types */
13032 if (PyType_Ready(&ScandirIteratorType) < 0)
13033 return NULL;
13034 if (PyType_Ready(&DirEntryType) < 0)
13035 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013036 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013037#if defined(HAVE_WAITID) && !defined(__APPLE__)
13038 Py_INCREF((PyObject*) &WaitidResultType);
13039 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13040#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013041 Py_INCREF((PyObject*) &StatResultType);
13042 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13043 Py_INCREF((PyObject*) &StatVFSResultType);
13044 PyModule_AddObject(m, "statvfs_result",
13045 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013046
13047#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013048 Py_INCREF(&SchedParamType);
13049 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013050#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013051
Larry Hastings605a62d2012-06-24 04:33:36 -070013052 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013053 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13054 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013055 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13056
13057 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013058 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13059 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013060 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13061
Thomas Wouters477c8d52006-05-27 19:21:47 +000013062#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013063 /*
13064 * Step 2 of weak-linking support on Mac OS X.
13065 *
13066 * The code below removes functions that are not available on the
13067 * currently active platform.
13068 *
13069 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013070 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013071 * OSX 10.4.
13072 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013073#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013074 if (fstatvfs == NULL) {
13075 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13076 return NULL;
13077 }
13078 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013079#endif /* HAVE_FSTATVFS */
13080
13081#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 if (statvfs == NULL) {
13083 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13084 return NULL;
13085 }
13086 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013087#endif /* HAVE_STATVFS */
13088
13089# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013090 if (lchown == NULL) {
13091 if (PyObject_DelAttrString(m, "lchown") == -1) {
13092 return NULL;
13093 }
13094 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013095#endif /* HAVE_LCHOWN */
13096
13097
13098#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013099
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013100 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013101 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13102
Larry Hastings6fe20b32012-04-19 15:07:49 -070013103 billion = PyLong_FromLong(1000000000);
13104 if (!billion)
13105 return NULL;
13106
Larry Hastings9cf065c2012-06-22 16:30:09 -070013107 /* suppress "function not used" warnings */
13108 {
13109 int ignored;
13110 fd_specified("", -1);
13111 follow_symlinks_specified("", 1);
13112 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13113 dir_fd_converter(Py_None, &ignored);
13114 dir_fd_unavailable(Py_None, &ignored);
13115 }
13116
13117 /*
13118 * provide list of locally available functions
13119 * so os.py can populate support_* lists
13120 */
13121 list = PyList_New(0);
13122 if (!list)
13123 return NULL;
13124 for (trace = have_functions; *trace; trace++) {
13125 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13126 if (!unicode)
13127 return NULL;
13128 if (PyList_Append(list, unicode))
13129 return NULL;
13130 Py_DECREF(unicode);
13131 }
13132 PyModule_AddObject(m, "_have_functions", list);
13133
13134 initialized = 1;
13135
Victor Stinner8c62be82010-05-06 00:08:46 +000013136 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013137}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013138
13139#ifdef __cplusplus
13140}
13141#endif