blob: 7da1ab0eb8982947062bc738534a7386e71a1cfe [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040099#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200116#ifdef __hpux
117#include <sys/mpctl.h>
118#endif
119
120#if defined(__DragonFly__) || \
121 defined(__OpenBSD__) || \
122 defined(__FreeBSD__) || \
123 defined(__NetBSD__) || \
124 defined(__APPLE__)
125#include <sys/sysctl.h>
126#endif
127
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100128#if defined(MS_WINDOWS)
129# define TERMSIZE_USE_CONIO
130#elif defined(HAVE_SYS_IOCTL_H)
131# include <sys/ioctl.h>
132# if defined(HAVE_TERMIOS_H)
133# include <termios.h>
134# endif
135# if defined(TIOCGWINSZ)
136# define TERMSIZE_USE_IOCTL
137# endif
138#endif /* MS_WINDOWS */
139
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000141/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#include <process.h>
146#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000147#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000148#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000149#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_EXECV 1
152#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_SYSTEM 1
154#define HAVE_CWAIT 1
155#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000156#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000157#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158/* Unix functions that the configure script doesn't check for */
159#define HAVE_EXECV 1
160#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000162#define HAVE_FORK1 1
163#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#define HAVE_GETEGID 1
165#define HAVE_GETEUID 1
166#define HAVE_GETGID 1
167#define HAVE_GETPPID 1
168#define HAVE_GETUID 1
169#define HAVE_KILL 1
170#define HAVE_OPENDIR 1
171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000177
Victor Stinnera2f7c002012-02-08 03:36:25 +0100178
Larry Hastings61272b72014-01-07 12:41:53 -0800179/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000180# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800181module os
Larry Hastings61272b72014-01-07 12:41:53 -0800182[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000183/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000187#if defined(__sgi)&&_COMPILER_VERSION>=700
188/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
189 (default) */
190extern char *ctermid_r(char *);
191#endif
192
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000193#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#endif
203#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(char *);
205extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int chdir(const char *);
208extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000211/*#ifdef HAVE_FCHMOD
212extern int fchmod(int, mode_t);
213#endif*/
214/*#ifdef HAVE_LCHMOD
215extern int lchmod(const char *, mode_t);
216#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chown(const char *, uid_t, gid_t);
218extern char *getcwd(char *, int);
219extern char *strerror(int);
220extern int link(const char *, const char *);
221extern int rename(const char *, const char *);
222extern int stat(const char *, struct stat *);
223extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000226#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#ifdef HAVE_UTIME_H
235#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000238#ifdef HAVE_SYS_UTIME_H
239#include <sys/utime.h>
240#define HAVE_UTIME_H /* pretend we do for the rest of this file */
241#endif /* HAVE_SYS_UTIME_H */
242
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_SYS_TIMES_H
244#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
247#ifdef HAVE_SYS_PARAM_H
248#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
251#ifdef HAVE_SYS_UTSNAME_H
252#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#define NAMLEN(dirent) strlen((dirent)->d_name)
258#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000259#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#include <direct.h>
261#define NAMLEN(dirent) strlen((dirent)->d_name)
262#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000265#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#endif
269#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#endif
272#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#endif
275#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000278#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280#endif
281#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000283#endif
284#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000287#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000288#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000289#endif
290#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000291#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000292#endif
293#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000294#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100296#ifndef IO_REPARSE_TAG_MOUNT_POINT
297#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
298#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000299#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000300#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000302#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000303#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000304#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
305#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000306static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000307#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000308#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311#if defined(PATH_MAX) && PATH_MAX > 1024
312#define MAXPATHLEN PATH_MAX
313#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#endif /* MAXPATHLEN */
317
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000318#ifdef UNION_WAIT
319/* Emulate some macros on systems that have a union instead of macros */
320
321#ifndef WIFEXITED
322#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
323#endif
324
325#ifndef WEXITSTATUS
326#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
327#endif
328
329#ifndef WTERMSIG
330#define WTERMSIG(u_wait) ((u_wait).w_termsig)
331#endif
332
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333#define WAIT_TYPE union wait
334#define WAIT_STATUS_INT(s) (s.w_status)
335
336#else /* !UNION_WAIT */
337#define WAIT_TYPE int
338#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000339#endif /* UNION_WAIT */
340
Greg Wardb48bc172000-03-01 21:51:56 +0000341/* Don't use the "_r" form if we don't need it (also, won't have a
342 prototype for it, at least on Solaris -- maybe others as well?). */
343#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
344#define USE_CTERMID_R
345#endif
346
Fred Drake699f3522000-06-29 21:12:41 +0000347/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000348#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000349#undef FSTAT
350#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200351#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000352# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700353# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200354# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800355# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000356#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT fstat
360# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#endif
362
Tim Peters11b23062003-04-23 02:39:17 +0000363#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#include <sys/mkdev.h>
365#else
366#if defined(MAJOR_IN_SYSMACROS)
367#include <sys/sysmacros.h>
368#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000369#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
370#include <sys/mkdev.h>
371#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#endif
Fred Drake699f3522000-06-29 21:12:41 +0000373
Victor Stinner6edddfa2013-11-24 19:22:57 +0100374#define DWORD_MAX 4294967295U
375
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200376#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100377#define INITFUNC PyInit_nt
378#define MODNAME "nt"
379#else
380#define INITFUNC PyInit_posix
381#define MODNAME "posix"
382#endif
383
384#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200385/* defined in fileutils.c */
386PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
387PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
388 ULONG, struct _Py_stat_struct *);
389#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390
391#ifdef MS_WINDOWS
392static int
393win32_warn_bytes_api()
394{
395 return PyErr_WarnEx(PyExc_DeprecationWarning,
396 "The Windows bytes API has been deprecated, "
397 "use Unicode filenames instead",
398 1);
399}
400#endif
401
402
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200403#ifndef MS_WINDOWS
404PyObject *
405_PyLong_FromUid(uid_t uid)
406{
407 if (uid == (uid_t)-1)
408 return PyLong_FromLong(-1);
409 return PyLong_FromUnsignedLong(uid);
410}
411
412PyObject *
413_PyLong_FromGid(gid_t gid)
414{
415 if (gid == (gid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(gid);
418}
419
420int
421_Py_Uid_Converter(PyObject *obj, void *p)
422{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700423 uid_t uid;
424 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200425 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200426 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427 unsigned long uresult;
428
429 index = PyNumber_Index(obj);
430 if (index == NULL) {
431 PyErr_Format(PyExc_TypeError,
432 "uid should be integer, not %.200s",
433 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 return 0;
435 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700436
437 /*
438 * Handling uid_t is complicated for two reasons:
439 * * Although uid_t is (always?) unsigned, it still
440 * accepts -1.
441 * * We don't know its size in advance--it may be
442 * bigger than an int, or it may be smaller than
443 * a long.
444 *
445 * So a bit of defensive programming is in order.
446 * Start with interpreting the value passed
447 * in as a signed long and see if it works.
448 */
449
450 result = PyLong_AsLongAndOverflow(index, &overflow);
451
452 if (!overflow) {
453 uid = (uid_t)result;
454
455 if (result == -1) {
456 if (PyErr_Occurred())
457 goto fail;
458 /* It's a legitimate -1, we're done. */
459 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200460 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700461
462 /* Any other negative number is disallowed. */
463 if (result < 0)
464 goto underflow;
465
466 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200467 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700468 (long)uid != result)
469 goto underflow;
470 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200471 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700472
473 if (overflow < 0)
474 goto underflow;
475
476 /*
477 * Okay, the value overflowed a signed long. If it
478 * fits in an *unsigned* long, it may still be okay,
479 * as uid_t may be unsigned long on this platform.
480 */
481 uresult = PyLong_AsUnsignedLong(index);
482 if (PyErr_Occurred()) {
483 if (PyErr_ExceptionMatches(PyExc_OverflowError))
484 goto overflow;
485 goto fail;
486 }
487
488 uid = (uid_t)uresult;
489
490 /*
491 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
492 * but this value would get interpreted as (uid_t)-1 by chown
493 * and its siblings. That's not what the user meant! So we
494 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100495 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700496 */
497 if (uid == (uid_t)-1)
498 goto overflow;
499
500 /* Ensure the value wasn't truncated. */
501 if (sizeof(uid_t) < sizeof(long) &&
502 (unsigned long)uid != uresult)
503 goto overflow;
504 /* fallthrough */
505
506success:
507 Py_DECREF(index);
508 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200509 return 1;
510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is less than minimum");
514 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200515
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700516overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518 "uid is greater than maximum");
519 /* fallthrough */
520
521fail:
522 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523 return 0;
524}
525
526int
527_Py_Gid_Converter(PyObject *obj, void *p)
528{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529 gid_t gid;
530 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200532 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533 unsigned long uresult;
534
535 index = PyNumber_Index(obj);
536 if (index == NULL) {
537 PyErr_Format(PyExc_TypeError,
538 "gid should be integer, not %.200s",
539 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 return 0;
541 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542
543 /*
544 * Handling gid_t is complicated for two reasons:
545 * * Although gid_t is (always?) unsigned, it still
546 * accepts -1.
547 * * We don't know its size in advance--it may be
548 * bigger than an int, or it may be smaller than
549 * a long.
550 *
551 * So a bit of defensive programming is in order.
552 * Start with interpreting the value passed
553 * in as a signed long and see if it works.
554 */
555
556 result = PyLong_AsLongAndOverflow(index, &overflow);
557
558 if (!overflow) {
559 gid = (gid_t)result;
560
561 if (result == -1) {
562 if (PyErr_Occurred())
563 goto fail;
564 /* It's a legitimate -1, we're done. */
565 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567
568 /* Any other negative number is disallowed. */
569 if (result < 0) {
570 goto underflow;
571 }
572
573 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575 (long)gid != result)
576 goto underflow;
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 if (overflow < 0)
581 goto underflow;
582
583 /*
584 * Okay, the value overflowed a signed long. If it
585 * fits in an *unsigned* long, it may still be okay,
586 * as gid_t may be unsigned long on this platform.
587 */
588 uresult = PyLong_AsUnsignedLong(index);
589 if (PyErr_Occurred()) {
590 if (PyErr_ExceptionMatches(PyExc_OverflowError))
591 goto overflow;
592 goto fail;
593 }
594
595 gid = (gid_t)uresult;
596
597 /*
598 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
599 * but this value would get interpreted as (gid_t)-1 by chown
600 * and its siblings. That's not what the user meant! So we
601 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100602 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 */
604 if (gid == (gid_t)-1)
605 goto overflow;
606
607 /* Ensure the value wasn't truncated. */
608 if (sizeof(gid_t) < sizeof(long) &&
609 (unsigned long)gid != uresult)
610 goto overflow;
611 /* fallthrough */
612
613success:
614 Py_DECREF(index);
615 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 return 1;
617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is less than minimum");
621 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625 "gid is greater than maximum");
626 /* fallthrough */
627
628fail:
629 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 return 0;
631}
632#endif /* MS_WINDOWS */
633
634
Gregory P. Smith702dada2015-01-28 16:07:52 -0800635#ifdef HAVE_LONG_LONG
636# define _PyLong_FromDev PyLong_FromLongLong
637#else
638# define _PyLong_FromDev PyLong_FromLong
639#endif
640
641
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200642#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
643static int
644_Py_Dev_Converter(PyObject *obj, void *p)
645{
646#ifdef HAVE_LONG_LONG
647 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
648#else
649 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
650#endif
651 if (PyErr_Occurred())
652 return 0;
653 return 1;
654}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800655#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200656
657
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400659/*
660 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
661 * without the int cast, the value gets interpreted as uint (4291925331),
662 * which doesn't play nicely with all the initializer lines in this file that
663 * look like this:
664 * int dir_fd = DEFAULT_DIR_FD;
665 */
666#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#else
668#define DEFAULT_DIR_FD (-100)
669#endif
670
671static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200672_fd_converter(PyObject *o, int *p, const char *allowed)
673{
674 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 long long_value;
676
677 PyObject *index = PyNumber_Index(o);
678 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200679 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "argument should be %s, not %.200s",
681 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682 return 0;
683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 long_value = PyLong_AsLongAndOverflow(index, &overflow);
686 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200687 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 return 0;
691 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200692 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700693 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700694 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 return 0;
696 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 *p = (int)long_value;
699 return 1;
700}
701
702static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200703dir_fd_converter(PyObject *o, void *p)
704{
705 if (o == Py_None) {
706 *(int *)p = DEFAULT_DIR_FD;
707 return 1;
708 }
709 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700710}
711
712
Larry Hastings9cf065c2012-06-22 16:30:09 -0700713/*
714 * A PyArg_ParseTuple "converter" function
715 * that handles filesystem paths in the manner
716 * preferred by the os module.
717 *
718 * path_converter accepts (Unicode) strings and their
719 * subclasses, and bytes and their subclasses. What
720 * it does with the argument depends on the platform:
721 *
722 * * On Windows, if we get a (Unicode) string we
723 * extract the wchar_t * and return it; if we get
724 * bytes we extract the char * and return that.
725 *
726 * * On all other platforms, strings are encoded
727 * to bytes using PyUnicode_FSConverter, then we
728 * extract the char * from the bytes object and
729 * return that.
730 *
731 * path_converter also optionally accepts signed
732 * integers (representing open file descriptors) instead
733 * of path strings.
734 *
735 * Input fields:
736 * path.nullable
737 * If nonzero, the path is permitted to be None.
738 * path.allow_fd
739 * If nonzero, the path is permitted to be a file handle
740 * (a signed int) instead of a string.
741 * path.function_name
742 * If non-NULL, path_converter will use that as the name
743 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700744 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700745 * path.argument_name
746 * If non-NULL, path_converter will use that as the name
747 * of the parameter in error messages.
748 * (If path.argument_name is NULL it uses "path".)
749 *
750 * Output fields:
751 * path.wide
752 * Points to the path if it was expressed as Unicode
753 * and was not encoded. (Only used on Windows.)
754 * path.narrow
755 * Points to the path if it was expressed as bytes,
756 * or it was Unicode and was encoded to bytes.
757 * path.fd
758 * Contains a file descriptor if path.accept_fd was true
759 * and the caller provided a signed integer instead of any
760 * sort of string.
761 *
762 * WARNING: if your "path" parameter is optional, and is
763 * unspecified, path_converter will never get called.
764 * So if you set allow_fd, you *MUST* initialize path.fd = -1
765 * yourself!
766 * path.length
767 * The length of the path in characters, if specified as
768 * a string.
769 * path.object
770 * The original object passed in.
771 * path.cleanup
772 * For internal use only. May point to a temporary object.
773 * (Pay no attention to the man behind the curtain.)
774 *
775 * At most one of path.wide or path.narrow will be non-NULL.
776 * If path was None and path.nullable was set,
777 * or if path was an integer and path.allow_fd was set,
778 * both path.wide and path.narrow will be NULL
779 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200780 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 * path_converter takes care to not write to the path_t
782 * unless it's successful. However it must reset the
783 * "cleanup" field each time it's called.
784 *
785 * Use as follows:
786 * path_t path;
787 * memset(&path, 0, sizeof(path));
788 * PyArg_ParseTuple(args, "O&", path_converter, &path);
789 * // ... use values from path ...
790 * path_cleanup(&path);
791 *
792 * (Note that if PyArg_Parse fails you don't need to call
793 * path_cleanup(). However it is safe to do so.)
794 */
795typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100796 const char *function_name;
797 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798 int nullable;
799 int allow_fd;
800 wchar_t *wide;
801 char *narrow;
802 int fd;
803 Py_ssize_t length;
804 PyObject *object;
805 PyObject *cleanup;
806} path_t;
807
Larry Hastings2f936352014-08-05 14:04:04 +1000808#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
809 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700810
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811static void
812path_cleanup(path_t *path) {
813 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200814 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815 }
816}
817
818static int
819path_converter(PyObject *o, void *p) {
820 path_t *path = (path_t *)p;
821 PyObject *unicode, *bytes;
822 Py_ssize_t length;
823 char *narrow;
824
825#define FORMAT_EXCEPTION(exc, fmt) \
826 PyErr_Format(exc, "%s%s" fmt, \
827 path->function_name ? path->function_name : "", \
828 path->function_name ? ": " : "", \
829 path->argument_name ? path->argument_name : "path")
830
831 /* Py_CLEANUP_SUPPORTED support */
832 if (o == NULL) {
833 path_cleanup(path);
834 return 1;
835 }
836
837 /* ensure it's always safe to call path_cleanup() */
838 path->cleanup = NULL;
839
840 if (o == Py_None) {
841 if (!path->nullable) {
842 FORMAT_EXCEPTION(PyExc_TypeError,
843 "can't specify None for %s argument");
844 return 0;
845 }
846 path->wide = NULL;
847 path->narrow = NULL;
848 path->length = 0;
849 path->object = o;
850 path->fd = -1;
851 return 1;
852 }
853
854 unicode = PyUnicode_FromObject(o);
855 if (unicode) {
856#ifdef MS_WINDOWS
857 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100858
859 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
860 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861 Py_DECREF(unicode);
862 return 0;
863 }
Victor Stinner59799a82013-11-13 14:17:30 +0100864 if (length > 32767) {
865 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 Py_DECREF(unicode);
867 return 0;
868 }
869
870 path->wide = wide;
871 path->narrow = NULL;
872 path->length = length;
873 path->object = o;
874 path->fd = -1;
875 path->cleanup = unicode;
876 return Py_CLEANUP_SUPPORTED;
877#else
878 int converted = PyUnicode_FSConverter(unicode, &bytes);
879 Py_DECREF(unicode);
880 if (!converted)
881 bytes = NULL;
882#endif
883 }
884 else {
885 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200886 if (PyObject_CheckBuffer(o))
887 bytes = PyBytes_FromObject(o);
888 else
889 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700890 if (!bytes) {
891 PyErr_Clear();
892 if (path->allow_fd) {
893 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200894 int result = _fd_converter(o, &fd,
895 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700896 if (result) {
897 path->wide = NULL;
898 path->narrow = NULL;
899 path->length = 0;
900 path->object = o;
901 path->fd = fd;
902 return result;
903 }
904 }
905 }
906 }
907
908 if (!bytes) {
909 if (!PyErr_Occurred())
910 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
911 return 0;
912 }
913
914#ifdef MS_WINDOWS
915 if (win32_warn_bytes_api()) {
916 Py_DECREF(bytes);
917 return 0;
918 }
919#endif
920
921 length = PyBytes_GET_SIZE(bytes);
922#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100923 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
925 Py_DECREF(bytes);
926 return 0;
927 }
928#endif
929
930 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200931 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300932 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 Py_DECREF(bytes);
934 return 0;
935 }
936
937 path->wide = NULL;
938 path->narrow = narrow;
939 path->length = length;
940 path->object = o;
941 path->fd = -1;
942 path->cleanup = bytes;
943 return Py_CLEANUP_SUPPORTED;
944}
945
946static void
947argument_unavailable_error(char *function_name, char *argument_name) {
948 PyErr_Format(PyExc_NotImplementedError,
949 "%s%s%s unavailable on this platform",
950 (function_name != NULL) ? function_name : "",
951 (function_name != NULL) ? ": ": "",
952 argument_name);
953}
954
955static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200956dir_fd_unavailable(PyObject *o, void *p)
957{
958 int dir_fd;
959 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200961 if (dir_fd != DEFAULT_DIR_FD) {
962 argument_unavailable_error(NULL, "dir_fd");
963 return 0;
964 }
965 *(int *)p = dir_fd;
966 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967}
968
969static int
970fd_specified(char *function_name, int fd) {
971 if (fd == -1)
972 return 0;
973
974 argument_unavailable_error(function_name, "fd");
975 return 1;
976}
977
978static int
979follow_symlinks_specified(char *function_name, int follow_symlinks) {
980 if (follow_symlinks)
981 return 0;
982
983 argument_unavailable_error(function_name, "follow_symlinks");
984 return 1;
985}
986
987static int
988path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
989 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
990 PyErr_Format(PyExc_ValueError,
991 "%s: can't specify dir_fd without matching path",
992 function_name);
993 return 1;
994 }
995 return 0;
996}
997
998static int
999dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1000 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1001 PyErr_Format(PyExc_ValueError,
1002 "%s: can't specify both dir_fd and fd",
1003 function_name);
1004 return 1;
1005 }
1006 return 0;
1007}
1008
1009static int
1010fd_and_follow_symlinks_invalid(char *function_name, int fd,
1011 int follow_symlinks) {
1012 if ((fd > 0) && (!follow_symlinks)) {
1013 PyErr_Format(PyExc_ValueError,
1014 "%s: cannot use fd and follow_symlinks together",
1015 function_name);
1016 return 1;
1017 }
1018 return 0;
1019}
1020
1021static int
1022dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1023 int follow_symlinks) {
1024 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1025 PyErr_Format(PyExc_ValueError,
1026 "%s: cannot use dir_fd and follow_symlinks together",
1027 function_name);
1028 return 1;
1029 }
1030 return 0;
1031}
1032
Larry Hastings2f936352014-08-05 14:04:04 +10001033#ifdef MS_WINDOWS
1034 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001035#else
Larry Hastings2f936352014-08-05 14:04:04 +10001036 typedef off_t Py_off_t;
1037#endif
1038
1039static int
1040Py_off_t_converter(PyObject *arg, void *addr)
1041{
1042#ifdef HAVE_LARGEFILE_SUPPORT
1043 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1044#else
1045 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001046#endif
1047 if (PyErr_Occurred())
1048 return 0;
1049 return 1;
1050}
Larry Hastings2f936352014-08-05 14:04:04 +10001051
1052static PyObject *
1053PyLong_FromPy_off_t(Py_off_t offset)
1054{
1055#ifdef HAVE_LARGEFILE_SUPPORT
1056 return PyLong_FromLongLong(offset);
1057#else
1058 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001059#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001060}
1061
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001062
Steve Dowerd81431f2015-03-06 14:47:02 -08001063#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1064/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1065 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001066 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001067#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001069#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001070#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001071#define _NO_CONSOLE_FILENO (intptr_t)-2
1072
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073/* the special case of checking dup2. The target fd must be in a sensible range */
1074static int
1075_PyVerify_fd_dup2(int fd1, int fd2)
1076{
Victor Stinner8c62be82010-05-06 00:08:46 +00001077 if (!_PyVerify_fd(fd1))
1078 return 0;
1079 if (fd2 == _NO_CONSOLE_FILENO)
1080 return 0;
1081 if ((unsigned)fd2 < _NHANDLE_)
1082 return 1;
1083 else
1084 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001085}
1086#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001087#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001088#endif
1089
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001090#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001091
1092static int
Brian Curtind25aef52011-06-13 15:16:04 -05001093win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001094{
1095 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1096 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1097 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001098
1099 if (0 == DeviceIoControl(
1100 reparse_point_handle,
1101 FSCTL_GET_REPARSE_POINT,
1102 NULL, 0, /* in buffer */
1103 target_buffer, sizeof(target_buffer),
1104 &n_bytes_returned,
1105 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001106 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001107
1108 if (reparse_tag)
1109 *reparse_tag = rdb->ReparseTag;
1110
Brian Curtind25aef52011-06-13 15:16:04 -05001111 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001113
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001114#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001115
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001117#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001118/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001119** environ directly, we must obtain it with _NSGetEnviron(). See also
1120** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001121*/
1122#include <crt_externs.h>
1123static char **environ;
1124#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001125extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001126#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001127
Barry Warsaw53699e91996-12-10 23:23:01 +00001128static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001129convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130{
Victor Stinner8c62be82010-05-06 00:08:46 +00001131 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001132#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001133 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001134#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001135 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001136#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001137
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 d = PyDict_New();
1139 if (d == NULL)
1140 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001141#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001142 if (environ == NULL)
1143 environ = *_NSGetEnviron();
1144#endif
1145#ifdef MS_WINDOWS
1146 /* _wenviron must be initialized in this way if the program is started
1147 through main() instead of wmain(). */
1148 _wgetenv(L"");
1149 if (_wenviron == NULL)
1150 return d;
1151 /* This part ignores errors */
1152 for (e = _wenviron; *e != NULL; e++) {
1153 PyObject *k;
1154 PyObject *v;
1155 wchar_t *p = wcschr(*e, L'=');
1156 if (p == NULL)
1157 continue;
1158 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1159 if (k == NULL) {
1160 PyErr_Clear();
1161 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001162 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001163 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1164 if (v == NULL) {
1165 PyErr_Clear();
1166 Py_DECREF(k);
1167 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001168 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001169 if (PyDict_GetItem(d, k) == NULL) {
1170 if (PyDict_SetItem(d, k, v) != 0)
1171 PyErr_Clear();
1172 }
1173 Py_DECREF(k);
1174 Py_DECREF(v);
1175 }
1176#else
1177 if (environ == NULL)
1178 return d;
1179 /* This part ignores errors */
1180 for (e = environ; *e != NULL; e++) {
1181 PyObject *k;
1182 PyObject *v;
1183 char *p = strchr(*e, '=');
1184 if (p == NULL)
1185 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001186 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001187 if (k == NULL) {
1188 PyErr_Clear();
1189 continue;
1190 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001191 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 if (v == NULL) {
1193 PyErr_Clear();
1194 Py_DECREF(k);
1195 continue;
1196 }
1197 if (PyDict_GetItem(d, k) == NULL) {
1198 if (PyDict_SetItem(d, k, v) != 0)
1199 PyErr_Clear();
1200 }
1201 Py_DECREF(k);
1202 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001203 }
1204#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001205 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206}
1207
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208/* Set a POSIX-specific error from errno, and return NULL */
1209
Barry Warsawd58d7641998-07-23 16:14:40 +00001210static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001211posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001212{
Victor Stinner8c62be82010-05-06 00:08:46 +00001213 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214}
Mark Hammondef8b6542001-05-13 08:04:26 +00001215
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001216#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001217static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001218win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 /* XXX We should pass the function name along in the future.
1221 (winreg.c also wants to pass the function name.)
1222 This would however require an additional param to the
1223 Windows error object, which is non-trivial.
1224 */
1225 errno = GetLastError();
1226 if (filename)
1227 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1228 else
1229 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001230}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001231
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001232static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001233win32_error_object(char* function, PyObject* filename)
1234{
1235 /* XXX - see win32_error for comments on 'function' */
1236 errno = GetLastError();
1237 if (filename)
1238 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001239 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001240 errno,
1241 filename);
1242 else
1243 return PyErr_SetFromWindowsErr(errno);
1244}
1245
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001246#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247
Larry Hastings9cf065c2012-06-22 16:30:09 -07001248static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001249path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001250{
1251#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001252 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1253 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001254#else
Victor Stinner292c8352012-10-30 02:17:38 +01001255 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001256#endif
1257}
1258
Larry Hastings31826802013-10-19 00:09:25 -07001259
Larry Hastingsb0827312014-02-09 22:05:19 -08001260static PyObject *
1261path_error2(path_t *path, path_t *path2)
1262{
1263#ifdef MS_WINDOWS
1264 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1265 0, path->object, path2->object);
1266#else
1267 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1268 path->object, path2->object);
1269#endif
1270}
1271
1272
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273/* POSIX generic methods */
1274
Larry Hastings2f936352014-08-05 14:04:04 +10001275static int
1276fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001277{
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001279 int *pointer = (int *)p;
1280 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001282 return 0;
1283 if (!_PyVerify_fd(fd)) {
1284 posix_error();
1285 return 0;
1286 }
1287 *pointer = fd;
1288 return 1;
1289}
1290
1291static PyObject *
1292posix_fildes_fd(int fd, int (*func)(int))
1293{
1294 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001295 int async_err = 0;
1296
1297 do {
1298 Py_BEGIN_ALLOW_THREADS
1299 res = (*func)(fd);
1300 Py_END_ALLOW_THREADS
1301 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1302 if (res != 0)
1303 return (!async_err) ? posix_error() : NULL;
1304 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001305}
Guido van Rossum21142a01999-01-08 21:05:37 +00001306
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001308#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner75875072013-11-24 19:23:25 +01001317 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001323 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001327 than MAX_PATH-1 (not including the final null character). */
1328 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner75875072013-11-24 19:23:25 +01001342 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001348 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 if (!result)
1350 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001351 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001352 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001359 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001370 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001383#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001384
Guido van Rossumd8faa362007-04-27 19:54:29 +00001385static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001386attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001387{
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 HANDLE hFindFile;
1389 WIN32_FIND_DATAA FileData;
1390 hFindFile = FindFirstFileA(pszFile, &FileData);
1391 if (hFindFile == INVALID_HANDLE_VALUE)
1392 return FALSE;
1393 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001395 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001396 info->dwFileAttributes = FileData.dwFileAttributes;
1397 info->ftCreationTime = FileData.ftCreationTime;
1398 info->ftLastAccessTime = FileData.ftLastAccessTime;
1399 info->ftLastWriteTime = FileData.ftLastWriteTime;
1400 info->nFileSizeHigh = FileData.nFileSizeHigh;
1401 info->nFileSizeLow = FileData.nFileSizeLow;
1402/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1404 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001405 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001406}
1407
Victor Stinner6036e442015-03-08 01:58:04 +01001408static void
1409find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1410 BY_HANDLE_FILE_INFORMATION *info,
1411 ULONG *reparse_tag)
1412{
1413 memset(info, 0, sizeof(*info));
1414 info->dwFileAttributes = pFileData->dwFileAttributes;
1415 info->ftCreationTime = pFileData->ftCreationTime;
1416 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1417 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1418 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1419 info->nFileSizeLow = pFileData->nFileSizeLow;
1420/* info->nNumberOfLinks = 1; */
1421 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1422 *reparse_tag = pFileData->dwReserved0;
1423 else
1424 *reparse_tag = 0;
1425}
1426
Guido van Rossumd8faa362007-04-27 19:54:29 +00001427static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 HANDLE hFindFile;
1431 WIN32_FIND_DATAW FileData;
1432 hFindFile = FindFirstFileW(pszFile, &FileData);
1433 if (hFindFile == INVALID_HANDLE_VALUE)
1434 return FALSE;
1435 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001436 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001438}
1439
Brian Curtind25aef52011-06-13 15:16:04 -05001440static BOOL
1441get_target_path(HANDLE hdl, wchar_t **target_path)
1442{
1443 int buf_size, result_length;
1444 wchar_t *buf;
1445
1446 /* We have a good handle to the target, use it to determine
1447 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001448 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1449 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001450 if(!buf_size)
1451 return FALSE;
1452
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001453 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001454 if (!buf) {
1455 SetLastError(ERROR_OUTOFMEMORY);
1456 return FALSE;
1457 }
1458
Steve Dower2ea51c92015-03-20 21:49:12 -07001459 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001460 buf, buf_size, VOLUME_NAME_DOS);
1461
1462 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001463 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001464 return FALSE;
1465 }
1466
1467 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001468 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001469 return FALSE;
1470 }
1471
1472 buf[result_length] = 0;
1473
1474 *target_path = buf;
1475 return TRUE;
1476}
1477
1478static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001479win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001480 BOOL traverse);
1481static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001482win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001483 BOOL traverse)
1484{
Victor Stinner26de69d2011-06-17 15:15:38 +02001485 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001486 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001487 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001488 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001489 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001490 const char *dot;
1491
1492 hFile = CreateFileA(
1493 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001494 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001495 0, /* share mode */
1496 NULL, /* security attributes */
1497 OPEN_EXISTING,
1498 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001499 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1500 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001501 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001502 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1503 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001504 NULL);
1505
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001507 /* Either the target doesn't exist, or we don't have access to
1508 get a handle to it. If the former, we need to return an error.
1509 If the latter, we can use attributes_from_dir. */
1510 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001511 return -1;
1512 /* Could not get attributes on open file. Fall back to
1513 reading the directory. */
1514 if (!attributes_from_dir(path, &info, &reparse_tag))
1515 /* Very strange. This should not fail now */
1516 return -1;
1517 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1518 if (traverse) {
1519 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001520 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001523 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001524 } else {
1525 if (!GetFileInformationByHandle(hFile, &info)) {
1526 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001527 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528 }
1529 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001530 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1531 return -1;
1532
1533 /* Close the outer open file handle now that we're about to
1534 reopen it with different flags. */
1535 if (!CloseHandle(hFile))
1536 return -1;
1537
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001538 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001539 /* In order to call GetFinalPathNameByHandle we need to open
1540 the file without the reparse handling flag set. */
1541 hFile2 = CreateFileA(
1542 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1543 NULL, OPEN_EXISTING,
1544 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1545 NULL);
1546 if (hFile2 == INVALID_HANDLE_VALUE)
1547 return -1;
1548
1549 if (!get_target_path(hFile2, &target_path))
1550 return -1;
1551
1552 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001553 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001554 return code;
1555 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001556 } else
1557 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001559 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560
1561 /* Set S_IEXEC if it is an .exe, .bat, ... */
1562 dot = strrchr(path, '.');
1563 if (dot) {
1564 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1565 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1566 result->st_mode |= 0111;
1567 }
1568 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001569}
1570
1571static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001572win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001573 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574{
1575 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001576 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001577 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001578 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001579 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580 const wchar_t *dot;
1581
1582 hFile = CreateFileW(
1583 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001584 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001585 0, /* share mode */
1586 NULL, /* security attributes */
1587 OPEN_EXISTING,
1588 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001589 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1590 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001591 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001592 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001593 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 NULL);
1595
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001596 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 /* Either the target doesn't exist, or we don't have access to
1598 get a handle to it. If the former, we need to return an error.
1599 If the latter, we can use attributes_from_dir. */
1600 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001601 return -1;
1602 /* Could not get attributes on open file. Fall back to
1603 reading the directory. */
1604 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1605 /* Very strange. This should not fail now */
1606 return -1;
1607 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1608 if (traverse) {
1609 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001610 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001611 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001612 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001613 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001614 } else {
1615 if (!GetFileInformationByHandle(hFile, &info)) {
1616 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001617 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001618 }
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001620 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1621 return -1;
1622
1623 /* Close the outer open file handle now that we're about to
1624 reopen it with different flags. */
1625 if (!CloseHandle(hFile))
1626 return -1;
1627
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001628 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001629 /* In order to call GetFinalPathNameByHandle we need to open
1630 the file without the reparse handling flag set. */
1631 hFile2 = CreateFileW(
1632 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1633 NULL, OPEN_EXISTING,
1634 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1635 NULL);
1636 if (hFile2 == INVALID_HANDLE_VALUE)
1637 return -1;
1638
1639 if (!get_target_path(hFile2, &target_path))
1640 return -1;
1641
1642 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001643 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001644 return code;
1645 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001646 } else
1647 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001649 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001650
1651 /* Set S_IEXEC if it is an .exe, .bat, ... */
1652 dot = wcsrchr(path, '.');
1653 if (dot) {
1654 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1655 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1656 result->st_mode |= 0111;
1657 }
1658 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659}
1660
1661static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001662win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001664 /* Protocol violation: we explicitly clear errno, instead of
1665 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001666 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 errno = 0;
1668 return code;
1669}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001671static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001672win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673{
1674 /* Protocol violation: we explicitly clear errno, instead of
1675 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001676 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677 errno = 0;
1678 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679}
Brian Curtind25aef52011-06-13 15:16:04 -05001680/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001681
1682 In Posix, stat automatically traverses symlinks and returns the stat
1683 structure for the target. In Windows, the equivalent GetFileAttributes by
1684 default does not traverse symlinks and instead returns attributes for
1685 the symlink.
1686
1687 Therefore, win32_lstat will get the attributes traditionally, and
1688 win32_stat will first explicitly resolve the symlink target and then will
1689 call win32_lstat on that result.
1690
Ezio Melotti4969f702011-03-15 05:59:46 +02001691 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001692
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001693static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001694win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001695{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001697}
1698
Victor Stinner8c62be82010-05-06 00:08:46 +00001699static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001700win32_lstat_w(const wchar_t* 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_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001703}
1704
1705static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001706win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001707{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001709}
1710
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001711static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001712win32_stat_w(const wchar_t* 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_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001715}
1716
Martin v. Löwis14694662006-02-03 12:54:16 +00001717#endif /* MS_WINDOWS */
1718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001720"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001721This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001722 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001723or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1724\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001725Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1726or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001727\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001728See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001729
1730static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 {"st_mode", "protection bits"},
1732 {"st_ino", "inode"},
1733 {"st_dev", "device"},
1734 {"st_nlink", "number of hard links"},
1735 {"st_uid", "user ID of owner"},
1736 {"st_gid", "group ID of owner"},
1737 {"st_size", "total size, in bytes"},
1738 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1739 {NULL, "integer time of last access"},
1740 {NULL, "integer time of last modification"},
1741 {NULL, "integer time of last change"},
1742 {"st_atime", "time of last access"},
1743 {"st_mtime", "time of last modification"},
1744 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001745 {"st_atime_ns", "time of last access in nanoseconds"},
1746 {"st_mtime_ns", "time of last modification in nanoseconds"},
1747 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001748#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001751#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001752 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001753#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001754#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001755 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001757#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001759#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001760#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001762#endif
1763#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001765#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001766#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1767 {"st_file_attributes", "Windows file attribute bits"},
1768#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001770};
1771
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001772#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001773#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001774#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001775#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776#endif
1777
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001778#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001779#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1780#else
1781#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1782#endif
1783
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1786#else
1787#define ST_RDEV_IDX ST_BLOCKS_IDX
1788#endif
1789
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001790#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1791#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1792#else
1793#define ST_FLAGS_IDX ST_RDEV_IDX
1794#endif
1795
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001796#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001797#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001799#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001800#endif
1801
1802#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1803#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1804#else
1805#define ST_BIRTHTIME_IDX ST_GEN_IDX
1806#endif
1807
Zachary Ware63f277b2014-06-19 09:46:37 -05001808#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1809#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1810#else
1811#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1812#endif
1813
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001814static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 "stat_result", /* name */
1816 stat_result__doc__, /* doc */
1817 stat_result_fields,
1818 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001819};
1820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001822"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1823This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001824 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001825or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001826\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001828
1829static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 {"f_bsize", },
1831 {"f_frsize", },
1832 {"f_blocks", },
1833 {"f_bfree", },
1834 {"f_bavail", },
1835 {"f_files", },
1836 {"f_ffree", },
1837 {"f_favail", },
1838 {"f_flag", },
1839 {"f_namemax",},
1840 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841};
1842
1843static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 "statvfs_result", /* name */
1845 statvfs_result__doc__, /* doc */
1846 statvfs_result_fields,
1847 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001848};
1849
Ross Lagerwall7807c352011-03-17 20:20:30 +02001850#if defined(HAVE_WAITID) && !defined(__APPLE__)
1851PyDoc_STRVAR(waitid_result__doc__,
1852"waitid_result: Result from waitid.\n\n\
1853This object may be accessed either as a tuple of\n\
1854 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1855or via the attributes si_pid, si_uid, and so on.\n\
1856\n\
1857See os.waitid for more information.");
1858
1859static PyStructSequence_Field waitid_result_fields[] = {
1860 {"si_pid", },
1861 {"si_uid", },
1862 {"si_signo", },
1863 {"si_status", },
1864 {"si_code", },
1865 {0}
1866};
1867
1868static PyStructSequence_Desc waitid_result_desc = {
1869 "waitid_result", /* name */
1870 waitid_result__doc__, /* doc */
1871 waitid_result_fields,
1872 5
1873};
1874static PyTypeObject WaitidResultType;
1875#endif
1876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001877static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001878static PyTypeObject StatResultType;
1879static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001880#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001881static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001882#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001883static newfunc structseq_new;
1884
1885static PyObject *
1886statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1887{
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 PyStructSequence *result;
1889 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001890
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 result = (PyStructSequence*)structseq_new(type, args, kwds);
1892 if (!result)
1893 return NULL;
1894 /* If we have been initialized from a tuple,
1895 st_?time might be set to None. Initialize it
1896 from the int slots. */
1897 for (i = 7; i <= 9; i++) {
1898 if (result->ob_item[i+3] == Py_None) {
1899 Py_DECREF(Py_None);
1900 Py_INCREF(result->ob_item[i]);
1901 result->ob_item[i+3] = result->ob_item[i];
1902 }
1903 }
1904 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001905}
1906
1907
1908
1909/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001910static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001911
1912PyDoc_STRVAR(stat_float_times__doc__,
1913"stat_float_times([newval]) -> oldval\n\n\
1914Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001915\n\
1916If value is True, future calls to stat() return floats; if it is False,\n\
1917future calls return ints.\n\
1918If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001919
Larry Hastings2f936352014-08-05 14:04:04 +10001920/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001921static PyObject*
1922stat_float_times(PyObject* self, PyObject *args)
1923{
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 int newval = -1;
1925 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1926 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001927 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1928 "stat_float_times() is deprecated",
1929 1))
1930 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 if (newval == -1)
1932 /* Return old value */
1933 return PyBool_FromLong(_stat_float_times);
1934 _stat_float_times = newval;
1935 Py_INCREF(Py_None);
1936 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001937}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938
Larry Hastings6fe20b32012-04-19 15:07:49 -07001939static PyObject *billion = NULL;
1940
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001941static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001942fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001943{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001944 PyObject *s = _PyLong_FromTime_t(sec);
1945 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1946 PyObject *s_in_ns = NULL;
1947 PyObject *ns_total = NULL;
1948 PyObject *float_s = NULL;
1949
1950 if (!(s && ns_fractional))
1951 goto exit;
1952
1953 s_in_ns = PyNumber_Multiply(s, billion);
1954 if (!s_in_ns)
1955 goto exit;
1956
1957 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1958 if (!ns_total)
1959 goto exit;
1960
Victor Stinner4195b5c2012-02-08 23:03:19 +01001961 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001962 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1963 if (!float_s)
1964 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001966 else {
1967 float_s = s;
1968 Py_INCREF(float_s);
1969 }
1970
1971 PyStructSequence_SET_ITEM(v, index, s);
1972 PyStructSequence_SET_ITEM(v, index+3, float_s);
1973 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1974 s = NULL;
1975 float_s = NULL;
1976 ns_total = NULL;
1977exit:
1978 Py_XDECREF(s);
1979 Py_XDECREF(ns_fractional);
1980 Py_XDECREF(s_in_ns);
1981 Py_XDECREF(ns_total);
1982 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001983}
1984
Tim Peters5aa91602002-01-30 05:46:57 +00001985/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001986 (used by posix_stat() and posix_fstat()) */
1987static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001988_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001989{
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 unsigned long ansec, mnsec, cnsec;
1991 PyObject *v = PyStructSequence_New(&StatResultType);
1992 if (v == NULL)
1993 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001994
Victor Stinner8c62be82010-05-06 00:08:46 +00001995 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001996#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 PyStructSequence_SET_ITEM(v, 1,
1998 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001999#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002001#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002002#ifdef MS_WINDOWS
2003 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002004#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002005 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002006#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002008#if defined(MS_WINDOWS)
2009 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2010 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2011#else
2012 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2013 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2014#endif
Fred Drake699f3522000-06-29 21:12:41 +00002015#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 PyStructSequence_SET_ITEM(v, 6,
2017 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002018#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002020#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002021
Martin v. Löwis14694662006-02-03 12:54:16 +00002022#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 ansec = st->st_atim.tv_nsec;
2024 mnsec = st->st_mtim.tv_nsec;
2025 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002026#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 ansec = st->st_atimespec.tv_nsec;
2028 mnsec = st->st_mtimespec.tv_nsec;
2029 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002030#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 ansec = st->st_atime_nsec;
2032 mnsec = st->st_mtime_nsec;
2033 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002034#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002036#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002037 fill_time(v, 7, st->st_atime, ansec);
2038 fill_time(v, 8, st->st_mtime, mnsec);
2039 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002040
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002041#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2043 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002044#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002045#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2047 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002049#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2051 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002052#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002053#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2055 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002056#endif
2057#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002059 PyObject *val;
2060 unsigned long bsec,bnsec;
2061 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002062#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002063 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002064#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002065 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002066#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002067 if (_stat_float_times) {
2068 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2069 } else {
2070 val = PyLong_FromLong((long)bsec);
2071 }
2072 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2073 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002074 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002075#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002076#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2078 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002079#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002080#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2081 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2082 PyLong_FromUnsignedLong(st->st_file_attributes));
2083#endif
Fred Drake699f3522000-06-29 21:12:41 +00002084
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 if (PyErr_Occurred()) {
2086 Py_DECREF(v);
2087 return NULL;
2088 }
Fred Drake699f3522000-06-29 21:12:41 +00002089
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002091}
2092
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002093/* POSIX methods */
2094
Guido van Rossum94f6f721999-01-06 18:42:14 +00002095
2096static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002097posix_do_stat(char *function_name, path_t *path,
2098 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002099{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002100 STRUCT_STAT st;
2101 int result;
2102
2103#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2104 if (follow_symlinks_specified(function_name, follow_symlinks))
2105 return NULL;
2106#endif
2107
2108 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2109 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2110 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2111 return NULL;
2112
2113 Py_BEGIN_ALLOW_THREADS
2114 if (path->fd != -1)
2115 result = FSTAT(path->fd, &st);
2116 else
2117#ifdef MS_WINDOWS
2118 if (path->wide) {
2119 if (follow_symlinks)
2120 result = win32_stat_w(path->wide, &st);
2121 else
2122 result = win32_lstat_w(path->wide, &st);
2123 }
2124 else
2125#endif
2126#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2127 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2128 result = LSTAT(path->narrow, &st);
2129 else
2130#endif
2131#ifdef HAVE_FSTATAT
2132 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2133 result = fstatat(dir_fd, path->narrow, &st,
2134 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2135 else
2136#endif
2137 result = STAT(path->narrow, &st);
2138 Py_END_ALLOW_THREADS
2139
Victor Stinner292c8352012-10-30 02:17:38 +01002140 if (result != 0) {
2141 return path_error(path);
2142 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002143
2144 return _pystat_fromstructstat(&st);
2145}
2146
Larry Hastings2f936352014-08-05 14:04:04 +10002147/*[python input]
2148
2149for s in """
2150
2151FACCESSAT
2152FCHMODAT
2153FCHOWNAT
2154FSTATAT
2155LINKAT
2156MKDIRAT
2157MKFIFOAT
2158MKNODAT
2159OPENAT
2160READLINKAT
2161SYMLINKAT
2162UNLINKAT
2163
2164""".strip().split():
2165 s = s.strip()
2166 print("""
2167#ifdef HAVE_{s}
2168 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002169#else
Larry Hastings2f936352014-08-05 14:04:04 +10002170 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002172""".rstrip().format(s=s))
2173
2174for s in """
2175
2176FCHDIR
2177FCHMOD
2178FCHOWN
2179FDOPENDIR
2180FEXECVE
2181FPATHCONF
2182FSTATVFS
2183FTRUNCATE
2184
2185""".strip().split():
2186 s = s.strip()
2187 print("""
2188#ifdef HAVE_{s}
2189 #define PATH_HAVE_{s} 1
2190#else
2191 #define PATH_HAVE_{s} 0
2192#endif
2193
2194""".rstrip().format(s=s))
2195[python start generated code]*/
2196
2197#ifdef HAVE_FACCESSAT
2198 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2199#else
2200 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2201#endif
2202
2203#ifdef HAVE_FCHMODAT
2204 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2205#else
2206 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2207#endif
2208
2209#ifdef HAVE_FCHOWNAT
2210 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2211#else
2212 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2213#endif
2214
2215#ifdef HAVE_FSTATAT
2216 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2217#else
2218 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2219#endif
2220
2221#ifdef HAVE_LINKAT
2222 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2223#else
2224 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2225#endif
2226
2227#ifdef HAVE_MKDIRAT
2228 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2229#else
2230 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2231#endif
2232
2233#ifdef HAVE_MKFIFOAT
2234 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2235#else
2236 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2237#endif
2238
2239#ifdef HAVE_MKNODAT
2240 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_OPENAT
2246 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_READLINKAT
2252 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_SYMLINKAT
2258 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_UNLINKAT
2264 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_FCHDIR
2270 #define PATH_HAVE_FCHDIR 1
2271#else
2272 #define PATH_HAVE_FCHDIR 0
2273#endif
2274
2275#ifdef HAVE_FCHMOD
2276 #define PATH_HAVE_FCHMOD 1
2277#else
2278 #define PATH_HAVE_FCHMOD 0
2279#endif
2280
2281#ifdef HAVE_FCHOWN
2282 #define PATH_HAVE_FCHOWN 1
2283#else
2284 #define PATH_HAVE_FCHOWN 0
2285#endif
2286
2287#ifdef HAVE_FDOPENDIR
2288 #define PATH_HAVE_FDOPENDIR 1
2289#else
2290 #define PATH_HAVE_FDOPENDIR 0
2291#endif
2292
2293#ifdef HAVE_FEXECVE
2294 #define PATH_HAVE_FEXECVE 1
2295#else
2296 #define PATH_HAVE_FEXECVE 0
2297#endif
2298
2299#ifdef HAVE_FPATHCONF
2300 #define PATH_HAVE_FPATHCONF 1
2301#else
2302 #define PATH_HAVE_FPATHCONF 0
2303#endif
2304
2305#ifdef HAVE_FSTATVFS
2306 #define PATH_HAVE_FSTATVFS 1
2307#else
2308 #define PATH_HAVE_FSTATVFS 0
2309#endif
2310
2311#ifdef HAVE_FTRUNCATE
2312 #define PATH_HAVE_FTRUNCATE 1
2313#else
2314 #define PATH_HAVE_FTRUNCATE 0
2315#endif
2316/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002317
2318
Larry Hastings61272b72014-01-07 12:41:53 -08002319/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002320
2321class path_t_converter(CConverter):
2322
2323 type = "path_t"
2324 impl_by_reference = True
2325 parse_by_reference = True
2326
2327 converter = 'path_converter'
2328
2329 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002330 # right now path_t doesn't support default values.
2331 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002332 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002333 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002334
Larry Hastings2f936352014-08-05 14:04:04 +10002335 if self.c_default not in (None, 'Py_None'):
2336 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002337
2338 self.nullable = nullable
2339 self.allow_fd = allow_fd
2340
Larry Hastings7726ac92014-01-31 22:03:12 -08002341 def pre_render(self):
2342 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002343 if isinstance(value, str):
2344 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002345 return str(int(bool(value)))
2346
2347 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002348 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002349 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002350 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002351 strify(self.nullable),
2352 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002353 )
2354
2355 def cleanup(self):
2356 return "path_cleanup(&" + self.name + ");\n"
2357
2358
2359class dir_fd_converter(CConverter):
2360 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002361
Larry Hastings2f936352014-08-05 14:04:04 +10002362 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002363 if self.default in (unspecified, None):
2364 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002365 if isinstance(requires, str):
2366 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2367 else:
2368 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002369
Larry Hastings2f936352014-08-05 14:04:04 +10002370class fildes_converter(CConverter):
2371 type = 'int'
2372 converter = 'fildes_converter'
2373
2374class uid_t_converter(CConverter):
2375 type = "uid_t"
2376 converter = '_Py_Uid_Converter'
2377
2378class gid_t_converter(CConverter):
2379 type = "gid_t"
2380 converter = '_Py_Gid_Converter'
2381
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002382class dev_t_converter(CConverter):
2383 type = 'dev_t'
2384 converter = '_Py_Dev_Converter'
2385
2386class dev_t_return_converter(unsigned_long_return_converter):
2387 type = 'dev_t'
2388 conversion_fn = '_PyLong_FromDev'
2389 unsigned_cast = '(dev_t)'
2390
Larry Hastings2f936352014-08-05 14:04:04 +10002391class FSConverter_converter(CConverter):
2392 type = 'PyObject *'
2393 converter = 'PyUnicode_FSConverter'
2394 def converter_init(self):
2395 if self.default is not unspecified:
2396 fail("FSConverter_converter does not support default values")
2397 self.c_default = 'NULL'
2398
2399 def cleanup(self):
2400 return "Py_XDECREF(" + self.name + ");\n"
2401
2402class pid_t_converter(CConverter):
2403 type = 'pid_t'
2404 format_unit = '" _Py_PARSE_PID "'
2405
2406class idtype_t_converter(int_converter):
2407 type = 'idtype_t'
2408
2409class id_t_converter(CConverter):
2410 type = 'id_t'
2411 format_unit = '" _Py_PARSE_PID "'
2412
2413class Py_intptr_t_converter(CConverter):
2414 type = 'Py_intptr_t'
2415 format_unit = '" _Py_PARSE_INTPTR "'
2416
2417class Py_off_t_converter(CConverter):
2418 type = 'Py_off_t'
2419 converter = 'Py_off_t_converter'
2420
2421class Py_off_t_return_converter(long_return_converter):
2422 type = 'Py_off_t'
2423 conversion_fn = 'PyLong_FromPy_off_t'
2424
2425class path_confname_converter(CConverter):
2426 type="int"
2427 converter="conv_path_confname"
2428
2429class confstr_confname_converter(path_confname_converter):
2430 converter='conv_confstr_confname'
2431
2432class sysconf_confname_converter(path_confname_converter):
2433 converter="conv_sysconf_confname"
2434
2435class sched_param_converter(CConverter):
2436 type = 'struct sched_param'
2437 converter = 'convert_sched_param'
2438 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002439
Larry Hastings61272b72014-01-07 12:41:53 -08002440[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002441/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002442
Larry Hastings61272b72014-01-07 12:41:53 -08002443/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002444
Larry Hastings2a727912014-01-16 11:32:01 -08002445os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002446
2447 path : path_t(allow_fd=True)
2448 Path to be examined; can be string, bytes, or open-file-descriptor int.
2449
2450 *
2451
Larry Hastings2f936352014-08-05 14:04:04 +10002452 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002453 If not None, it should be a file descriptor open to a directory,
2454 and path should be a relative string; path will then be relative to
2455 that directory.
2456
2457 follow_symlinks: bool = True
2458 If False, and the last element of the path is a symbolic link,
2459 stat will examine the symbolic link itself instead of the file
2460 the link points to.
2461
2462Perform a stat system call on the given path.
2463
2464dir_fd and follow_symlinks may not be implemented
2465 on your platform. If they are unavailable, using them will raise a
2466 NotImplementedError.
2467
2468It's an error to use dir_fd or follow_symlinks when specifying path as
2469 an open file descriptor.
2470
Larry Hastings61272b72014-01-07 12:41:53 -08002471[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002472
Larry Hastings31826802013-10-19 00:09:25 -07002473static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002474os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002475/*[clinic end generated code: output=708c225f94fcfc8e input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002476{
2477 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2478}
2479
Larry Hastings2f936352014-08-05 14:04:04 +10002480
2481/*[clinic input]
2482os.lstat
2483
2484 path : path_t
2485
2486 *
2487
2488 dir_fd : dir_fd(requires='fstatat') = None
2489
2490Perform a stat system call on the given path, without following symbolic links.
2491
2492Like stat(), but do not follow symbolic links.
2493Equivalent to stat(path, follow_symlinks=False).
2494[clinic start generated code]*/
2495
Larry Hastings2f936352014-08-05 14:04:04 +10002496static PyObject *
2497os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002498/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002499{
2500 int follow_symlinks = 0;
2501 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2502}
Larry Hastings31826802013-10-19 00:09:25 -07002503
Larry Hastings2f936352014-08-05 14:04:04 +10002504
Larry Hastings61272b72014-01-07 12:41:53 -08002505/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002506os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002507
2508 path: path_t(allow_fd=True)
2509 Path to be tested; can be string, bytes, or open-file-descriptor int.
2510
2511 mode: int
2512 Operating-system mode bitfield. Can be F_OK to test existence,
2513 or the inclusive-OR of R_OK, W_OK, and X_OK.
2514
2515 *
2516
Larry Hastings2f936352014-08-05 14:04:04 +10002517 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002518 If not None, it should be a file descriptor open to a directory,
2519 and path should be relative; path will then be relative to that
2520 directory.
2521
2522 effective_ids: bool = False
2523 If True, access will use the effective uid/gid instead of
2524 the real uid/gid.
2525
2526 follow_symlinks: bool = True
2527 If False, and the last element of the path is a symbolic link,
2528 access will examine the symbolic link itself instead of the file
2529 the link points to.
2530
2531Use the real uid/gid to test for access to a path.
2532
2533{parameters}
2534dir_fd, effective_ids, and follow_symlinks may not be implemented
2535 on your platform. If they are unavailable, using them will raise a
2536 NotImplementedError.
2537
2538Note that most operations will use the effective uid/gid, therefore this
2539 routine can be used in a suid/sgid environment to test if the invoking user
2540 has the specified access to the path.
2541
Larry Hastings61272b72014-01-07 12:41:53 -08002542[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002543
Larry Hastings2f936352014-08-05 14:04:04 +10002544static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002545os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002546/*[clinic end generated code: output=f9e734db3d88b767 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002547{
Larry Hastings2f936352014-08-05 14:04:04 +10002548 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002549
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002550#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002551 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002552#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002554#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002555
Larry Hastings9cf065c2012-06-22 16:30:09 -07002556#ifndef HAVE_FACCESSAT
2557 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002558 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559
2560 if (effective_ids) {
2561 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002562 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002563 }
2564#endif
2565
2566#ifdef MS_WINDOWS
2567 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002568 if (path->wide != NULL)
2569 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002571 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 Py_END_ALLOW_THREADS
2573
2574 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002575 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 * * we didn't get a -1, and
2577 * * write access wasn't requested,
2578 * * or the file isn't read-only,
2579 * * or it's a directory.
2580 * (Directories cannot be read-only on Windows.)
2581 */
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002585 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002598 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 }
2600 else
2601#endif
Larry Hastings31826802013-10-19 00:09:25 -07002602 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002604 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#endif
2606
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002608}
2609
Guido van Rossumd371ff11999-01-25 16:12:23 +00002610#ifndef F_OK
2611#define F_OK 0
2612#endif
2613#ifndef R_OK
2614#define R_OK 4
2615#endif
2616#ifndef W_OK
2617#define W_OK 2
2618#endif
2619#ifndef X_OK
2620#define X_OK 1
2621#endif
2622
Larry Hastings31826802013-10-19 00:09:25 -07002623
Guido van Rossumd371ff11999-01-25 16:12:23 +00002624#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002625/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002626os.ttyname -> DecodeFSDefault
2627
2628 fd: int
2629 Integer file descriptor handle.
2630
2631 /
2632
2633Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002634[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635
Larry Hastings31826802013-10-19 00:09:25 -07002636static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002637os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002638/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002639{
2640 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002641
Larry Hastings31826802013-10-19 00:09:25 -07002642 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002644 posix_error();
2645 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002646}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002647#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002650/*[clinic input]
2651os.ctermid
2652
2653Return the name of the controlling terminal for this process.
2654[clinic start generated code]*/
2655
Larry Hastings2f936352014-08-05 14:04:04 +10002656static PyObject *
2657os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002658/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659{
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 char *ret;
2661 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
Greg Wardb48bc172000-03-01 21:51:56 +00002663#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 if (ret == NULL)
2669 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002670 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671}
Larry Hastings2f936352014-08-05 14:04:04 +10002672#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673
Larry Hastings2f936352014-08-05 14:04:04 +10002674
2675/*[clinic input]
2676os.chdir
2677
2678 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2679
2680Change the current working directory to the specified path.
2681
2682path may always be specified as a string.
2683On some platforms, path may also be specified as an open file descriptor.
2684 If this functionality is unavailable, using it raises an exception.
2685[clinic start generated code]*/
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687static PyObject *
2688os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002689/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002690{
2691 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002695 if (path->wide)
2696 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 else
Larry Hastings2f936352014-08-05 14:04:04 +10002698 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002699 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700#else
2701#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002702 if (path->fd != -1)
2703 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704 else
2705#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002706 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002707#endif
2708 Py_END_ALLOW_THREADS
2709
2710 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002711 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712 }
2713
Larry Hastings2f936352014-08-05 14:04:04 +10002714 Py_RETURN_NONE;
2715}
2716
2717
2718#ifdef HAVE_FCHDIR
2719/*[clinic input]
2720os.fchdir
2721
2722 fd: fildes
2723
2724Change to the directory of the given file descriptor.
2725
2726fd must be opened on a directory, not a file.
2727Equivalent to os.chdir(fd).
2728
2729[clinic start generated code]*/
2730
Fred Drake4d1e64b2002-04-15 19:40:07 +00002731static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002732os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002733/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002734{
Larry Hastings2f936352014-08-05 14:04:04 +10002735 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002736}
2737#endif /* HAVE_FCHDIR */
2738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002739
Larry Hastings2f936352014-08-05 14:04:04 +10002740/*[clinic input]
2741os.chmod
2742
2743 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2744 Path to be modified. May always be specified as a str or bytes.
2745 On some platforms, path may also be specified as an open file descriptor.
2746 If this functionality is unavailable, using it raises an exception.
2747
2748 mode: int
2749 Operating-system mode bitfield.
2750
2751 *
2752
2753 dir_fd : dir_fd(requires='fchmodat') = None
2754 If not None, it should be a file descriptor open to a directory,
2755 and path should be relative; path will then be relative to that
2756 directory.
2757
2758 follow_symlinks: bool = True
2759 If False, and the last element of the path is a symbolic link,
2760 chmod will modify the symbolic link itself instead of the file
2761 the link points to.
2762
2763Change the access permissions of a file.
2764
2765It is an error to use dir_fd or follow_symlinks when specifying path as
2766 an open file descriptor.
2767dir_fd and follow_symlinks may not be implemented on your platform.
2768 If they are unavailable, using them will raise a NotImplementedError.
2769
2770[clinic start generated code]*/
2771
Larry Hastings2f936352014-08-05 14:04:04 +10002772static PyObject *
2773os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002774/*[clinic end generated code: output=96063c976f23106a input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002775{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002776 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002777
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002778#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002779 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002781
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782#ifdef HAVE_FCHMODAT
2783 int fchmodat_nofollow_unsupported = 0;
2784#endif
2785
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2787 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002788 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002789#endif
2790
2791#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002793 if (path->wide)
2794 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 else
Larry Hastings2f936352014-08-05 14:04:04 +10002796 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002797 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 result = 0;
2799 else {
2800 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 attr &= ~FILE_ATTRIBUTE_READONLY;
2802 else
2803 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002804 if (path->wide)
2805 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806 else
Larry Hastings2f936352014-08-05 14:04:04 +10002807 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 }
2809 Py_END_ALLOW_THREADS
2810
2811 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002812 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 }
2814#else /* MS_WINDOWS */
2815 Py_BEGIN_ALLOW_THREADS
2816#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002817 if (path->fd != -1)
2818 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 else
2820#endif
2821#ifdef HAVE_LCHMOD
2822 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002823 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 else
2825#endif
2826#ifdef HAVE_FCHMODAT
2827 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2828 /*
2829 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2830 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002831 * and then says it isn't implemented yet.
2832 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833 *
2834 * Once it is supported, os.chmod will automatically
2835 * support dir_fd and follow_symlinks=False. (Hopefully.)
2836 * Until then, we need to be careful what exception we raise.
2837 */
Larry Hastings2f936352014-08-05 14:04:04 +10002838 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2840 /*
2841 * But wait! We can't throw the exception without allowing threads,
2842 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2843 */
2844 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002845 result &&
2846 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2847 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002848 }
2849 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002850#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002851 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 Py_END_ALLOW_THREADS
2853
2854 if (result) {
2855#ifdef HAVE_FCHMODAT
2856 if (fchmodat_nofollow_unsupported) {
2857 if (dir_fd != DEFAULT_DIR_FD)
2858 dir_fd_and_follow_symlinks_invalid("chmod",
2859 dir_fd, follow_symlinks);
2860 else
2861 follow_symlinks_specified("chmod", follow_symlinks);
2862 }
2863 else
2864#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002865 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002866 }
2867#endif
2868
Larry Hastings2f936352014-08-05 14:04:04 +10002869 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002870}
2871
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872
Christian Heimes4e30a842007-11-30 22:12:06 +00002873#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002874/*[clinic input]
2875os.fchmod
2876
2877 fd: int
2878 mode: int
2879
2880Change the access permissions of the file given by file descriptor fd.
2881
2882Equivalent to os.chmod(fd, mode).
2883[clinic start generated code]*/
2884
Larry Hastings2f936352014-08-05 14:04:04 +10002885static PyObject *
2886os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002887/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002888{
2889 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002890 int async_err = 0;
2891
2892 do {
2893 Py_BEGIN_ALLOW_THREADS
2894 res = fchmod(fd, mode);
2895 Py_END_ALLOW_THREADS
2896 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2897 if (res != 0)
2898 return (!async_err) ? posix_error() : NULL;
2899
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002901}
2902#endif /* HAVE_FCHMOD */
2903
Larry Hastings2f936352014-08-05 14:04:04 +10002904
Christian Heimes4e30a842007-11-30 22:12:06 +00002905#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002906/*[clinic input]
2907os.lchmod
2908
2909 path: path_t
2910 mode: int
2911
2912Change the access permissions of a file, without following symbolic links.
2913
2914If path is a symlink, this affects the link itself rather than the target.
2915Equivalent to chmod(path, mode, follow_symlinks=False)."
2916[clinic start generated code]*/
2917
Larry Hastings2f936352014-08-05 14:04:04 +10002918static PyObject *
2919os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002920/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002921{
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002923 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002924 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002925 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002926 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002927 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002928 return NULL;
2929 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002931}
2932#endif /* HAVE_LCHMOD */
2933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002934
Thomas Wouterscf297e42007-02-23 15:07:44 +00002935#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002936/*[clinic input]
2937os.chflags
2938
2939 path: path_t
2940 flags: unsigned_long(bitwise=True)
2941 follow_symlinks: bool=True
2942
2943Set file flags.
2944
2945If follow_symlinks is False, and the last element of the path is a symbolic
2946 link, chflags will change flags on the symbolic link itself instead of the
2947 file the link points to.
2948follow_symlinks may not be implemented on your platform. If it is
2949unavailable, using it will raise a NotImplementedError.
2950
2951[clinic start generated code]*/
2952
Larry Hastings2f936352014-08-05 14:04:04 +10002953static PyObject *
2954os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002955/*[clinic end generated code: output=9e5f9417afc20c4b input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002956{
2957 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958
2959#ifndef HAVE_LCHFLAGS
2960 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002961 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962#endif
2963
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965#ifdef HAVE_LCHFLAGS
2966 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002967 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002968 else
2969#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002970 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
Larry Hastings2f936352014-08-05 14:04:04 +10002973 if (result)
2974 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
Larry Hastings2f936352014-08-05 14:04:04 +10002976 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002977}
2978#endif /* HAVE_CHFLAGS */
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980
Thomas Wouterscf297e42007-02-23 15:07:44 +00002981#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002982/*[clinic input]
2983os.lchflags
2984
2985 path: path_t
2986 flags: unsigned_long(bitwise=True)
2987
2988Set file flags.
2989
2990This function will not follow symbolic links.
2991Equivalent to chflags(path, flags, follow_symlinks=False).
2992[clinic start generated code]*/
2993
Larry Hastings2f936352014-08-05 14:04:04 +10002994static PyObject *
2995os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002996/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002997{
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003000 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003002 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003003 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003004 }
Victor Stinner292c8352012-10-30 02:17:38 +01003005 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003006}
3007#endif /* HAVE_LCHFLAGS */
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009
Martin v. Löwis244edc82001-10-04 22:44:26 +00003010#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003011/*[clinic input]
3012os.chroot
3013 path: path_t
3014
3015Change root directory to path.
3016
3017[clinic start generated code]*/
3018
Larry Hastings2f936352014-08-05 14:04:04 +10003019static PyObject *
3020os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003021/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003022{
3023 int res;
3024 Py_BEGIN_ALLOW_THREADS
3025 res = chroot(path->narrow);
3026 Py_END_ALLOW_THREADS
3027 if (res < 0)
3028 return path_error(path);
3029 Py_RETURN_NONE;
3030}
3031#endif /* HAVE_CHROOT */
3032
Martin v. Löwis244edc82001-10-04 22:44:26 +00003033
Guido van Rossum21142a01999-01-08 21:05:37 +00003034#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003035/*[clinic input]
3036os.fsync
3037
3038 fd: fildes
3039
3040Force write of fd to disk.
3041[clinic start generated code]*/
3042
Larry Hastings2f936352014-08-05 14:04:04 +10003043static PyObject *
3044os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003045/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003046{
3047 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003048}
3049#endif /* HAVE_FSYNC */
3050
Larry Hastings2f936352014-08-05 14:04:04 +10003051
Ross Lagerwall7807c352011-03-17 20:20:30 +02003052#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003053/*[clinic input]
3054os.sync
3055
3056Force write of everything to disk.
3057[clinic start generated code]*/
3058
Larry Hastings2f936352014-08-05 14:04:04 +10003059static PyObject *
3060os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003061/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003062{
3063 Py_BEGIN_ALLOW_THREADS
3064 sync();
3065 Py_END_ALLOW_THREADS
3066 Py_RETURN_NONE;
3067}
Larry Hastings2f936352014-08-05 14:04:04 +10003068#endif /* HAVE_SYNC */
3069
Ross Lagerwall7807c352011-03-17 20:20:30 +02003070
Guido van Rossum21142a01999-01-08 21:05:37 +00003071#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003072#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003073extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3074#endif
3075
Larry Hastings2f936352014-08-05 14:04:04 +10003076/*[clinic input]
3077os.fdatasync
3078
3079 fd: fildes
3080
3081Force write of fd to disk without forcing update of metadata.
3082[clinic start generated code]*/
3083
Larry Hastings2f936352014-08-05 14:04:04 +10003084static PyObject *
3085os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003086/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003087{
3088 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003089}
3090#endif /* HAVE_FDATASYNC */
3091
3092
Fredrik Lundh10723342000-07-10 16:38:09 +00003093#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003094/*[clinic input]
3095os.chown
3096
3097 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3098 Path to be examined; can be string, bytes, or open-file-descriptor int.
3099
3100 uid: uid_t
3101
3102 gid: gid_t
3103
3104 *
3105
3106 dir_fd : dir_fd(requires='fchownat') = None
3107 If not None, it should be a file descriptor open to a directory,
3108 and path should be relative; path will then be relative to that
3109 directory.
3110
3111 follow_symlinks: bool = True
3112 If False, and the last element of the path is a symbolic link,
3113 stat will examine the symbolic link itself instead of the file
3114 the link points to.
3115
3116Change the owner and group id of path to the numeric uid and gid.\
3117
3118path may always be specified as a string.
3119On some platforms, path may also be specified as an open file descriptor.
3120 If this functionality is unavailable, using it raises an exception.
3121If dir_fd is 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 directory.
3123If follow_symlinks is False, and the last element of the path is a symbolic
3124 link, chown will modify the symbolic link itself instead of the file the
3125 link points to.
3126It is an error to use dir_fd or follow_symlinks when specifying path as
3127 an open file descriptor.
3128dir_fd and follow_symlinks may not be implemented on your platform.
3129 If they are unavailable, using them will raise a NotImplementedError.
3130
3131[clinic start generated code]*/
3132
Larry Hastings2f936352014-08-05 14:04:04 +10003133static PyObject *
3134os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003135/*[clinic end generated code: output=59a8db91897fb46c input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003136{
3137 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138
3139#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3140 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003141 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003143 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3144 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3145 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003146
3147#ifdef __APPLE__
3148 /*
3149 * This is for Mac OS X 10.3, which doesn't have lchown.
3150 * (But we still have an lchown symbol because of weak-linking.)
3151 * It doesn't have fchownat either. So there's no possibility
3152 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003153 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003154 if ((!follow_symlinks) && (lchown == NULL)) {
3155 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003156 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 }
3158#endif
3159
Victor Stinner8c62be82010-05-06 00:08:46 +00003160 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003162 if (path->fd != -1)
3163 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164 else
3165#endif
3166#ifdef HAVE_LCHOWN
3167 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003168 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 else
3170#endif
3171#ifdef HAVE_FCHOWNAT
3172 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003173 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3175 else
3176#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003177 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179
Larry Hastings2f936352014-08-05 14:04:04 +10003180 if (result)
3181 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182
Larry Hastings2f936352014-08-05 14:04:04 +10003183 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003184}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003185#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003186
Larry Hastings2f936352014-08-05 14:04:04 +10003187
Christian Heimes4e30a842007-11-30 22:12:06 +00003188#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003189/*[clinic input]
3190os.fchown
3191
3192 fd: int
3193 uid: uid_t
3194 gid: gid_t
3195
3196Change the owner and group id of the file specified by file descriptor.
3197
3198Equivalent to os.chown(fd, uid, gid).
3199
3200[clinic start generated code]*/
3201
Larry Hastings2f936352014-08-05 14:04:04 +10003202static PyObject *
3203os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003204/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003205{
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003207 int async_err = 0;
3208
3209 do {
3210 Py_BEGIN_ALLOW_THREADS
3211 res = fchown(fd, uid, gid);
3212 Py_END_ALLOW_THREADS
3213 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3214 if (res != 0)
3215 return (!async_err) ? posix_error() : NULL;
3216
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003218}
3219#endif /* HAVE_FCHOWN */
3220
Larry Hastings2f936352014-08-05 14:04:04 +10003221
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003222#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003223/*[clinic input]
3224os.lchown
3225
3226 path : path_t
3227 uid: uid_t
3228 gid: gid_t
3229
3230Change the owner and group id of path to the numeric uid and gid.
3231
3232This function will not follow symbolic links.
3233Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3234[clinic start generated code]*/
3235
Larry Hastings2f936352014-08-05 14:04:04 +10003236static PyObject *
3237os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003238/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003239{
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003242 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003244 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003245 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003246 }
Larry Hastings2f936352014-08-05 14:04:04 +10003247 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003248}
3249#endif /* HAVE_LCHOWN */
3250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251
Barry Warsaw53699e91996-12-10 23:23:01 +00003252static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003253posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003254{
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 char buf[1026];
3256 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003257
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003258#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 if (!use_bytes) {
3260 wchar_t wbuf[1026];
3261 wchar_t *wbuf2 = wbuf;
3262 PyObject *resobj;
3263 DWORD len;
3264 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003265 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 /* If the buffer is large enough, len does not include the
3267 terminating \0. If the buffer is too small, len includes
3268 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003269 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003270 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 if (wbuf2)
3272 len = GetCurrentDirectoryW(len, wbuf2);
3273 }
3274 Py_END_ALLOW_THREADS
3275 if (!wbuf2) {
3276 PyErr_NoMemory();
3277 return NULL;
3278 }
3279 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003280 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003281 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003282 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003283 }
3284 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003285 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003286 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 return resobj;
3288 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003289
3290 if (win32_warn_bytes_api())
3291 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003292#endif
3293
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003295 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 Py_END_ALLOW_THREADS
3297 if (res == NULL)
3298 return posix_error();
3299 if (use_bytes)
3300 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003301 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003302}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303
Larry Hastings2f936352014-08-05 14:04:04 +10003304
3305/*[clinic input]
3306os.getcwd
3307
3308Return a unicode string representing the current working directory.
3309[clinic start generated code]*/
3310
Larry Hastings2f936352014-08-05 14:04:04 +10003311static PyObject *
3312os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003313/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003314{
3315 return posix_getcwd(0);
3316}
3317
Larry Hastings2f936352014-08-05 14:04:04 +10003318
3319/*[clinic input]
3320os.getcwdb
3321
3322Return a bytes string representing the current working directory.
3323[clinic start generated code]*/
3324
Larry Hastings2f936352014-08-05 14:04:04 +10003325static PyObject *
3326os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003327/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003328{
3329 return posix_getcwd(1);
3330}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003331
Larry Hastings2f936352014-08-05 14:04:04 +10003332
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3334#define HAVE_LINK 1
3335#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003336
Guido van Rossumb6775db1994-08-01 11:34:53 +00003337#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003338/*[clinic input]
3339
3340os.link
3341
3342 src : path_t
3343 dst : path_t
3344 *
3345 src_dir_fd : dir_fd = None
3346 dst_dir_fd : dir_fd = None
3347 follow_symlinks: bool = True
3348
3349Create a hard link to a file.
3350
3351If either src_dir_fd or dst_dir_fd is not None, it should be a file
3352 descriptor open to a directory, and the respective path string (src or dst)
3353 should be relative; the path will then be relative to that directory.
3354If follow_symlinks is False, and the last element of src is a symbolic
3355 link, link will create a link to the symbolic link itself instead of the
3356 file the link points to.
3357src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3358 platform. If they are unavailable, using them will raise a
3359 NotImplementedError.
3360[clinic start generated code]*/
3361
Larry Hastings2f936352014-08-05 14:04:04 +10003362static PyObject *
3363os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003364/*[clinic end generated code: output=c0a9ded8111d2a79 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003365{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003366#ifdef MS_WINDOWS
3367 BOOL result;
3368#else
3369 int result;
3370#endif
3371
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372#ifndef HAVE_LINKAT
3373 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3374 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003375 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376 }
3377#endif
3378
Larry Hastings2f936352014-08-05 14:04:04 +10003379 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003380 PyErr_SetString(PyExc_NotImplementedError,
3381 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003382 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003384
Brian Curtin1b9df392010-11-24 20:24:31 +00003385#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003387 if (src->wide)
3388 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 else
Larry Hastings2f936352014-08-05 14:04:04 +10003390 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003392
Larry Hastings2f936352014-08-05 14:04:04 +10003393 if (!result)
3394 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395#else
3396 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003397#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3399 (dst_dir_fd != DEFAULT_DIR_FD) ||
3400 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003401 result = linkat(src_dir_fd, src->narrow,
3402 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3404 else
3405#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003406 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003408
Larry Hastings2f936352014-08-05 14:04:04 +10003409 if (result)
3410 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411#endif
3412
Larry Hastings2f936352014-08-05 14:04:04 +10003413 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003414}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415#endif
3416
Brian Curtin1b9df392010-11-24 20:24:31 +00003417
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003418#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003419static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003420_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 PyObject *v;
3423 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3424 BOOL result;
3425 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003426 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 char *bufptr = namebuf;
3428 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003429 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 PyObject *po = NULL;
3431 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432
Gregory P. Smith40a21602013-03-20 20:52:50 -07003433 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003436
Gregory P. Smith40a21602013-03-20 20:52:50 -07003437 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003438 po_wchars = L".";
3439 len = 1;
3440 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003441 po_wchars = path->wide;
3442 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003443 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003445 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 if (!wnamebuf) {
3447 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003450 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003452 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003453 if (wch != SEP && wch != ALTSEP && wch != L':')
3454 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 wcscpy(wnamebuf + len, L"*.*");
3456 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 if ((list = PyList_New(0)) == NULL) {
3458 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003460 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003462 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 if (hFindFile == INVALID_HANDLE_VALUE) {
3464 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 if (error == ERROR_FILE_NOT_FOUND)
3466 goto exit;
3467 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003468 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
3471 do {
3472 /* Skip over . and .. */
3473 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3474 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 v = PyUnicode_FromWideChar(wFileData.cFileName,
3476 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 Py_DECREF(list);
3479 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 break;
3481 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 Py_DECREF(list);
3485 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 break;
3487 }
3488 Py_DECREF(v);
3489 }
3490 Py_BEGIN_ALLOW_THREADS
3491 result = FindNextFileW(hFindFile, &wFileData);
3492 Py_END_ALLOW_THREADS
3493 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3494 it got to the end of the directory. */
3495 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003497 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 }
3500 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003501
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003504 strcpy(namebuf, path->narrow);
3505 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 if (len > 0) {
3507 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003508 if (ch != '\\' && ch != '/' && ch != ':')
3509 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 strcpy(namebuf + len, "*.*");
3511 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003512
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003515
Antoine Pitroub73caab2010-08-09 23:39:31 +00003516 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003518 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 if (hFindFile == INVALID_HANDLE_VALUE) {
3520 int error = GetLastError();
3521 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 goto exit;
3523 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003524 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 }
3527 do {
3528 /* Skip over . and .. */
3529 if (strcmp(FileData.cFileName, ".") != 0 &&
3530 strcmp(FileData.cFileName, "..") != 0) {
3531 v = PyBytes_FromString(FileData.cFileName);
3532 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 Py_DECREF(list);
3534 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 break;
3536 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 Py_DECREF(list);
3540 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 break;
3542 }
3543 Py_DECREF(v);
3544 }
3545 Py_BEGIN_ALLOW_THREADS
3546 result = FindNextFile(hFindFile, &FileData);
3547 Py_END_ALLOW_THREADS
3548 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3549 it got to the end of the directory. */
3550 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003552 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 }
3555 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003556
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557exit:
3558 if (hFindFile != INVALID_HANDLE_VALUE) {
3559 if (FindClose(hFindFile) == FALSE) {
3560 if (list != NULL) {
3561 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003562 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 }
3564 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003566 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003567
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003569} /* end of _listdir_windows_no_opendir */
3570
3571#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3572
3573static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003574_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003575{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003576 PyObject *v;
3577 DIR *dirp = NULL;
3578 struct dirent *ep;
3579 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003580#ifdef HAVE_FDOPENDIR
3581 int fd = -1;
3582#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003583
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003586 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003588 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003589 if (fd == -1)
3590 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591
Larry Hastingsfdaea062012-06-25 04:42:23 -07003592 return_str = 1;
3593
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 Py_BEGIN_ALLOW_THREADS
3595 dirp = fdopendir(fd);
3596 Py_END_ALLOW_THREADS
3597 }
3598 else
3599#endif
3600 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003601 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003602 if (path->narrow) {
3603 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003604 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003605 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003606 }
3607 else {
3608 name = ".";
3609 return_str = 1;
3610 }
3611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 Py_BEGIN_ALLOW_THREADS
3613 dirp = opendir(name);
3614 Py_END_ALLOW_THREADS
3615 }
3616
3617 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003618 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003619#ifdef HAVE_FDOPENDIR
3620 if (fd != -1) {
3621 Py_BEGIN_ALLOW_THREADS
3622 close(fd);
3623 Py_END_ALLOW_THREADS
3624 }
3625#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 goto exit;
3627 }
3628 if ((list = PyList_New(0)) == NULL) {
3629 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 }
3631 for (;;) {
3632 errno = 0;
3633 Py_BEGIN_ALLOW_THREADS
3634 ep = readdir(dirp);
3635 Py_END_ALLOW_THREADS
3636 if (ep == NULL) {
3637 if (errno == 0) {
3638 break;
3639 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 }
3644 }
3645 if (ep->d_name[0] == '.' &&
3646 (NAMLEN(ep) == 1 ||
3647 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3648 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003649 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003650 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3651 else
3652 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 break;
3656 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 break;
3661 }
3662 Py_DECREF(v);
3663 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003664
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665exit:
3666 if (dirp != NULL) {
3667 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003668#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 if (fd > -1)
3670 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003671#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 closedir(dirp);
3673 Py_END_ALLOW_THREADS
3674 }
3675
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003677} /* end of _posix_listdir */
3678#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003679
Larry Hastings2f936352014-08-05 14:04:04 +10003680
3681/*[clinic input]
3682os.listdir
3683
3684 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3685
3686Return a list containing the names of the files in the directory.
3687
3688path can be specified as either str or bytes. If path is bytes,
3689 the filenames returned will also be bytes; in all other circumstances
3690 the filenames returned will be str.
3691If path is None, uses the path='.'.
3692On some platforms, path may also be specified as an open file descriptor;\
3693 the file descriptor must refer to a directory.
3694 If this functionality is unavailable, using it raises NotImplementedError.
3695
3696The list is in arbitrary order. It does not include the special
3697entries '.' and '..' even if they are present in the directory.
3698
3699
3700[clinic start generated code]*/
3701
Larry Hastings2f936352014-08-05 14:04:04 +10003702static PyObject *
3703os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003704/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003705{
3706#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3707 return _listdir_windows_no_opendir(path, NULL);
3708#else
3709 return _posix_listdir(path, NULL);
3710#endif
3711}
3712
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003713#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003714/* A helper function for abspath on win32 */
Larry Hastings2f936352014-08-05 14:04:04 +10003715/* AC 3.5: probably just convert to using path converter */
Mark Hammondef8b6542001-05-13 08:04:26 +00003716static PyObject *
3717posix__getfullpathname(PyObject *self, PyObject *args)
3718{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003719 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003720 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003721 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003722 PyObject *po;
3723
3724 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3725 {
3726 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003727 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003728 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 DWORD result;
3730 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731
3732 wpath = PyUnicode_AsUnicode(po);
3733 if (wpath == NULL)
3734 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003735 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003736 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003737 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003738 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003739 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 if (!woutbufp)
3741 return PyErr_NoMemory();
3742 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3743 }
3744 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003745 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003746 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003747 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003749 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 return v;
3751 }
3752 /* Drop the argument parsing error as narrow strings
3753 are also valid. */
3754 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003755
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003756 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3757 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003759 if (win32_warn_bytes_api())
3760 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003761 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 outbuf, &temp)) {
3763 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 return NULL;
3765 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3767 return PyUnicode_Decode(outbuf, strlen(outbuf),
3768 Py_FileSystemDefaultEncoding, NULL);
3769 }
3770 return PyBytes_FromString(outbuf);
Larry Hastings2f936352014-08-05 14:04:04 +10003771}
Brian Curtind40e6f72010-07-08 21:39:08 +00003772
Brian Curtind25aef52011-06-13 15:16:04 -05003773
Larry Hastings2f936352014-08-05 14:04:04 +10003774/*[clinic input]
3775os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003776
Larry Hastings2f936352014-08-05 14:04:04 +10003777 path: unicode
3778 /
3779
3780A helper function for samepath on windows.
3781[clinic start generated code]*/
3782
Larry Hastings2f936352014-08-05 14:04:04 +10003783static PyObject *
3784os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003785/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003786{
3787 HANDLE hFile;
3788 int buf_size;
3789 wchar_t *target_path;
3790 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003791 PyObject *result;
3792 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003793
Larry Hastings2f936352014-08-05 14:04:04 +10003794 path_wchar = PyUnicode_AsUnicode(path);
3795 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003796 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003797
Brian Curtind40e6f72010-07-08 21:39:08 +00003798 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003799 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003800 0, /* desired access */
3801 0, /* share mode */
3802 NULL, /* security attributes */
3803 OPEN_EXISTING,
3804 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3805 FILE_FLAG_BACKUP_SEMANTICS,
3806 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003807
Victor Stinnereb5657a2011-09-30 01:44:27 +02003808 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003809 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003810
3811 /* We have a good handle to the target, use it to determine the
3812 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003813 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003814
3815 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003816 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003817
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003818 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003819 if(!target_path)
3820 return PyErr_NoMemory();
3821
Steve Dower2ea51c92015-03-20 21:49:12 -07003822 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3823 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003824 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003825 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003826
3827 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003828 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
3830 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003831 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003832 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003833 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003834}
Brian Curtin62857742010-09-06 17:07:27 +00003835
Brian Curtin95d028f2011-06-09 09:10:38 -05003836PyDoc_STRVAR(posix__isdir__doc__,
3837"Return true if the pathname refers to an existing directory.");
3838
Larry Hastings2f936352014-08-05 14:04:04 +10003839/* AC 3.5: convert using path converter */
Brian Curtin9c669cc2011-06-08 18:17:18 -05003840static PyObject *
3841posix__isdir(PyObject *self, PyObject *args)
3842{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003843 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003844 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003845 DWORD attributes;
3846
3847 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003848 wchar_t *wpath = PyUnicode_AsUnicode(po);
3849 if (wpath == NULL)
3850 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003851
3852 attributes = GetFileAttributesW(wpath);
3853 if (attributes == INVALID_FILE_ATTRIBUTES)
3854 Py_RETURN_FALSE;
3855 goto check;
3856 }
3857 /* Drop the argument parsing error as narrow strings
3858 are also valid. */
3859 PyErr_Clear();
3860
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003861 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003862 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003863 if (win32_warn_bytes_api())
3864 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003865 attributes = GetFileAttributesA(path);
3866 if (attributes == INVALID_FILE_ATTRIBUTES)
3867 Py_RETURN_FALSE;
3868
3869check:
3870 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3871 Py_RETURN_TRUE;
3872 else
3873 Py_RETURN_FALSE;
3874}
Tim Golden6b528062013-08-01 12:44:00 +01003875
Tim Golden6b528062013-08-01 12:44:00 +01003876
Larry Hastings2f936352014-08-05 14:04:04 +10003877/*[clinic input]
3878os._getvolumepathname
3879
3880 path: unicode
3881
3882A helper function for ismount on Win32.
3883[clinic start generated code]*/
3884
Larry Hastings2f936352014-08-05 14:04:04 +10003885static PyObject *
3886os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003887/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003888{
3889 PyObject *result;
3890 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003891 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003892 BOOL ret;
3893
Larry Hastings2f936352014-08-05 14:04:04 +10003894 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3895 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003896 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003897 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003898
3899 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003900 buflen = Py_MAX(buflen, MAX_PATH);
3901
3902 if (buflen > DWORD_MAX) {
3903 PyErr_SetString(PyExc_OverflowError, "path too long");
3904 return NULL;
3905 }
3906
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003907 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003908 if (mountpath == NULL)
3909 return PyErr_NoMemory();
3910
3911 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003912 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003913 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003914 Py_END_ALLOW_THREADS
3915
3916 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003917 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003918 goto exit;
3919 }
3920 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3921
3922exit:
3923 PyMem_Free(mountpath);
3924 return result;
3925}
Tim Golden6b528062013-08-01 12:44:00 +01003926
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003927#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003928
Larry Hastings2f936352014-08-05 14:04:04 +10003929
3930/*[clinic input]
3931os.mkdir
3932
3933 path : path_t
3934
3935 mode: int = 0o777
3936
3937 *
3938
3939 dir_fd : dir_fd(requires='mkdirat') = None
3940
3941# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3942
3943Create a directory.
3944
3945If dir_fd is not None, it should be a file descriptor open to a directory,
3946 and path should be relative; path will then be relative to that directory.
3947dir_fd may not be implemented on your platform.
3948 If it is unavailable, using it will raise a NotImplementedError.
3949
3950The mode argument is ignored on Windows.
3951[clinic start generated code]*/
3952
Larry Hastings2f936352014-08-05 14:04:04 +10003953static PyObject *
3954os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003955/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003956{
3957 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003958
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003961 if (path->wide)
3962 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003963 else
Larry Hastings2f936352014-08-05 14:04:04 +10003964 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966
Larry Hastings2f936352014-08-05 14:04:04 +10003967 if (!result)
3968 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003971#if HAVE_MKDIRAT
3972 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003973 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 else
3975#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003976#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003977 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003978#else
Larry Hastings2f936352014-08-05 14:04:04 +10003979 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003980#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003982 if (result < 0)
3983 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003984#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003985 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003986}
3987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003988
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003989/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3990#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003991#include <sys/resource.h>
3992#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003993
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003994
3995#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003996/*[clinic input]
3997os.nice
3998
3999 increment: int
4000 /
4001
4002Add increment to the priority of process and return the new priority.
4003[clinic start generated code]*/
4004
Larry Hastings2f936352014-08-05 14:04:04 +10004005static PyObject *
4006os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004007/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004008{
4009 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004010
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 /* There are two flavours of 'nice': one that returns the new
4012 priority (as required by almost all standards out there) and the
4013 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4014 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004015
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 If we are of the nice family that returns the new priority, we
4017 need to clear errno before the call, and check if errno is filled
4018 before calling posix_error() on a returnvalue of -1, because the
4019 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004020
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 errno = 0;
4022 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004023#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 if (value == 0)
4025 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004026#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004027 if (value == -1 && errno != 0)
4028 /* either nice() or getpriority() returned an error */
4029 return posix_error();
4030 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004031}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004032#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004033
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004034
4035#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004036/*[clinic input]
4037os.getpriority
4038
4039 which: int
4040 who: int
4041
4042Return program scheduling priority.
4043[clinic start generated code]*/
4044
Larry Hastings2f936352014-08-05 14:04:04 +10004045static PyObject *
4046os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004047/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004048{
4049 int retval;
4050
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004051 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004052 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004053 if (errno != 0)
4054 return posix_error();
4055 return PyLong_FromLong((long)retval);
4056}
4057#endif /* HAVE_GETPRIORITY */
4058
4059
4060#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004061/*[clinic input]
4062os.setpriority
4063
4064 which: int
4065 who: int
4066 priority: int
4067
4068Set program scheduling priority.
4069[clinic start generated code]*/
4070
Larry Hastings2f936352014-08-05 14:04:04 +10004071static PyObject *
4072os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004073/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004074{
4075 int retval;
4076
4077 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004078 if (retval == -1)
4079 return posix_error();
4080 Py_RETURN_NONE;
4081}
4082#endif /* HAVE_SETPRIORITY */
4083
4084
Barry Warsaw53699e91996-12-10 23:23:01 +00004085static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004086internal_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 +00004087{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004091#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004093 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004094#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004096#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097
Larry Hastings9cf065c2012-06-22 16:30:09 -07004098 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4099 (dst_dir_fd != DEFAULT_DIR_FD);
4100#ifndef HAVE_RENAMEAT
4101 if (dir_fd_specified) {
4102 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004103 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 }
4105#endif
4106
Larry Hastings2f936352014-08-05 14:04:04 +10004107 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108 PyErr_Format(PyExc_ValueError,
4109 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004110 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 }
4112
4113#ifdef MS_WINDOWS
4114 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004115 if (src->wide)
4116 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004117 else
Larry Hastings2f936352014-08-05 14:04:04 +10004118 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 Py_END_ALLOW_THREADS
4120
Larry Hastings2f936352014-08-05 14:04:04 +10004121 if (!result)
4122 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123
4124#else
4125 Py_BEGIN_ALLOW_THREADS
4126#ifdef HAVE_RENAMEAT
4127 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004128 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 else
4130#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004131 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132 Py_END_ALLOW_THREADS
4133
Larry Hastings2f936352014-08-05 14:04:04 +10004134 if (result)
4135 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004137 Py_RETURN_NONE;
4138}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004139
Larry Hastings2f936352014-08-05 14:04:04 +10004140
4141/*[clinic input]
4142os.rename
4143
4144 src : path_t
4145 dst : path_t
4146 *
4147 src_dir_fd : dir_fd = None
4148 dst_dir_fd : dir_fd = None
4149
4150Rename a file or directory.
4151
4152If either src_dir_fd or dst_dir_fd is not None, it should be a file
4153 descriptor open to a directory, and the respective path string (src or dst)
4154 should be relative; the path will then be relative to that directory.
4155src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4156 If they are unavailable, using them will raise a NotImplementedError.
4157[clinic start generated code]*/
4158
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004159static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004160os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004161/*[clinic end generated code: output=1bb520bf2fad186d input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004162{
Larry Hastings2f936352014-08-05 14:04:04 +10004163 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004164}
4165
Larry Hastings2f936352014-08-05 14:04:04 +10004166
4167/*[clinic input]
4168os.replace = os.rename
4169
4170Rename a file or directory, overwriting the destination.
4171
4172If either src_dir_fd or dst_dir_fd is not None, it should be a file
4173 descriptor open to a directory, and the respective path string (src or dst)
4174 should be relative; the path will then be relative to that directory.
4175src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4176 If they are unavailable, using them will raise a NotImplementedError."
4177[clinic start generated code]*/
4178
Larry Hastings2f936352014-08-05 14:04:04 +10004179static PyObject *
4180os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004181/*[clinic end generated code: output=aa9ddad55fdef8e3 input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004182{
4183 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4184}
4185
4186
4187/*[clinic input]
4188os.rmdir
4189
4190 path: path_t
4191 *
4192 dir_fd: dir_fd(requires='unlinkat') = None
4193
4194Remove a directory.
4195
4196If dir_fd is not None, it should be a file descriptor open to a directory,
4197 and path should be relative; path will then be relative to that directory.
4198dir_fd may not be implemented on your platform.
4199 If it is unavailable, using it will raise a NotImplementedError.
4200[clinic start generated code]*/
4201
Larry Hastings2f936352014-08-05 14:04:04 +10004202static PyObject *
4203os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004204/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004205{
4206 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004207
4208 Py_BEGIN_ALLOW_THREADS
4209#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004210 if (path->wide)
4211 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004212 else
Larry Hastings2f936352014-08-05 14:04:04 +10004213 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004214 result = !result; /* Windows, success=1, UNIX, success=0 */
4215#else
4216#ifdef HAVE_UNLINKAT
4217 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004218 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004219 else
4220#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004221 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004222#endif
4223 Py_END_ALLOW_THREADS
4224
Larry Hastings2f936352014-08-05 14:04:04 +10004225 if (result)
4226 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004227
Larry Hastings2f936352014-08-05 14:04:04 +10004228 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004229}
4230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004231
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004232#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004233#ifdef MS_WINDOWS
4234/*[clinic input]
4235os.system -> long
4236
4237 command: Py_UNICODE
4238
4239Execute the command in a subshell.
4240[clinic start generated code]*/
4241
Larry Hastings2f936352014-08-05 14:04:04 +10004242static long
4243os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004244/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004245{
4246 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004248 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004250 return result;
4251}
4252#else /* MS_WINDOWS */
4253/*[clinic input]
4254os.system -> long
4255
4256 command: FSConverter
4257
4258Execute the command in a subshell.
4259[clinic start generated code]*/
4260
Larry Hastings2f936352014-08-05 14:04:04 +10004261static long
4262os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004263/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004264{
4265 long result;
4266 char *bytes = PyBytes_AsString(command);
4267 Py_BEGIN_ALLOW_THREADS
4268 result = system(bytes);
4269 Py_END_ALLOW_THREADS
4270 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004271}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004272#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004273#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Larry Hastings2f936352014-08-05 14:04:04 +10004276/*[clinic input]
4277os.umask
4278
4279 mask: int
4280 /
4281
4282Set the current numeric umask and return the previous umask.
4283[clinic start generated code]*/
4284
Larry Hastings2f936352014-08-05 14:04:04 +10004285static PyObject *
4286os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004287/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004288{
4289 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004290 if (i < 0)
4291 return posix_error();
4292 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004293}
4294
Brian Curtind40e6f72010-07-08 21:39:08 +00004295#ifdef MS_WINDOWS
4296
4297/* override the default DeleteFileW behavior so that directory
4298symlinks can be removed with this function, the same as with
4299Unix symlinks */
4300BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4301{
4302 WIN32_FILE_ATTRIBUTE_DATA info;
4303 WIN32_FIND_DATAW find_data;
4304 HANDLE find_data_handle;
4305 int is_directory = 0;
4306 int is_link = 0;
4307
4308 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4309 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004310
Brian Curtind40e6f72010-07-08 21:39:08 +00004311 /* Get WIN32_FIND_DATA structure for the path to determine if
4312 it is a symlink */
4313 if(is_directory &&
4314 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4315 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4316
4317 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004318 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4319 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4320 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4321 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004322 FindClose(find_data_handle);
4323 }
4324 }
4325 }
4326
4327 if (is_directory && is_link)
4328 return RemoveDirectoryW(lpFileName);
4329
4330 return DeleteFileW(lpFileName);
4331}
4332#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004334
Larry Hastings2f936352014-08-05 14:04:04 +10004335/*[clinic input]
4336os.unlink
4337
4338 path: path_t
4339 *
4340 dir_fd: dir_fd(requires='unlinkat')=None
4341
4342Remove a file (same as remove()).
4343
4344If dir_fd is not None, it should be a file descriptor open to a directory,
4345 and path should be relative; path will then be relative to that directory.
4346dir_fd may not be implemented on your platform.
4347 If it is unavailable, using it will raise a NotImplementedError.
4348
4349[clinic start generated code]*/
4350
Larry Hastings2f936352014-08-05 14:04:04 +10004351static PyObject *
4352os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004353/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004354{
4355 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004356
4357 Py_BEGIN_ALLOW_THREADS
4358#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004359 if (path->wide)
4360 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004361 else
Larry Hastings2f936352014-08-05 14:04:04 +10004362 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363 result = !result; /* Windows, success=1, UNIX, success=0 */
4364#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365#ifdef HAVE_UNLINKAT
4366 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004367 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 else
4369#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004370 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004371#endif
4372 Py_END_ALLOW_THREADS
4373
Larry Hastings2f936352014-08-05 14:04:04 +10004374 if (result)
4375 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376
Larry Hastings2f936352014-08-05 14:04:04 +10004377 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004378}
4379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004380
Larry Hastings2f936352014-08-05 14:04:04 +10004381/*[clinic input]
4382os.remove = os.unlink
4383
4384Remove a file (same as unlink()).
4385
4386If dir_fd is not None, it should be a file descriptor open to a directory,
4387 and path should be relative; path will then be relative to that directory.
4388dir_fd may not be implemented on your platform.
4389 If it is unavailable, using it will raise a NotImplementedError.
4390[clinic start generated code]*/
4391
Larry Hastings2f936352014-08-05 14:04:04 +10004392static PyObject *
4393os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004394/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004395{
4396 return os_unlink_impl(module, path, dir_fd);
4397}
4398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004399
Larry Hastings605a62d2012-06-24 04:33:36 -07004400static PyStructSequence_Field uname_result_fields[] = {
4401 {"sysname", "operating system name"},
4402 {"nodename", "name of machine on network (implementation-defined)"},
4403 {"release", "operating system release"},
4404 {"version", "operating system version"},
4405 {"machine", "hardware identifier"},
4406 {NULL}
4407};
4408
4409PyDoc_STRVAR(uname_result__doc__,
4410"uname_result: Result from os.uname().\n\n\
4411This object may be accessed either as a tuple of\n\
4412 (sysname, nodename, release, version, machine),\n\
4413or via the attributes sysname, nodename, release, version, and machine.\n\
4414\n\
4415See os.uname for more information.");
4416
4417static PyStructSequence_Desc uname_result_desc = {
4418 "uname_result", /* name */
4419 uname_result__doc__, /* doc */
4420 uname_result_fields,
4421 5
4422};
4423
4424static PyTypeObject UnameResultType;
4425
4426
4427#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004428/*[clinic input]
4429os.uname
4430
4431Return an object identifying the current operating system.
4432
4433The object behaves like a named tuple with the following fields:
4434 (sysname, nodename, release, version, machine)
4435
4436[clinic start generated code]*/
4437
Larry Hastings2f936352014-08-05 14:04:04 +10004438static PyObject *
4439os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004440/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004441{
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 struct utsname u;
4443 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004444 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004445
Victor Stinner8c62be82010-05-06 00:08:46 +00004446 Py_BEGIN_ALLOW_THREADS
4447 res = uname(&u);
4448 Py_END_ALLOW_THREADS
4449 if (res < 0)
4450 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004451
4452 value = PyStructSequence_New(&UnameResultType);
4453 if (value == NULL)
4454 return NULL;
4455
4456#define SET(i, field) \
4457 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004458 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004459 if (!o) { \
4460 Py_DECREF(value); \
4461 return NULL; \
4462 } \
4463 PyStructSequence_SET_ITEM(value, i, o); \
4464 } \
4465
4466 SET(0, u.sysname);
4467 SET(1, u.nodename);
4468 SET(2, u.release);
4469 SET(3, u.version);
4470 SET(4, u.machine);
4471
4472#undef SET
4473
4474 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004475}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004476#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004477
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004478
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479
4480typedef struct {
4481 int now;
4482 time_t atime_s;
4483 long atime_ns;
4484 time_t mtime_s;
4485 long mtime_ns;
4486} utime_t;
4487
4488/*
Victor Stinner484df002014-10-09 13:52:31 +02004489 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490 * they also intentionally leak the declaration of a pointer named "time"
4491 */
4492#define UTIME_TO_TIMESPEC \
4493 struct timespec ts[2]; \
4494 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004495 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496 time = NULL; \
4497 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004498 ts[0].tv_sec = ut->atime_s; \
4499 ts[0].tv_nsec = ut->atime_ns; \
4500 ts[1].tv_sec = ut->mtime_s; \
4501 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502 time = ts; \
4503 } \
4504
4505#define UTIME_TO_TIMEVAL \
4506 struct timeval tv[2]; \
4507 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004508 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509 time = NULL; \
4510 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004511 tv[0].tv_sec = ut->atime_s; \
4512 tv[0].tv_usec = ut->atime_ns / 1000; \
4513 tv[1].tv_sec = ut->mtime_s; \
4514 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515 time = tv; \
4516 } \
4517
4518#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004519 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004521 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522 time = NULL; \
4523 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004524 u.actime = ut->atime_s; \
4525 u.modtime = ut->mtime_s; \
4526 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 }
4528
4529#define UTIME_TO_TIME_T \
4530 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004531 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004532 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533 time = NULL; \
4534 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004535 timet[0] = ut->atime_s; \
4536 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004537 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 } \
4539
4540
4541#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4542
4543#if UTIME_HAVE_DIR_FD
4544
4545static int
Victor Stinner484df002014-10-09 13:52:31 +02004546utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547{
4548#ifdef HAVE_UTIMENSAT
4549 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4550 UTIME_TO_TIMESPEC;
4551 return utimensat(dir_fd, path, time, flags);
4552#elif defined(HAVE_FUTIMESAT)
4553 UTIME_TO_TIMEVAL;
4554 /*
4555 * follow_symlinks will never be false here;
4556 * we only allow !follow_symlinks and dir_fd together
4557 * if we have utimensat()
4558 */
4559 assert(follow_symlinks);
4560 return futimesat(dir_fd, path, time);
4561#endif
4562}
4563
Larry Hastings2f936352014-08-05 14:04:04 +10004564 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4565#else
4566 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567#endif
4568
4569#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4570
4571#if UTIME_HAVE_FD
4572
4573static int
Victor Stinner484df002014-10-09 13:52:31 +02004574utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575{
4576#ifdef HAVE_FUTIMENS
4577 UTIME_TO_TIMESPEC;
4578 return futimens(fd, time);
4579#else
4580 UTIME_TO_TIMEVAL;
4581 return futimes(fd, time);
4582#endif
4583}
4584
Larry Hastings2f936352014-08-05 14:04:04 +10004585 #define PATH_UTIME_HAVE_FD 1
4586#else
4587 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588#endif
4589
4590
4591#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4592 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4593
4594#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4595
4596static int
Victor Stinner484df002014-10-09 13:52:31 +02004597utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598{
4599#ifdef HAVE_UTIMENSAT
4600 UTIME_TO_TIMESPEC;
4601 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4602#else
4603 UTIME_TO_TIMEVAL;
4604 return lutimes(path, time);
4605#endif
4606}
4607
4608#endif
4609
4610#ifndef MS_WINDOWS
4611
4612static int
Victor Stinner484df002014-10-09 13:52:31 +02004613utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614{
4615#ifdef HAVE_UTIMENSAT
4616 UTIME_TO_TIMESPEC;
4617 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4618#elif defined(HAVE_UTIMES)
4619 UTIME_TO_TIMEVAL;
4620 return utimes(path, time);
4621#elif defined(HAVE_UTIME_H)
4622 UTIME_TO_UTIMBUF;
4623 return utime(path, time);
4624#else
4625 UTIME_TO_TIME_T;
4626 return utime(path, time);
4627#endif
4628}
4629
4630#endif
4631
Larry Hastings76ad59b2012-05-03 00:30:07 -07004632static int
4633split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4634{
4635 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004636 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 divmod = PyNumber_Divmod(py_long, billion);
4638 if (!divmod)
4639 goto exit;
4640 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4641 if ((*s == -1) && PyErr_Occurred())
4642 goto exit;
4643 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004644 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645 goto exit;
4646
4647 result = 1;
4648exit:
4649 Py_XDECREF(divmod);
4650 return result;
4651}
4652
Larry Hastings2f936352014-08-05 14:04:04 +10004653
4654/*[clinic input]
4655os.utime
4656
4657 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4658 times: object = NULL
4659 *
4660 ns: object = NULL
4661 dir_fd: dir_fd(requires='futimensat') = None
4662 follow_symlinks: bool=True
4663
4664# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4665
4666Set the access and modified time of path.
4667
4668path may always be specified as a string.
4669On some platforms, path may also be specified as an open file descriptor.
4670 If this functionality is unavailable, using it raises an exception.
4671
4672If times is not None, it must be a tuple (atime, mtime);
4673 atime and mtime should be expressed as float seconds since the epoch.
4674If ns is not None, it must be a tuple (atime_ns, mtime_ns);
4675 atime_ns and mtime_ns should be expressed as integer nanoseconds
4676 since the epoch.
4677If both times and ns are None, utime uses the current time.
4678Specifying tuples for both times and ns is an error.
4679
4680If dir_fd is not None, it should be a file descriptor open to a directory,
4681 and path should be relative; path will then be relative to that directory.
4682If follow_symlinks is False, and the last element of the path is a symbolic
4683 link, utime will modify the symbolic link itself instead of the file the
4684 link points to.
4685It is an error to use dir_fd or follow_symlinks when specifying path
4686 as an open file descriptor.
4687dir_fd and follow_symlinks may not be available on your platform.
4688 If they are unavailable, using them will raise a NotImplementedError.
4689
4690[clinic start generated code]*/
4691
Larry Hastings2f936352014-08-05 14:04:04 +10004692static PyObject *
4693os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004694/*[clinic end generated code: output=c52d8fd0d1067f0b input=1f18c17d5941aa82]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004695{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696#ifdef MS_WINDOWS
4697 HANDLE hFile;
4698 FILETIME atime, mtime;
4699#else
4700 int result;
4701#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004702
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004704 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004705
Christian Heimesb3c87242013-08-01 00:08:16 +02004706 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004707
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 if (times && (times != Py_None) && ns) {
4709 PyErr_SetString(PyExc_ValueError,
4710 "utime: you may specify either 'times'"
4711 " or 'ns' but not both");
4712 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004713 }
4714
4715 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004716 time_t a_sec, m_sec;
4717 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004718 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 PyErr_SetString(PyExc_TypeError,
4720 "utime: 'times' must be either"
4721 " a tuple of two ints or None");
4722 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004723 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004725 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004726 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004727 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004728 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004730 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004731 utime.atime_s = a_sec;
4732 utime.atime_ns = a_nsec;
4733 utime.mtime_s = m_sec;
4734 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004737 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 PyErr_SetString(PyExc_TypeError,
4739 "utime: 'ns' must be a tuple of two ints");
4740 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004743 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004745 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 &utime.mtime_s, &utime.mtime_ns)) {
4747 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004748 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004749 }
4750 else {
4751 /* times and ns are both None/unspecified. use "now". */
4752 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004753 }
4754
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4756 if (follow_symlinks_specified("utime", follow_symlinks))
4757 goto exit;
4758#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004759
Larry Hastings2f936352014-08-05 14:04:04 +10004760 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4761 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4762 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004764
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765#if !defined(HAVE_UTIMENSAT)
4766 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004767 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 "utime: cannot use dir_fd and follow_symlinks "
4769 "together on this platform");
4770 goto exit;
4771 }
4772#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004773
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004774#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004776 if (path->wide)
4777 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 NULL, OPEN_EXISTING,
4779 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 else
Larry Hastings2f936352014-08-05 14:04:04 +10004781 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 NULL, OPEN_EXISTING,
4783 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784 Py_END_ALLOW_THREADS
4785 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004786 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004788 }
4789
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004791 GetSystemTimeAsFileTime(&mtime);
4792 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004795 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4796 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 }
4798 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4799 /* Avoid putting the file name into the error here,
4800 as that may confuse the user into believing that
4801 something is wrong with the file, when it also
4802 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004803 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004806#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004808
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4810 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004811 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004813#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814
4815#if UTIME_HAVE_DIR_FD
4816 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004817 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 else
4819#endif
4820
4821#if UTIME_HAVE_FD
Larry Hastings2f936352014-08-05 14:04:04 +10004822 if (path->fd != -1)
4823 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 else
4825#endif
4826
Larry Hastings2f936352014-08-05 14:04:04 +10004827 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828
4829 Py_END_ALLOW_THREADS
4830
4831 if (result < 0) {
4832 /* see previous comment about not putting filename in error here */
4833 return_value = posix_error();
4834 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004836
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004837#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838
4839 Py_INCREF(Py_None);
4840 return_value = Py_None;
4841
4842exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843#ifdef MS_WINDOWS
4844 if (hFile != INVALID_HANDLE_VALUE)
4845 CloseHandle(hFile);
4846#endif
4847 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004848}
4849
Guido van Rossum3b066191991-06-04 19:40:25 +00004850/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004851
Larry Hastings2f936352014-08-05 14:04:04 +10004852
4853/*[clinic input]
4854os._exit
4855
4856 status: int
4857
4858Exit to the system with specified status, without normal exit processing.
4859[clinic start generated code]*/
4860
Larry Hastings2f936352014-08-05 14:04:04 +10004861static PyObject *
4862os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004863/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004864{
4865 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004867}
4868
Martin v. Löwis114619e2002-10-07 06:44:21 +00004869#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4870static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004871free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004872{
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 Py_ssize_t i;
4874 for (i = 0; i < count; i++)
4875 PyMem_Free(array[i]);
4876 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004877}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004878
Antoine Pitrou69f71142009-05-24 21:25:49 +00004879static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004880int fsconvert_strdup(PyObject *o, char**out)
4881{
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 PyObject *bytes;
4883 Py_ssize_t size;
4884 if (!PyUnicode_FSConverter(o, &bytes))
4885 return 0;
4886 size = PyBytes_GET_SIZE(bytes);
4887 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004888 if (!*out) {
4889 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004891 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 memcpy(*out, PyBytes_AsString(bytes), size+1);
4893 Py_DECREF(bytes);
4894 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004895}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896#endif
4897
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004899static char**
4900parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4901{
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 char **envlist;
4903 Py_ssize_t i, pos, envc;
4904 PyObject *keys=NULL, *vals=NULL;
4905 PyObject *key, *val, *key2, *val2;
4906 char *p, *k, *v;
4907 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 i = PyMapping_Size(env);
4910 if (i < 0)
4911 return NULL;
4912 envlist = PyMem_NEW(char *, i + 1);
4913 if (envlist == NULL) {
4914 PyErr_NoMemory();
4915 return NULL;
4916 }
4917 envc = 0;
4918 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004919 if (!keys)
4920 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004922 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 goto error;
4924 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4925 PyErr_Format(PyExc_TypeError,
4926 "env.keys() or env.values() is not a list");
4927 goto error;
4928 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 for (pos = 0; pos < i; pos++) {
4931 key = PyList_GetItem(keys, pos);
4932 val = PyList_GetItem(vals, pos);
4933 if (!key || !val)
4934 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004935
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 if (PyUnicode_FSConverter(key, &key2) == 0)
4937 goto error;
4938 if (PyUnicode_FSConverter(val, &val2) == 0) {
4939 Py_DECREF(key2);
4940 goto error;
4941 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 k = PyBytes_AsString(key2);
4944 v = PyBytes_AsString(val2);
4945 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004946
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 p = PyMem_NEW(char, len);
4948 if (p == NULL) {
4949 PyErr_NoMemory();
4950 Py_DECREF(key2);
4951 Py_DECREF(val2);
4952 goto error;
4953 }
4954 PyOS_snprintf(p, len, "%s=%s", k, v);
4955 envlist[envc++] = p;
4956 Py_DECREF(key2);
4957 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004958 }
4959 Py_DECREF(vals);
4960 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004961
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 envlist[envc] = 0;
4963 *envc_ptr = envc;
4964 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004965
4966error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 Py_XDECREF(keys);
4968 Py_XDECREF(vals);
4969 while (--envc >= 0)
4970 PyMem_DEL(envlist[envc]);
4971 PyMem_DEL(envlist);
4972 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004973}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004974
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975static char**
4976parse_arglist(PyObject* argv, Py_ssize_t *argc)
4977{
4978 int i;
4979 char **argvlist = PyMem_NEW(char *, *argc+1);
4980 if (argvlist == NULL) {
4981 PyErr_NoMemory();
4982 return NULL;
4983 }
4984 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004985 PyObject* item = PySequence_ITEM(argv, i);
4986 if (item == NULL)
4987 goto fail;
4988 if (!fsconvert_strdup(item, &argvlist[i])) {
4989 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004990 goto fail;
4991 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004992 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993 }
4994 argvlist[*argc] = NULL;
4995 return argvlist;
4996fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004997 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998 free_string_array(argvlist, *argc);
4999 return NULL;
5000}
5001#endif
5002
Larry Hastings2f936352014-08-05 14:04:04 +10005003
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005005/*[clinic input]
5006os.execv
5007
5008 path: FSConverter
5009 Path of executable file.
5010 argv: object
5011 Tuple or list of strings.
5012 /
5013
5014Execute an executable path with arguments, replacing current process.
5015[clinic start generated code]*/
5016
Larry Hastings2f936352014-08-05 14:04:04 +10005017static PyObject *
5018os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005019/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005020{
5021 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022 char **argvlist;
5023 Py_ssize_t argc;
5024
5025 /* execv has two arguments: (path, argv), where
5026 argv is a list or tuple of strings. */
5027
Larry Hastings2f936352014-08-05 14:04:04 +10005028 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005029 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5030 PyErr_SetString(PyExc_TypeError,
5031 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032 return NULL;
5033 }
5034 argc = PySequence_Size(argv);
5035 if (argc < 1) {
5036 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005037 return NULL;
5038 }
5039
5040 argvlist = parse_arglist(argv, &argc);
5041 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042 return NULL;
5043 }
5044
Larry Hastings2f936352014-08-05 14:04:04 +10005045 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046
5047 /* If we get here it's definitely an error */
5048
5049 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005050 return posix_error();
5051}
5052
Larry Hastings2f936352014-08-05 14:04:04 +10005053
5054/*[clinic input]
5055os.execve
5056
5057 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5058 Path of executable file.
5059 argv: object
5060 Tuple or list of strings.
5061 env: object
5062 Dictionary of strings mapping to strings.
5063
5064Execute an executable path with arguments, replacing current process.
5065[clinic start generated code]*/
5066
Larry Hastings2f936352014-08-05 14:04:04 +10005067static PyObject *
5068os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005069/*[clinic end generated code: output=7758d4f230d8aac6 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005070{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005071 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 /* execve has three arguments: (path, argv, env), where
5076 argv is a list or tuple of strings and env is a dictionary
5077 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005078
Ross Lagerwall7807c352011-03-17 20:20:30 +02005079 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005081 "execve: argv must be a tuple or list");
5082 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 if (!PyMapping_Check(env)) {
5086 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005087 "execve: environment must be a mapping object");
5088 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005090
Ross Lagerwall7807c352011-03-17 20:20:30 +02005091 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005093 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005095
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 envlist = parse_envlist(env, &envc);
5097 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 goto fail;
5099
Larry Hastings9cf065c2012-06-22 16:30:09 -07005100#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005101 if (path->fd > -1)
5102 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005103 else
5104#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005105 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106
5107 /* If we get here it's definitely an error */
5108
Larry Hastings2f936352014-08-05 14:04:04 +10005109 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110
5111 while (--envc >= 0)
5112 PyMem_DEL(envlist[envc]);
5113 PyMem_DEL(envlist);
5114 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005115 if (argvlist)
5116 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005117 return NULL;
5118}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005119#endif /* HAVE_EXECV */
5120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005121
Guido van Rossuma1065681999-01-25 23:20:23 +00005122#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005123/*[clinic input]
5124os.spawnv
5125
5126 mode: int
5127 Mode of process creation.
5128 path: FSConverter
5129 Path of executable file.
5130 argv: object
5131 Tuple or list of strings.
5132 /
5133
5134Execute the program specified by path in a new process.
5135[clinic start generated code]*/
5136
Larry Hastings2f936352014-08-05 14:04:04 +10005137static PyObject *
5138os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005139/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005140{
5141 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005143 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 Py_ssize_t argc;
5145 Py_intptr_t spawnval;
5146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 /* spawnv has three arguments: (mode, path, argv), where
5149 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005150
Larry Hastings2f936352014-08-05 14:04:04 +10005151 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 if (PyList_Check(argv)) {
5153 argc = PyList_Size(argv);
5154 getitem = PyList_GetItem;
5155 }
5156 else if (PyTuple_Check(argv)) {
5157 argc = PyTuple_Size(argv);
5158 getitem = PyTuple_GetItem;
5159 }
5160 else {
5161 PyErr_SetString(PyExc_TypeError,
5162 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 return NULL;
5164 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005165
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 argvlist = PyMem_NEW(char *, argc+1);
5167 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 return PyErr_NoMemory();
5169 }
5170 for (i = 0; i < argc; i++) {
5171 if (!fsconvert_strdup((*getitem)(argv, i),
5172 &argvlist[i])) {
5173 free_string_array(argvlist, i);
5174 PyErr_SetString(
5175 PyExc_TypeError,
5176 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 return NULL;
5178 }
5179 }
5180 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005181
Victor Stinner8c62be82010-05-06 00:08:46 +00005182 if (mode == _OLD_P_OVERLAY)
5183 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005184
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005186 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005190
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 if (spawnval == -1)
5192 return posix_error();
5193 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005194 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005195}
5196
5197
Larry Hastings2f936352014-08-05 14:04:04 +10005198/*[clinic input]
5199os.spawnve
5200
5201 mode: int
5202 Mode of process creation.
5203 path: FSConverter
5204 Path of executable file.
5205 argv: object
5206 Tuple or list of strings.
5207 env: object
5208 Dictionary of strings mapping to strings.
5209 /
5210
5211Execute the program specified by path in a new process.
5212[clinic start generated code]*/
5213
Larry Hastings2f936352014-08-05 14:04:04 +10005214static PyObject *
5215os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005216/*[clinic end generated code: output=1c52955789461be8 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005217{
5218 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 char **argvlist;
5220 char **envlist;
5221 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005222 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 Py_intptr_t spawnval;
5224 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5225 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005226
Victor Stinner8c62be82010-05-06 00:08:46 +00005227 /* spawnve has four arguments: (mode, path, argv, env), where
5228 argv is a list or tuple of strings and env is a dictionary
5229 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005230
Larry Hastings2f936352014-08-05 14:04:04 +10005231 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 if (PyList_Check(argv)) {
5233 argc = PyList_Size(argv);
5234 getitem = PyList_GetItem;
5235 }
5236 else if (PyTuple_Check(argv)) {
5237 argc = PyTuple_Size(argv);
5238 getitem = PyTuple_GetItem;
5239 }
5240 else {
5241 PyErr_SetString(PyExc_TypeError,
5242 "spawnve() arg 2 must be a tuple or list");
5243 goto fail_0;
5244 }
5245 if (!PyMapping_Check(env)) {
5246 PyErr_SetString(PyExc_TypeError,
5247 "spawnve() arg 3 must be a mapping object");
5248 goto fail_0;
5249 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 argvlist = PyMem_NEW(char *, argc+1);
5252 if (argvlist == NULL) {
5253 PyErr_NoMemory();
5254 goto fail_0;
5255 }
5256 for (i = 0; i < argc; i++) {
5257 if (!fsconvert_strdup((*getitem)(argv, i),
5258 &argvlist[i]))
5259 {
5260 lastarg = i;
5261 goto fail_1;
5262 }
5263 }
5264 lastarg = argc;
5265 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005266
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 envlist = parse_envlist(env, &envc);
5268 if (envlist == NULL)
5269 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005270
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 if (mode == _OLD_P_OVERLAY)
5272 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005275 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005277
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 if (spawnval == -1)
5279 (void) posix_error();
5280 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005281 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005282
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 while (--envc >= 0)
5284 PyMem_DEL(envlist[envc]);
5285 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005286 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005288 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005290}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005291
Guido van Rossuma1065681999-01-25 23:20:23 +00005292#endif /* HAVE_SPAWNV */
5293
5294
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005295#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005296/*[clinic input]
5297os.fork1
5298
5299Fork a child process with a single multiplexed (i.e., not bound) thread.
5300
5301Return 0 to child process and PID of child to parent process.
5302[clinic start generated code]*/
5303
Larry Hastings2f936352014-08-05 14:04:04 +10005304static PyObject *
5305os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005306/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005307{
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 pid_t pid;
5309 int result = 0;
5310 _PyImport_AcquireLock();
5311 pid = fork1();
5312 if (pid == 0) {
5313 /* child: this clobbers and resets the import lock. */
5314 PyOS_AfterFork();
5315 } else {
5316 /* parent: release the import lock. */
5317 result = _PyImport_ReleaseLock();
5318 }
5319 if (pid == -1)
5320 return posix_error();
5321 if (result < 0) {
5322 /* Don't clobber the OSError if the fork failed. */
5323 PyErr_SetString(PyExc_RuntimeError,
5324 "not holding the import lock");
5325 return NULL;
5326 }
5327 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005328}
Larry Hastings2f936352014-08-05 14:04:04 +10005329#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005330
5331
Guido van Rossumad0ee831995-03-01 10:34:45 +00005332#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005333/*[clinic input]
5334os.fork
5335
5336Fork a child process.
5337
5338Return 0 to child process and PID of child to parent process.
5339[clinic start generated code]*/
5340
Larry Hastings2f936352014-08-05 14:04:04 +10005341static PyObject *
5342os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005343/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005344{
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 pid_t pid;
5346 int result = 0;
5347 _PyImport_AcquireLock();
5348 pid = fork();
5349 if (pid == 0) {
5350 /* child: this clobbers and resets the import lock. */
5351 PyOS_AfterFork();
5352 } else {
5353 /* parent: release the import lock. */
5354 result = _PyImport_ReleaseLock();
5355 }
5356 if (pid == -1)
5357 return posix_error();
5358 if (result < 0) {
5359 /* Don't clobber the OSError if the fork failed. */
5360 PyErr_SetString(PyExc_RuntimeError,
5361 "not holding the import lock");
5362 return NULL;
5363 }
5364 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005365}
Larry Hastings2f936352014-08-05 14:04:04 +10005366#endif /* HAVE_FORK */
5367
Guido van Rossum85e3b011991-06-03 12:42:10 +00005368
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005369#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005370#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005371/*[clinic input]
5372os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005373
Larry Hastings2f936352014-08-05 14:04:04 +10005374 policy: int
5375
5376Get the maximum scheduling priority for policy.
5377[clinic start generated code]*/
5378
Larry Hastings2f936352014-08-05 14:04:04 +10005379static PyObject *
5380os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005381/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005382{
5383 int max;
5384
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005385 max = sched_get_priority_max(policy);
5386 if (max < 0)
5387 return posix_error();
5388 return PyLong_FromLong(max);
5389}
5390
Larry Hastings2f936352014-08-05 14:04:04 +10005391
5392/*[clinic input]
5393os.sched_get_priority_min
5394
5395 policy: int
5396
5397Get the minimum scheduling priority for policy.
5398[clinic start generated code]*/
5399
Larry Hastings2f936352014-08-05 14:04:04 +10005400static PyObject *
5401os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005402/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005403{
5404 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005405 if (min < 0)
5406 return posix_error();
5407 return PyLong_FromLong(min);
5408}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005409#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5410
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005411
Larry Hastings2f936352014-08-05 14:04:04 +10005412#ifdef HAVE_SCHED_SETSCHEDULER
5413/*[clinic input]
5414os.sched_getscheduler
5415 pid: pid_t
5416 /
5417
5418Get the scheduling policy for the process identifiedy by pid.
5419
5420Passing 0 for pid returns the scheduling policy for the calling process.
5421[clinic start generated code]*/
5422
Larry Hastings2f936352014-08-05 14:04:04 +10005423static PyObject *
5424os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005425/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005426{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005427 int policy;
5428
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005429 policy = sched_getscheduler(pid);
5430 if (policy < 0)
5431 return posix_error();
5432 return PyLong_FromLong(policy);
5433}
Larry Hastings2f936352014-08-05 14:04:04 +10005434#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005436
5437#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005438/*[clinic input]
5439class os.sched_param "PyObject *" "&SchedParamType"
5440
5441@classmethod
5442os.sched_param.__new__
5443
5444 sched_priority: object
5445 A scheduling parameter.
5446
5447Current has only one field: sched_priority");
5448[clinic start generated code]*/
5449
Larry Hastings2f936352014-08-05 14:04:04 +10005450static PyObject *
5451os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005452/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005453{
5454 PyObject *res;
5455
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456 res = PyStructSequence_New(type);
5457 if (!res)
5458 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005459 Py_INCREF(sched_priority);
5460 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005461 return res;
5462}
5463
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005464
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005465PyDoc_VAR(os_sched_param__doc__);
5466
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005467static PyStructSequence_Field sched_param_fields[] = {
5468 {"sched_priority", "the scheduling priority"},
5469 {0}
5470};
5471
5472static PyStructSequence_Desc sched_param_desc = {
5473 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005474 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475 sched_param_fields,
5476 1
5477};
5478
5479static int
5480convert_sched_param(PyObject *param, struct sched_param *res)
5481{
5482 long priority;
5483
5484 if (Py_TYPE(param) != &SchedParamType) {
5485 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5486 return 0;
5487 }
5488 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5489 if (priority == -1 && PyErr_Occurred())
5490 return 0;
5491 if (priority > INT_MAX || priority < INT_MIN) {
5492 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5493 return 0;
5494 }
5495 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5496 return 1;
5497}
Larry Hastings2f936352014-08-05 14:04:04 +10005498#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005500
5501#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005502/*[clinic input]
5503os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005504
Larry Hastings2f936352014-08-05 14:04:04 +10005505 pid: pid_t
5506 policy: int
5507 param: sched_param
5508 /
5509
5510Set the scheduling policy for the process identified by pid.
5511
5512If pid is 0, the calling process is changed.
5513param is an instance of sched_param.
5514[clinic start generated code]*/
5515
Larry Hastings2f936352014-08-05 14:04:04 +10005516static PyObject *
5517os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005518/*[clinic end generated code: output=97f40f8384e554b0 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005519{
Jesus Cea9c822272011-09-10 01:40:52 +02005520 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005521 ** sched_setscheduler() returns 0 in Linux, but the previous
5522 ** scheduling policy under Solaris/Illumos, and others.
5523 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005524 */
Larry Hastings2f936352014-08-05 14:04:04 +10005525 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005526 return posix_error();
5527 Py_RETURN_NONE;
5528}
Larry Hastings2f936352014-08-05 14:04:04 +10005529#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005530
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005531
5532#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005533/*[clinic input]
5534os.sched_getparam
5535 pid: pid_t
5536 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005537
Larry Hastings2f936352014-08-05 14:04:04 +10005538Returns scheduling parameters for the process identified by pid.
5539
5540If pid is 0, returns parameters for the calling process.
5541Return value is an instance of sched_param.
5542[clinic start generated code]*/
5543
Larry Hastings2f936352014-08-05 14:04:04 +10005544static PyObject *
5545os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005546/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005547{
5548 struct sched_param param;
5549 PyObject *result;
5550 PyObject *priority;
5551
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552 if (sched_getparam(pid, &param))
5553 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005554 result = PyStructSequence_New(&SchedParamType);
5555 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005556 return NULL;
5557 priority = PyLong_FromLong(param.sched_priority);
5558 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005559 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005560 return NULL;
5561 }
Larry Hastings2f936352014-08-05 14:04:04 +10005562 PyStructSequence_SET_ITEM(result, 0, priority);
5563 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005564}
5565
Larry Hastings2f936352014-08-05 14:04:04 +10005566
5567/*[clinic input]
5568os.sched_setparam
5569 pid: pid_t
5570 param: sched_param
5571 /
5572
5573Set scheduling parameters for the process identified by pid.
5574
5575If pid is 0, sets parameters for the calling process.
5576param should be an instance of sched_param.
5577[clinic start generated code]*/
5578
Larry Hastings2f936352014-08-05 14:04:04 +10005579static PyObject *
5580os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005581/*[clinic end generated code: output=c6560b34395bb343 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005582{
5583 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005584 return posix_error();
5585 Py_RETURN_NONE;
5586}
Larry Hastings2f936352014-08-05 14:04:04 +10005587#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005588
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005589
5590#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005591/*[clinic input]
5592os.sched_rr_get_interval -> double
5593 pid: pid_t
5594 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005595
Larry Hastings2f936352014-08-05 14:04:04 +10005596Return the round-robin quantum for the process identified by pid, in seconds.
5597
5598Value returned is a float.
5599[clinic start generated code]*/
5600
Larry Hastings2f936352014-08-05 14:04:04 +10005601static double
5602os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005603/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005604{
5605 struct timespec interval;
5606 if (sched_rr_get_interval(pid, &interval)) {
5607 posix_error();
5608 return -1.0;
5609 }
5610 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5611}
5612#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005613
Larry Hastings2f936352014-08-05 14:04:04 +10005614
5615/*[clinic input]
5616os.sched_yield
5617
5618Voluntarily relinquish the CPU.
5619[clinic start generated code]*/
5620
Larry Hastings2f936352014-08-05 14:04:04 +10005621static PyObject *
5622os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005623/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005624{
5625 if (sched_yield())
5626 return posix_error();
5627 Py_RETURN_NONE;
5628}
5629
Benjamin Peterson2740af82011-08-02 17:41:34 -05005630#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005631/* The minimum number of CPUs allocated in a cpu_set_t */
5632static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005633
Larry Hastings2f936352014-08-05 14:04:04 +10005634/*[clinic input]
5635os.sched_setaffinity
5636 pid: pid_t
5637 mask : object
5638 /
5639
5640Set the CPU affinity of the process identified by pid to mask.
5641
5642mask should be an iterable of integers identifying CPUs.
5643[clinic start generated code]*/
5644
Larry Hastings2f936352014-08-05 14:04:04 +10005645static PyObject *
5646os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005647/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005648{
Antoine Pitrou84869872012-08-04 16:16:35 +02005649 int ncpus;
5650 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005651 cpu_set_t *cpu_set = NULL;
5652 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005653
Larry Hastings2f936352014-08-05 14:04:04 +10005654 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005655 if (iterator == NULL)
5656 return NULL;
5657
5658 ncpus = NCPUS_START;
5659 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005660 cpu_set = CPU_ALLOC(ncpus);
5661 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005662 PyErr_NoMemory();
5663 goto error;
5664 }
Larry Hastings2f936352014-08-05 14:04:04 +10005665 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005666
5667 while ((item = PyIter_Next(iterator))) {
5668 long cpu;
5669 if (!PyLong_Check(item)) {
5670 PyErr_Format(PyExc_TypeError,
5671 "expected an iterator of ints, "
5672 "but iterator yielded %R",
5673 Py_TYPE(item));
5674 Py_DECREF(item);
5675 goto error;
5676 }
5677 cpu = PyLong_AsLong(item);
5678 Py_DECREF(item);
5679 if (cpu < 0) {
5680 if (!PyErr_Occurred())
5681 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5682 goto error;
5683 }
5684 if (cpu > INT_MAX - 1) {
5685 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5686 goto error;
5687 }
5688 if (cpu >= ncpus) {
5689 /* Grow CPU mask to fit the CPU number */
5690 int newncpus = ncpus;
5691 cpu_set_t *newmask;
5692 size_t newsetsize;
5693 while (newncpus <= cpu) {
5694 if (newncpus > INT_MAX / 2)
5695 newncpus = cpu + 1;
5696 else
5697 newncpus = newncpus * 2;
5698 }
5699 newmask = CPU_ALLOC(newncpus);
5700 if (newmask == NULL) {
5701 PyErr_NoMemory();
5702 goto error;
5703 }
5704 newsetsize = CPU_ALLOC_SIZE(newncpus);
5705 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005706 memcpy(newmask, cpu_set, setsize);
5707 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005708 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005709 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005710 ncpus = newncpus;
5711 }
Larry Hastings2f936352014-08-05 14:04:04 +10005712 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005713 }
5714 Py_CLEAR(iterator);
5715
Larry Hastings2f936352014-08-05 14:04:04 +10005716 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005717 posix_error();
5718 goto error;
5719 }
Larry Hastings2f936352014-08-05 14:04:04 +10005720 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005721 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005722
5723error:
Larry Hastings2f936352014-08-05 14:04:04 +10005724 if (cpu_set)
5725 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005726 Py_XDECREF(iterator);
5727 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005728}
5729
Larry Hastings2f936352014-08-05 14:04:04 +10005730
5731/*[clinic input]
5732os.sched_getaffinity
5733 pid: pid_t
5734 /
5735
5736Return the affinity of the process identified by pid.
5737
5738The affinity is returned as a set of CPU identifiers.
5739[clinic start generated code]*/
5740
Larry Hastings2f936352014-08-05 14:04:04 +10005741static PyObject *
5742os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005743/*[clinic end generated code: output=b431a8f310e369e7 input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005744{
Antoine Pitrou84869872012-08-04 16:16:35 +02005745 int cpu, ncpus, count;
5746 size_t setsize;
5747 cpu_set_t *mask = NULL;
5748 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749
Antoine Pitrou84869872012-08-04 16:16:35 +02005750 ncpus = NCPUS_START;
5751 while (1) {
5752 setsize = CPU_ALLOC_SIZE(ncpus);
5753 mask = CPU_ALLOC(ncpus);
5754 if (mask == NULL)
5755 return PyErr_NoMemory();
5756 if (sched_getaffinity(pid, setsize, mask) == 0)
5757 break;
5758 CPU_FREE(mask);
5759 if (errno != EINVAL)
5760 return posix_error();
5761 if (ncpus > INT_MAX / 2) {
5762 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5763 "a large enough CPU set");
5764 return NULL;
5765 }
5766 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005767 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005768
5769 res = PySet_New(NULL);
5770 if (res == NULL)
5771 goto error;
5772 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5773 if (CPU_ISSET_S(cpu, setsize, mask)) {
5774 PyObject *cpu_num = PyLong_FromLong(cpu);
5775 --count;
5776 if (cpu_num == NULL)
5777 goto error;
5778 if (PySet_Add(res, cpu_num)) {
5779 Py_DECREF(cpu_num);
5780 goto error;
5781 }
5782 Py_DECREF(cpu_num);
5783 }
5784 }
5785 CPU_FREE(mask);
5786 return res;
5787
5788error:
5789 if (mask)
5790 CPU_FREE(mask);
5791 Py_XDECREF(res);
5792 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005793}
5794
Benjamin Peterson2740af82011-08-02 17:41:34 -05005795#endif /* HAVE_SCHED_SETAFFINITY */
5796
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797#endif /* HAVE_SCHED_H */
5798
Larry Hastings2f936352014-08-05 14:04:04 +10005799
Neal Norwitzb59798b2003-03-21 01:43:31 +00005800/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005801/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5802#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005803#define DEV_PTY_FILE "/dev/ptc"
5804#define HAVE_DEV_PTMX
5805#else
5806#define DEV_PTY_FILE "/dev/ptmx"
5807#endif
5808
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005809#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005810#ifdef HAVE_PTY_H
5811#include <pty.h>
5812#else
5813#ifdef HAVE_LIBUTIL_H
5814#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005815#else
5816#ifdef HAVE_UTIL_H
5817#include <util.h>
5818#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005819#endif /* HAVE_LIBUTIL_H */
5820#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005821#ifdef HAVE_STROPTS_H
5822#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005823#endif
5824#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005825
Larry Hastings2f936352014-08-05 14:04:04 +10005826
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005827#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005828/*[clinic input]
5829os.openpty
5830
5831Open a pseudo-terminal.
5832
5833Return a tuple of (master_fd, slave_fd) containing open file descriptors
5834for both the master and slave ends.
5835[clinic start generated code]*/
5836
Larry Hastings2f936352014-08-05 14:04:04 +10005837static PyObject *
5838os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005839/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005840{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005841 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005842#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005844#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005845#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005847#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005849#endif
5850#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005851
Thomas Wouters70c21a12000-07-14 14:28:33 +00005852#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005854 goto posix_error;
5855
5856 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5857 goto error;
5858 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5859 goto error;
5860
Neal Norwitzb59798b2003-03-21 01:43:31 +00005861#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005862 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5863 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005864 goto posix_error;
5865 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5866 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005867
Victor Stinnerdaf45552013-08-28 00:53:59 +02005868 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005870 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005871
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005872#else
Victor Stinner000de532013-11-25 23:19:58 +01005873 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005875 goto posix_error;
5876
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005878
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 /* change permission of slave */
5880 if (grantpt(master_fd) < 0) {
5881 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005882 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005884
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 /* unlock slave */
5886 if (unlockpt(master_fd) < 0) {
5887 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005888 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005890
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005892
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 slave_name = ptsname(master_fd); /* get name of slave */
5894 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005895 goto posix_error;
5896
5897 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005898 if (slave_fd == -1)
5899 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005900
5901 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5902 goto posix_error;
5903
Neal Norwitzb59798b2003-03-21 01:43:31 +00005904#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5906 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005907#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005909#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005910#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005911#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005912
Victor Stinner8c62be82010-05-06 00:08:46 +00005913 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005914
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915posix_error:
5916 posix_error();
5917error:
5918 if (master_fd != -1)
5919 close(master_fd);
5920 if (slave_fd != -1)
5921 close(slave_fd);
5922 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005923}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005924#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005925
Larry Hastings2f936352014-08-05 14:04:04 +10005926
Fred Drake8cef4cf2000-06-28 16:40:38 +00005927#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005928/*[clinic input]
5929os.forkpty
5930
5931Fork a new process with a new pseudo-terminal as controlling tty.
5932
5933Returns a tuple of (pid, master_fd).
5934Like fork(), return pid of 0 to the child process,
5935and pid of child to the parent process.
5936To both, return fd of newly opened pseudo-terminal.
5937[clinic start generated code]*/
5938
Larry Hastings2f936352014-08-05 14:04:04 +10005939static PyObject *
5940os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005941/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005942{
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 int master_fd = -1, result = 0;
5944 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005945
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 _PyImport_AcquireLock();
5947 pid = forkpty(&master_fd, NULL, NULL, NULL);
5948 if (pid == 0) {
5949 /* child: this clobbers and resets the import lock. */
5950 PyOS_AfterFork();
5951 } else {
5952 /* parent: release the import lock. */
5953 result = _PyImport_ReleaseLock();
5954 }
5955 if (pid == -1)
5956 return posix_error();
5957 if (result < 0) {
5958 /* Don't clobber the OSError if the fork failed. */
5959 PyErr_SetString(PyExc_RuntimeError,
5960 "not holding the import lock");
5961 return NULL;
5962 }
5963 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005964}
Larry Hastings2f936352014-08-05 14:04:04 +10005965#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005966
Ross Lagerwall7807c352011-03-17 20:20:30 +02005967
Guido van Rossumad0ee831995-03-01 10:34:45 +00005968#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005969/*[clinic input]
5970os.getegid
5971
5972Return the current process's effective group id.
5973[clinic start generated code]*/
5974
Larry Hastings2f936352014-08-05 14:04:04 +10005975static PyObject *
5976os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005977/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005978{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005979 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005980}
Larry Hastings2f936352014-08-05 14:04:04 +10005981#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005983
Guido van Rossumad0ee831995-03-01 10:34:45 +00005984#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005985/*[clinic input]
5986os.geteuid
5987
5988Return the current process's effective user id.
5989[clinic start generated code]*/
5990
Larry Hastings2f936352014-08-05 14:04:04 +10005991static PyObject *
5992os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005993/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005994{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005995 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005996}
Larry Hastings2f936352014-08-05 14:04:04 +10005997#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005999
Guido van Rossumad0ee831995-03-01 10:34:45 +00006000#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006001/*[clinic input]
6002os.getgid
6003
6004Return the current process's group id.
6005[clinic start generated code]*/
6006
Larry Hastings2f936352014-08-05 14:04:04 +10006007static PyObject *
6008os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006009/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006010{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006011 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006012}
Larry Hastings2f936352014-08-05 14:04:04 +10006013#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006015
Larry Hastings2f936352014-08-05 14:04:04 +10006016/*[clinic input]
6017os.getpid
6018
6019Return the current process id.
6020[clinic start generated code]*/
6021
Larry Hastings2f936352014-08-05 14:04:04 +10006022static PyObject *
6023os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006024/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006025{
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006027}
6028
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006029#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006030
6031/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006032PyDoc_STRVAR(posix_getgrouplist__doc__,
6033"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6034Returns a list of groups to which a user belongs.\n\n\
6035 user: username to lookup\n\
6036 group: base group id of the user");
6037
6038static PyObject *
6039posix_getgrouplist(PyObject *self, PyObject *args)
6040{
6041#ifdef NGROUPS_MAX
6042#define MAX_GROUPS NGROUPS_MAX
6043#else
6044 /* defined to be 16 on Solaris7, so this should be a small number */
6045#define MAX_GROUPS 64
6046#endif
6047
6048 const char *user;
6049 int i, ngroups;
6050 PyObject *list;
6051#ifdef __APPLE__
6052 int *groups, basegid;
6053#else
6054 gid_t *groups, basegid;
6055#endif
6056 ngroups = MAX_GROUPS;
6057
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006058#ifdef __APPLE__
6059 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006060 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006061#else
6062 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6063 _Py_Gid_Converter, &basegid))
6064 return NULL;
6065#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006066
6067#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006068 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006069#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006070 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006071#endif
6072 if (groups == NULL)
6073 return PyErr_NoMemory();
6074
6075 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6076 PyMem_Del(groups);
6077 return posix_error();
6078 }
6079
6080 list = PyList_New(ngroups);
6081 if (list == NULL) {
6082 PyMem_Del(groups);
6083 return NULL;
6084 }
6085
6086 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006088 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006089#else
6090 PyObject *o = _PyLong_FromGid(groups[i]);
6091#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006092 if (o == NULL) {
6093 Py_DECREF(list);
6094 PyMem_Del(groups);
6095 return NULL;
6096 }
6097 PyList_SET_ITEM(list, i, o);
6098 }
6099
6100 PyMem_Del(groups);
6101
6102 return list;
6103}
Larry Hastings2f936352014-08-05 14:04:04 +10006104#endif /* HAVE_GETGROUPLIST */
6105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006106
Fred Drakec9680921999-12-13 16:37:25 +00006107#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006108/*[clinic input]
6109os.getgroups
6110
6111Return list of supplemental group IDs for the process.
6112[clinic start generated code]*/
6113
Larry Hastings2f936352014-08-05 14:04:04 +10006114static PyObject *
6115os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006116/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006117{
6118 PyObject *result = NULL;
6119
Fred Drakec9680921999-12-13 16:37:25 +00006120#ifdef NGROUPS_MAX
6121#define MAX_GROUPS NGROUPS_MAX
6122#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006124#define MAX_GROUPS 64
6125#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006127
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006128 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006129 * This is a helper variable to store the intermediate result when
6130 * that happens.
6131 *
6132 * To keep the code readable the OSX behaviour is unconditional,
6133 * according to the POSIX spec this should be safe on all unix-y
6134 * systems.
6135 */
6136 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006138
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006139#ifdef __APPLE__
6140 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6141 * there are more groups than can fit in grouplist. Therefore, on OS X
6142 * always first call getgroups with length 0 to get the actual number
6143 * of groups.
6144 */
6145 n = getgroups(0, NULL);
6146 if (n < 0) {
6147 return posix_error();
6148 } else if (n <= MAX_GROUPS) {
6149 /* groups will fit in existing array */
6150 alt_grouplist = grouplist;
6151 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006152 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006153 if (alt_grouplist == NULL) {
6154 errno = EINVAL;
6155 return posix_error();
6156 }
6157 }
6158
6159 n = getgroups(n, alt_grouplist);
6160 if (n == -1) {
6161 if (alt_grouplist != grouplist) {
6162 PyMem_Free(alt_grouplist);
6163 }
6164 return posix_error();
6165 }
6166#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006168 if (n < 0) {
6169 if (errno == EINVAL) {
6170 n = getgroups(0, NULL);
6171 if (n == -1) {
6172 return posix_error();
6173 }
6174 if (n == 0) {
6175 /* Avoid malloc(0) */
6176 alt_grouplist = grouplist;
6177 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006178 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006179 if (alt_grouplist == NULL) {
6180 errno = EINVAL;
6181 return posix_error();
6182 }
6183 n = getgroups(n, alt_grouplist);
6184 if (n == -1) {
6185 PyMem_Free(alt_grouplist);
6186 return posix_error();
6187 }
6188 }
6189 } else {
6190 return posix_error();
6191 }
6192 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006193#endif
6194
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006195 result = PyList_New(n);
6196 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 int i;
6198 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006199 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006200 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006201 Py_DECREF(result);
6202 result = NULL;
6203 break;
Fred Drakec9680921999-12-13 16:37:25 +00006204 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006206 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006207 }
6208
6209 if (alt_grouplist != grouplist) {
6210 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006212
Fred Drakec9680921999-12-13 16:37:25 +00006213 return result;
6214}
Larry Hastings2f936352014-08-05 14:04:04 +10006215#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006216
Antoine Pitroub7572f02009-12-02 20:46:48 +00006217#ifdef HAVE_INITGROUPS
6218PyDoc_STRVAR(posix_initgroups__doc__,
6219"initgroups(username, gid) -> None\n\n\
6220Call the system initgroups() to initialize the group access list with all of\n\
6221the groups of which the specified username is a member, plus the specified\n\
6222group id.");
6223
Larry Hastings2f936352014-08-05 14:04:04 +10006224/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006225static PyObject *
6226posix_initgroups(PyObject *self, PyObject *args)
6227{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006228 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006230 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006231#ifdef __APPLE__
6232 int gid;
6233#else
6234 gid_t gid;
6235#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006236
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006237#ifdef __APPLE__
6238 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6239 PyUnicode_FSConverter, &oname,
6240 &gid))
6241#else
6242 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6243 PyUnicode_FSConverter, &oname,
6244 _Py_Gid_Converter, &gid))
6245#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006246 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006247 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006248
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006249 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006250 Py_DECREF(oname);
6251 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006253
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 Py_INCREF(Py_None);
6255 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006256}
Larry Hastings2f936352014-08-05 14:04:04 +10006257#endif /* HAVE_INITGROUPS */
6258
Antoine Pitroub7572f02009-12-02 20:46:48 +00006259
Martin v. Löwis606edc12002-06-13 21:09:11 +00006260#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006261/*[clinic input]
6262os.getpgid
6263
6264 pid: pid_t
6265
6266Call the system call getpgid(), and return the result.
6267[clinic start generated code]*/
6268
Larry Hastings2f936352014-08-05 14:04:04 +10006269static PyObject *
6270os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006271/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006272{
6273 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 if (pgid < 0)
6275 return posix_error();
6276 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006277}
6278#endif /* HAVE_GETPGID */
6279
6280
Guido van Rossumb6775db1994-08-01 11:34:53 +00006281#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006282/*[clinic input]
6283os.getpgrp
6284
6285Return the current process group id.
6286[clinic start generated code]*/
6287
Larry Hastings2f936352014-08-05 14:04:04 +10006288static PyObject *
6289os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006290/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006291{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006292#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006294#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006296#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006297}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006298#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006300
Guido van Rossumb6775db1994-08-01 11:34:53 +00006301#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006302/*[clinic input]
6303os.setpgrp
6304
6305Make the current process the leader of its process group.
6306[clinic start generated code]*/
6307
Larry Hastings2f936352014-08-05 14:04:04 +10006308static PyObject *
6309os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006310/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006311{
Guido van Rossum64933891994-10-20 21:56:42 +00006312#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006314#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006316#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 return posix_error();
6318 Py_INCREF(Py_None);
6319 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006320}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#endif /* HAVE_SETPGRP */
6322
Guido van Rossumad0ee831995-03-01 10:34:45 +00006323#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006324
6325#ifdef MS_WINDOWS
6326#include <tlhelp32.h>
6327
6328static PyObject*
6329win32_getppid()
6330{
6331 HANDLE snapshot;
6332 pid_t mypid;
6333 PyObject* result = NULL;
6334 BOOL have_record;
6335 PROCESSENTRY32 pe;
6336
6337 mypid = getpid(); /* This function never fails */
6338
6339 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6340 if (snapshot == INVALID_HANDLE_VALUE)
6341 return PyErr_SetFromWindowsErr(GetLastError());
6342
6343 pe.dwSize = sizeof(pe);
6344 have_record = Process32First(snapshot, &pe);
6345 while (have_record) {
6346 if (mypid == (pid_t)pe.th32ProcessID) {
6347 /* We could cache the ulong value in a static variable. */
6348 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6349 break;
6350 }
6351
6352 have_record = Process32Next(snapshot, &pe);
6353 }
6354
6355 /* If our loop exits and our pid was not found (result will be NULL)
6356 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6357 * error anyway, so let's raise it. */
6358 if (!result)
6359 result = PyErr_SetFromWindowsErr(GetLastError());
6360
6361 CloseHandle(snapshot);
6362
6363 return result;
6364}
6365#endif /*MS_WINDOWS*/
6366
Larry Hastings2f936352014-08-05 14:04:04 +10006367
6368/*[clinic input]
6369os.getppid
6370
6371Return the parent's process id.
6372
6373If the parent process has already exited, Windows machines will still
6374return its id; others systems will return the id of the 'init' process (1).
6375[clinic start generated code]*/
6376
Larry Hastings2f936352014-08-05 14:04:04 +10006377static PyObject *
6378os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006379/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006380{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006381#ifdef MS_WINDOWS
6382 return win32_getppid();
6383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006385#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006386}
6387#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006389
Fred Drake12c6e2d1999-12-14 21:25:03 +00006390#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006391/*[clinic input]
6392os.getlogin
6393
6394Return the actual login name.
6395[clinic start generated code]*/
6396
Larry Hastings2f936352014-08-05 14:04:04 +10006397static PyObject *
6398os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006399/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006400{
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006402#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006403 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006404 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006405
6406 if (GetUserNameW(user_name, &num_chars)) {
6407 /* num_chars is the number of unicode chars plus null terminator */
6408 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006409 }
6410 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006411 result = PyErr_SetFromWindowsErr(GetLastError());
6412#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 char *name;
6414 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006415
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 errno = 0;
6417 name = getlogin();
6418 if (name == NULL) {
6419 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006420 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006421 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006422 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 }
6424 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006425 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006427#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006428 return result;
6429}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006430#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006431
Larry Hastings2f936352014-08-05 14:04:04 +10006432
Guido van Rossumad0ee831995-03-01 10:34:45 +00006433#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006434/*[clinic input]
6435os.getuid
6436
6437Return the current process's user id.
6438[clinic start generated code]*/
6439
Larry Hastings2f936352014-08-05 14:04:04 +10006440static PyObject *
6441os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006442/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006443{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006444 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006445}
Larry Hastings2f936352014-08-05 14:04:04 +10006446#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006448
Brian Curtineb24d742010-04-12 17:16:38 +00006449#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006450#define HAVE_KILL
6451#endif /* MS_WINDOWS */
6452
6453#ifdef HAVE_KILL
6454/*[clinic input]
6455os.kill
6456
6457 pid: pid_t
6458 signal: Py_ssize_t
6459 /
6460
6461Kill a process with a signal.
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
6465os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006466/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006467#ifndef MS_WINDOWS
6468{
6469 if (kill(pid, (int)signal) == -1)
6470 return posix_error();
6471 Py_RETURN_NONE;
6472}
6473#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006474{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006475 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006476 DWORD sig = (DWORD)signal;
6477 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006479
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 /* Console processes which share a common console can be sent CTRL+C or
6481 CTRL+BREAK events, provided they handle said events. */
6482 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006483 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 err = GetLastError();
6485 PyErr_SetFromWindowsErr(err);
6486 }
6487 else
6488 Py_RETURN_NONE;
6489 }
Brian Curtineb24d742010-04-12 17:16:38 +00006490
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6492 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006493 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 if (handle == NULL) {
6495 err = GetLastError();
6496 return PyErr_SetFromWindowsErr(err);
6497 }
Brian Curtineb24d742010-04-12 17:16:38 +00006498
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 if (TerminateProcess(handle, sig) == 0) {
6500 err = GetLastError();
6501 result = PyErr_SetFromWindowsErr(err);
6502 } else {
6503 Py_INCREF(Py_None);
6504 result = Py_None;
6505 }
Brian Curtineb24d742010-04-12 17:16:38 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 CloseHandle(handle);
6508 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006509}
Larry Hastings2f936352014-08-05 14:04:04 +10006510#endif /* !MS_WINDOWS */
6511#endif /* HAVE_KILL */
6512
6513
6514#ifdef HAVE_KILLPG
6515/*[clinic input]
6516os.killpg
6517
6518 pgid: pid_t
6519 signal: int
6520 /
6521
6522Kill a process group with a signal.
6523[clinic start generated code]*/
6524
Larry Hastings2f936352014-08-05 14:04:04 +10006525static PyObject *
6526os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006527/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006528{
6529 /* XXX some man pages make the `pgid` parameter an int, others
6530 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6531 take the same type. Moreover, pid_t is always at least as wide as
6532 int (else compilation of this module fails), which is safe. */
6533 if (killpg(pgid, signal) == -1)
6534 return posix_error();
6535 Py_RETURN_NONE;
6536}
6537#endif /* HAVE_KILLPG */
6538
Brian Curtineb24d742010-04-12 17:16:38 +00006539
Guido van Rossumc0125471996-06-28 18:55:32 +00006540#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006541#ifdef HAVE_SYS_LOCK_H
6542#include <sys/lock.h>
6543#endif
6544
Larry Hastings2f936352014-08-05 14:04:04 +10006545/*[clinic input]
6546os.plock
6547 op: int
6548 /
6549
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006551[clinic start generated code]*/
6552
Larry Hastings2f936352014-08-05 14:04:04 +10006553static PyObject *
6554os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006555/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006556{
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 if (plock(op) == -1)
6558 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006559 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006560}
Larry Hastings2f936352014-08-05 14:04:04 +10006561#endif /* HAVE_PLOCK */
6562
Guido van Rossumc0125471996-06-28 18:55:32 +00006563
Guido van Rossumb6775db1994-08-01 11:34:53 +00006564#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006565/*[clinic input]
6566os.setuid
6567
6568 uid: uid_t
6569 /
6570
6571Set the current process's user id.
6572[clinic start generated code]*/
6573
Larry Hastings2f936352014-08-05 14:04:04 +10006574static PyObject *
6575os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006576/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006577{
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 if (setuid(uid) < 0)
6579 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006580 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006581}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006582#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006584
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006585#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006586/*[clinic input]
6587os.seteuid
6588
6589 euid: uid_t
6590 /
6591
6592Set the current process's effective user id.
6593[clinic start generated code]*/
6594
Larry Hastings2f936352014-08-05 14:04:04 +10006595static PyObject *
6596os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006597/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006598{
6599 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006601 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006602}
6603#endif /* HAVE_SETEUID */
6604
Larry Hastings2f936352014-08-05 14:04:04 +10006605
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006606#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006607/*[clinic input]
6608os.setegid
6609
6610 egid: gid_t
6611 /
6612
6613Set the current process's effective group id.
6614[clinic start generated code]*/
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616static PyObject *
6617os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006618/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006619{
6620 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006622 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006623}
6624#endif /* HAVE_SETEGID */
6625
Larry Hastings2f936352014-08-05 14:04:04 +10006626
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006627#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.setreuid
6630
6631 ruid: uid_t
6632 euid: uid_t
6633 /
6634
6635Set the current process's real and effective user ids.
6636[clinic start generated code]*/
6637
Larry Hastings2f936352014-08-05 14:04:04 +10006638static PyObject *
6639os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006640/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006641{
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 if (setreuid(ruid, euid) < 0) {
6643 return posix_error();
6644 } else {
6645 Py_INCREF(Py_None);
6646 return Py_None;
6647 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006648}
6649#endif /* HAVE_SETREUID */
6650
Larry Hastings2f936352014-08-05 14:04:04 +10006651
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006652#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006653/*[clinic input]
6654os.setregid
6655
6656 rgid: gid_t
6657 egid: gid_t
6658 /
6659
6660Set the current process's real and effective group ids.
6661[clinic start generated code]*/
6662
Larry Hastings2f936352014-08-05 14:04:04 +10006663static PyObject *
6664os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006665/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006666{
6667 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006669 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006670}
6671#endif /* HAVE_SETREGID */
6672
Larry Hastings2f936352014-08-05 14:04:04 +10006673
Guido van Rossumb6775db1994-08-01 11:34:53 +00006674#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006675/*[clinic input]
6676os.setgid
6677 gid: gid_t
6678 /
6679
6680Set the current process's group id.
6681[clinic start generated code]*/
6682
Larry Hastings2f936352014-08-05 14:04:04 +10006683static PyObject *
6684os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006685/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006686{
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 if (setgid(gid) < 0)
6688 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006689 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006690}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006691#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006692
Larry Hastings2f936352014-08-05 14:04:04 +10006693
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006694#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006695/*[clinic input]
6696os.setgroups
6697
6698 groups: object
6699 /
6700
6701Set the groups of the current process to list.
6702[clinic start generated code]*/
6703
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006704static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006705os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006706/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006707{
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 int i, len;
6709 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006710
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 if (!PySequence_Check(groups)) {
6712 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6713 return NULL;
6714 }
6715 len = PySequence_Size(groups);
6716 if (len > MAX_GROUPS) {
6717 PyErr_SetString(PyExc_ValueError, "too many groups");
6718 return NULL;
6719 }
6720 for(i = 0; i < len; i++) {
6721 PyObject *elem;
6722 elem = PySequence_GetItem(groups, i);
6723 if (!elem)
6724 return NULL;
6725 if (!PyLong_Check(elem)) {
6726 PyErr_SetString(PyExc_TypeError,
6727 "groups must be integers");
6728 Py_DECREF(elem);
6729 return NULL;
6730 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006731 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 Py_DECREF(elem);
6733 return NULL;
6734 }
6735 }
6736 Py_DECREF(elem);
6737 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006738
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 if (setgroups(len, grouplist) < 0)
6740 return posix_error();
6741 Py_INCREF(Py_None);
6742 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006743}
6744#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006745
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006746#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6747static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006748wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006749{
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 PyObject *result;
6751 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006752 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006753
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 if (pid == -1)
6755 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006756
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 if (struct_rusage == NULL) {
6758 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6759 if (m == NULL)
6760 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006761 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 Py_DECREF(m);
6763 if (struct_rusage == NULL)
6764 return NULL;
6765 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006766
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6768 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6769 if (!result)
6770 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006771
6772#ifndef doubletime
6773#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6774#endif
6775
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006777 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006779 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006780#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6782 SET_INT(result, 2, ru->ru_maxrss);
6783 SET_INT(result, 3, ru->ru_ixrss);
6784 SET_INT(result, 4, ru->ru_idrss);
6785 SET_INT(result, 5, ru->ru_isrss);
6786 SET_INT(result, 6, ru->ru_minflt);
6787 SET_INT(result, 7, ru->ru_majflt);
6788 SET_INT(result, 8, ru->ru_nswap);
6789 SET_INT(result, 9, ru->ru_inblock);
6790 SET_INT(result, 10, ru->ru_oublock);
6791 SET_INT(result, 11, ru->ru_msgsnd);
6792 SET_INT(result, 12, ru->ru_msgrcv);
6793 SET_INT(result, 13, ru->ru_nsignals);
6794 SET_INT(result, 14, ru->ru_nvcsw);
6795 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006796#undef SET_INT
6797
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 if (PyErr_Occurred()) {
6799 Py_DECREF(result);
6800 return NULL;
6801 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006802
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006804}
6805#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6806
Larry Hastings2f936352014-08-05 14:04:04 +10006807
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006809/*[clinic input]
6810os.wait3
6811
6812 options: int
6813Wait for completion of a child process.
6814
6815Returns a tuple of information about the child process:
6816 (pid, status, rusage)
6817[clinic start generated code]*/
6818
Larry Hastings2f936352014-08-05 14:04:04 +10006819static PyObject *
6820os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006821/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822{
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006825 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 WAIT_TYPE status;
6827 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006829 do {
6830 Py_BEGIN_ALLOW_THREADS
6831 pid = wait3(&status, options, &ru);
6832 Py_END_ALLOW_THREADS
6833 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6834 if (pid < 0)
6835 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836
Victor Stinner4195b5c2012-02-08 23:03:19 +01006837 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838}
6839#endif /* HAVE_WAIT3 */
6840
Larry Hastings2f936352014-08-05 14:04:04 +10006841
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006843/*[clinic input]
6844
6845os.wait4
6846
6847 pid: pid_t
6848 options: int
6849
6850Wait for completion of a specific child process.
6851
6852Returns a tuple of information about the child process:
6853 (pid, status, rusage)
6854[clinic start generated code]*/
6855
Larry Hastings2f936352014-08-05 14:04:04 +10006856static PyObject *
6857os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006858/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006859{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006860 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006862 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 WAIT_TYPE status;
6864 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006866 do {
6867 Py_BEGIN_ALLOW_THREADS
6868 res = wait4(pid, &status, options, &ru);
6869 Py_END_ALLOW_THREADS
6870 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6871 if (res < 0)
6872 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006874 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875}
6876#endif /* HAVE_WAIT4 */
6877
Larry Hastings2f936352014-08-05 14:04:04 +10006878
Ross Lagerwall7807c352011-03-17 20:20:30 +02006879#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006880/*[clinic input]
6881os.waitid
6882
6883 idtype: idtype_t
6884 Must be one of be P_PID, P_PGID or P_ALL.
6885 id: id_t
6886 The id to wait on.
6887 options: int
6888 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6889 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6890 /
6891
6892Returns the result of waiting for a process or processes.
6893
6894Returns either waitid_result or None if WNOHANG is specified and there are
6895no children in a waitable state.
6896[clinic start generated code]*/
6897
Larry Hastings2f936352014-08-05 14:04:04 +10006898static PyObject *
6899os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006900/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006901{
6902 PyObject *result;
6903 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006905 siginfo_t si;
6906 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006907
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006908 do {
6909 Py_BEGIN_ALLOW_THREADS
6910 res = waitid(idtype, id, &si, options);
6911 Py_END_ALLOW_THREADS
6912 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6913 if (res < 0)
6914 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006915
6916 if (si.si_pid == 0)
6917 Py_RETURN_NONE;
6918
6919 result = PyStructSequence_New(&WaitidResultType);
6920 if (!result)
6921 return NULL;
6922
6923 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006924 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006925 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6926 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6927 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6928 if (PyErr_Occurred()) {
6929 Py_DECREF(result);
6930 return NULL;
6931 }
6932
6933 return result;
6934}
Larry Hastings2f936352014-08-05 14:04:04 +10006935#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006936
Larry Hastings2f936352014-08-05 14:04:04 +10006937
6938#if defined(HAVE_WAITPID)
6939/*[clinic input]
6940os.waitpid
6941 pid: pid_t
6942 options: int
6943 /
6944
6945Wait for completion of a given child process.
6946
6947Returns a tuple of information regarding the child process:
6948 (pid, status)
6949
6950The options argument is ignored on Windows.
6951[clinic start generated code]*/
6952
Larry Hastings2f936352014-08-05 14:04:04 +10006953static PyObject *
6954os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006955/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006956{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006957 pid_t res;
6958 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 WAIT_TYPE status;
6960 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006961
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006962 do {
6963 Py_BEGIN_ALLOW_THREADS
6964 res = waitpid(pid, &status, options);
6965 Py_END_ALLOW_THREADS
6966 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6967 if (res < 0)
6968 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006969
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006970 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006971}
Tim Petersab034fa2002-02-01 11:27:43 +00006972#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006973/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006974/*[clinic input]
6975os.waitpid
6976 pid: Py_intptr_t
6977 options: int
6978 /
6979
6980Wait for completion of a given process.
6981
6982Returns a tuple of information regarding the process:
6983 (pid, status << 8)
6984
6985The options argument is ignored on Windows.
6986[clinic start generated code]*/
6987
Larry Hastings2f936352014-08-05 14:04:04 +10006988static PyObject *
6989os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006990/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006991{
6992 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006993 Py_intptr_t res;
6994 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006995
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006996 do {
6997 Py_BEGIN_ALLOW_THREADS
6998 res = _cwait(&status, pid, options);
6999 Py_END_ALLOW_THREADS
7000 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7001 if (res != 0)
7002 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007003
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007005 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007006}
Larry Hastings2f936352014-08-05 14:04:04 +10007007#endif
7008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007009
Guido van Rossumad0ee831995-03-01 10:34:45 +00007010#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007011/*[clinic input]
7012os.wait
7013
7014Wait for completion of a child process.
7015
7016Returns a tuple of information about the child process:
7017 (pid, status)
7018[clinic start generated code]*/
7019
Larry Hastings2f936352014-08-05 14:04:04 +10007020static PyObject *
7021os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007022/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007023{
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007025 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 WAIT_TYPE status;
7027 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007028
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007029 do {
7030 Py_BEGIN_ALLOW_THREADS
7031 pid = wait(&status);
7032 Py_END_ALLOW_THREADS
7033 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7034 if (pid < 0)
7035 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007036
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007038}
Larry Hastings2f936352014-08-05 14:04:04 +10007039#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007041
Larry Hastings9cf065c2012-06-22 16:30:09 -07007042#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7043PyDoc_STRVAR(readlink__doc__,
7044"readlink(path, *, dir_fd=None) -> path\n\n\
7045Return a string representing the path to which the symbolic link points.\n\
7046\n\
7047If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7048 and path should be relative; path will then be relative to that directory.\n\
7049dir_fd may not be implemented on your platform.\n\
7050 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007051#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007052
Guido van Rossumb6775db1994-08-01 11:34:53 +00007053#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007054
Larry Hastings2f936352014-08-05 14:04:04 +10007055/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007056static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007057posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007058{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007059 path_t path;
7060 int dir_fd = DEFAULT_DIR_FD;
7061 char buffer[MAXPATHLEN];
7062 ssize_t length;
7063 PyObject *return_value = NULL;
7064 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007065
Larry Hastings9cf065c2012-06-22 16:30:09 -07007066 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007067 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007068 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7069 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007070 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007072
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007074#ifdef HAVE_READLINKAT
7075 if (dir_fd != DEFAULT_DIR_FD)
7076 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007077 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007078#endif
7079 length = readlink(path.narrow, buffer, sizeof(buffer));
7080 Py_END_ALLOW_THREADS
7081
7082 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007083 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084 goto exit;
7085 }
7086
7087 if (PyUnicode_Check(path.object))
7088 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7089 else
7090 return_value = PyBytes_FromStringAndSize(buffer, length);
7091exit:
7092 path_cleanup(&path);
7093 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007094}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095
Guido van Rossumb6775db1994-08-01 11:34:53 +00007096#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007097
Larry Hastings2f936352014-08-05 14:04:04 +10007098#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7099
7100static PyObject *
7101win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7102{
7103 wchar_t *path;
7104 DWORD n_bytes_returned;
7105 DWORD io_result;
7106 PyObject *po, *result;
7107 int dir_fd;
7108 HANDLE reparse_point_handle;
7109
7110 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7111 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7112 wchar_t *print_name;
7113
7114 static char *keywords[] = {"path", "dir_fd", NULL};
7115
7116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7117 &po,
7118 dir_fd_unavailable, &dir_fd
7119 ))
7120 return NULL;
7121
7122 path = PyUnicode_AsUnicode(po);
7123 if (path == NULL)
7124 return NULL;
7125
7126 /* First get a handle to the reparse point */
7127 Py_BEGIN_ALLOW_THREADS
7128 reparse_point_handle = CreateFileW(
7129 path,
7130 0,
7131 0,
7132 0,
7133 OPEN_EXISTING,
7134 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7135 0);
7136 Py_END_ALLOW_THREADS
7137
7138 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7139 return win32_error_object("readlink", po);
7140
7141 Py_BEGIN_ALLOW_THREADS
7142 /* New call DeviceIoControl to read the reparse point */
7143 io_result = DeviceIoControl(
7144 reparse_point_handle,
7145 FSCTL_GET_REPARSE_POINT,
7146 0, 0, /* in buffer */
7147 target_buffer, sizeof(target_buffer),
7148 &n_bytes_returned,
7149 0 /* we're not using OVERLAPPED_IO */
7150 );
7151 CloseHandle(reparse_point_handle);
7152 Py_END_ALLOW_THREADS
7153
7154 if (io_result==0)
7155 return win32_error_object("readlink", po);
7156
7157 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7158 {
7159 PyErr_SetString(PyExc_ValueError,
7160 "not a symbolic link");
7161 return NULL;
7162 }
7163 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7164 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7165
7166 result = PyUnicode_FromWideChar(print_name,
7167 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7168 return result;
7169}
7170
7171#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7172
7173
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007174
Larry Hastings9cf065c2012-06-22 16:30:09 -07007175#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007176
7177#if defined(MS_WINDOWS)
7178
7179/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7180static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7181static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007182
Larry Hastings9cf065c2012-06-22 16:30:09 -07007183static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007184check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007185{
7186 HINSTANCE hKernel32;
7187 /* only recheck */
7188 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7189 return 1;
7190 hKernel32 = GetModuleHandleW(L"KERNEL32");
7191 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7192 "CreateSymbolicLinkW");
7193 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7194 "CreateSymbolicLinkA");
7195 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7196}
7197
Victor Stinner31b3b922013-06-05 01:49:17 +02007198/* Remove the last portion of the path */
7199static void
7200_dirnameW(WCHAR *path)
7201{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007202 WCHAR *ptr;
7203
7204 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007205 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007206 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007207 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007208 }
7209 *ptr = 0;
7210}
7211
Victor Stinner31b3b922013-06-05 01:49:17 +02007212/* Remove the last portion of the path */
7213static void
7214_dirnameA(char *path)
7215{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007216 char *ptr;
7217
7218 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007219 for(ptr = path + strlen(path); ptr != path; ptr--) {
7220 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007221 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007222 }
7223 *ptr = 0;
7224}
7225
Victor Stinner31b3b922013-06-05 01:49:17 +02007226/* Is this path absolute? */
7227static int
7228_is_absW(const WCHAR *path)
7229{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007230 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7231
7232}
7233
Victor Stinner31b3b922013-06-05 01:49:17 +02007234/* Is this path absolute? */
7235static int
7236_is_absA(const char *path)
7237{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007238 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7239
7240}
7241
Victor Stinner31b3b922013-06-05 01:49:17 +02007242/* join root and rest with a backslash */
7243static void
7244_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7245{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007246 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007247
Victor Stinner31b3b922013-06-05 01:49:17 +02007248 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 wcscpy(dest_path, rest);
7250 return;
7251 }
7252
7253 root_len = wcslen(root);
7254
7255 wcscpy(dest_path, root);
7256 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007257 dest_path[root_len] = L'\\';
7258 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 }
7260 wcscpy(dest_path+root_len, rest);
7261}
7262
Victor Stinner31b3b922013-06-05 01:49:17 +02007263/* join root and rest with a backslash */
7264static void
7265_joinA(char *dest_path, const char *root, const char *rest)
7266{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007267 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268
Victor Stinner31b3b922013-06-05 01:49:17 +02007269 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270 strcpy(dest_path, rest);
7271 return;
7272 }
7273
7274 root_len = strlen(root);
7275
7276 strcpy(dest_path, root);
7277 if(root_len) {
7278 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007279 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007280 }
7281 strcpy(dest_path+root_len, rest);
7282}
7283
Victor Stinner31b3b922013-06-05 01:49:17 +02007284/* Return True if the path at src relative to dest is a directory */
7285static int
7286_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007287{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288 WIN32_FILE_ATTRIBUTE_DATA src_info;
7289 WCHAR dest_parent[MAX_PATH];
7290 WCHAR src_resolved[MAX_PATH] = L"";
7291
7292 /* dest_parent = os.path.dirname(dest) */
7293 wcscpy(dest_parent, dest);
7294 _dirnameW(dest_parent);
7295 /* src_resolved = os.path.join(dest_parent, src) */
7296 _joinW(src_resolved, dest_parent, src);
7297 return (
7298 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7299 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7300 );
7301}
7302
Victor Stinner31b3b922013-06-05 01:49:17 +02007303/* Return True if the path at src relative to dest is a directory */
7304static int
7305_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007306{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007307 WIN32_FILE_ATTRIBUTE_DATA src_info;
7308 char dest_parent[MAX_PATH];
7309 char src_resolved[MAX_PATH] = "";
7310
7311 /* dest_parent = os.path.dirname(dest) */
7312 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007313 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007315 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316 return (
7317 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7318 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7319 );
7320}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007321#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007322
Larry Hastings2f936352014-08-05 14:04:04 +10007323
7324/*[clinic input]
7325os.symlink
7326 src: path_t
7327 dst: path_t
7328 target_is_directory: bool = False
7329 *
7330 dir_fd: dir_fd(requires='symlinkat')=None
7331
7332# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7333
7334Create a symbolic link pointing to src named dst.
7335
7336target_is_directory is required on Windows if the target is to be
7337 interpreted as a directory. (On Windows, symlink requires
7338 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7339 target_is_directory is ignored on non-Windows platforms.
7340
7341If dir_fd is not None, it should be a file descriptor open to a directory,
7342 and path should be relative; path will then be relative to that directory.
7343dir_fd may not be implemented on your platform.
7344 If it is unavailable, using it will raise a NotImplementedError.
7345
7346[clinic start generated code]*/
7347
Larry Hastings2f936352014-08-05 14:04:04 +10007348static PyObject *
7349os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007350/*[clinic end generated code: output=11aa03f278bb2c8a input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007351{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007352#ifdef MS_WINDOWS
7353 DWORD result;
7354#else
7355 int result;
7356#endif
7357
Larry Hastings9cf065c2012-06-22 16:30:09 -07007358#ifdef MS_WINDOWS
7359 if (!check_CreateSymbolicLink()) {
7360 PyErr_SetString(PyExc_NotImplementedError,
7361 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007362 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007363 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007364 if (!win32_can_symlink) {
7365 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007366 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007367 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007368#endif
7369
Larry Hastings2f936352014-08-05 14:04:04 +10007370 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371 PyErr_SetString(PyExc_ValueError,
7372 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007373 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374 }
7375
7376#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007377
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007379 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007380 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007381 target_is_directory |= _check_dirW(src->wide, dst->wide);
7382 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007384 }
7385 else {
7386 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007387 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7388 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007390 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391 Py_END_ALLOW_THREADS
7392
Larry Hastings2f936352014-08-05 14:04:04 +10007393 if (!result)
7394 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395
7396#else
7397
7398 Py_BEGIN_ALLOW_THREADS
7399#if HAVE_SYMLINKAT
7400 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007401 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 else
7403#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007404 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 Py_END_ALLOW_THREADS
7406
Larry Hastings2f936352014-08-05 14:04:04 +10007407 if (result)
7408 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409#endif
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007412}
7413#endif /* HAVE_SYMLINK */
7414
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415
Brian Curtind40e6f72010-07-08 21:39:08 +00007416
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007417
Larry Hastings605a62d2012-06-24 04:33:36 -07007418static PyStructSequence_Field times_result_fields[] = {
7419 {"user", "user time"},
7420 {"system", "system time"},
7421 {"children_user", "user time of children"},
7422 {"children_system", "system time of children"},
7423 {"elapsed", "elapsed time since an arbitrary point in the past"},
7424 {NULL}
7425};
7426
7427PyDoc_STRVAR(times_result__doc__,
7428"times_result: Result from os.times().\n\n\
7429This object may be accessed either as a tuple of\n\
7430 (user, system, children_user, children_system, elapsed),\n\
7431or via the attributes user, system, children_user, children_system,\n\
7432and elapsed.\n\
7433\n\
7434See os.times for more information.");
7435
7436static PyStructSequence_Desc times_result_desc = {
7437 "times_result", /* name */
7438 times_result__doc__, /* doc */
7439 times_result_fields,
7440 5
7441};
7442
7443static PyTypeObject TimesResultType;
7444
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007445#ifdef MS_WINDOWS
7446#define HAVE_TIMES /* mandatory, for the method table */
7447#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007448
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007449#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007450
7451static PyObject *
7452build_times_result(double user, double system,
7453 double children_user, double children_system,
7454 double elapsed)
7455{
7456 PyObject *value = PyStructSequence_New(&TimesResultType);
7457 if (value == NULL)
7458 return NULL;
7459
7460#define SET(i, field) \
7461 { \
7462 PyObject *o = PyFloat_FromDouble(field); \
7463 if (!o) { \
7464 Py_DECREF(value); \
7465 return NULL; \
7466 } \
7467 PyStructSequence_SET_ITEM(value, i, o); \
7468 } \
7469
7470 SET(0, user);
7471 SET(1, system);
7472 SET(2, children_user);
7473 SET(3, children_system);
7474 SET(4, elapsed);
7475
7476#undef SET
7477
7478 return value;
7479}
7480
Larry Hastings605a62d2012-06-24 04:33:36 -07007481
Larry Hastings2f936352014-08-05 14:04:04 +10007482#ifndef MS_WINDOWS
7483#define NEED_TICKS_PER_SECOND
7484static long ticks_per_second = -1;
7485#endif /* MS_WINDOWS */
7486
7487/*[clinic input]
7488os.times
7489
7490Return a collection containing process timing information.
7491
7492The object returned behaves like a named tuple with these fields:
7493 (utime, stime, cutime, cstime, elapsed_time)
7494All fields are floating point numbers.
7495[clinic start generated code]*/
7496
Larry Hastings2f936352014-08-05 14:04:04 +10007497static PyObject *
7498os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007499/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007500#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007501{
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 FILETIME create, exit, kernel, user;
7503 HANDLE hProc;
7504 hProc = GetCurrentProcess();
7505 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7506 /* The fields of a FILETIME structure are the hi and lo part
7507 of a 64-bit value expressed in 100 nanosecond units.
7508 1e7 is one second in such units; 1e-7 the inverse.
7509 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7510 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007511 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007512 (double)(user.dwHighDateTime*429.4967296 +
7513 user.dwLowDateTime*1e-7),
7514 (double)(kernel.dwHighDateTime*429.4967296 +
7515 kernel.dwLowDateTime*1e-7),
7516 (double)0,
7517 (double)0,
7518 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007519}
Larry Hastings2f936352014-08-05 14:04:04 +10007520#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007521{
Larry Hastings2f936352014-08-05 14:04:04 +10007522
7523
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007524 struct tms t;
7525 clock_t c;
7526 errno = 0;
7527 c = times(&t);
7528 if (c == (clock_t) -1)
7529 return posix_error();
7530 return build_times_result(
7531 (double)t.tms_utime / ticks_per_second,
7532 (double)t.tms_stime / ticks_per_second,
7533 (double)t.tms_cutime / ticks_per_second,
7534 (double)t.tms_cstime / ticks_per_second,
7535 (double)c / ticks_per_second);
7536}
Larry Hastings2f936352014-08-05 14:04:04 +10007537#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007538#endif /* HAVE_TIMES */
7539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007540
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007541#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007542/*[clinic input]
7543os.getsid
7544
7545 pid: pid_t
7546 /
7547
7548Call the system call getsid(pid) and return the result.
7549[clinic start generated code]*/
7550
Larry Hastings2f936352014-08-05 14:04:04 +10007551static PyObject *
7552os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007553/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007554{
Victor Stinner8c62be82010-05-06 00:08:46 +00007555 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 sid = getsid(pid);
7557 if (sid < 0)
7558 return posix_error();
7559 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007560}
7561#endif /* HAVE_GETSID */
7562
7563
Guido van Rossumb6775db1994-08-01 11:34:53 +00007564#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007565/*[clinic input]
7566os.setsid
7567
7568Call the system call setsid().
7569[clinic start generated code]*/
7570
Larry Hastings2f936352014-08-05 14:04:04 +10007571static PyObject *
7572os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007573/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007574{
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 if (setsid() < 0)
7576 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007577 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007578}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007579#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007580
Larry Hastings2f936352014-08-05 14:04:04 +10007581
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.setpgid
7585
7586 pid: pid_t
7587 pgrp: pid_t
7588 /
7589
7590Call the system call setpgid(pid, pgrp).
7591[clinic start generated code]*/
7592
Larry Hastings2f936352014-08-05 14:04:04 +10007593static PyObject *
7594os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007595/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007596{
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 if (setpgid(pid, pgrp) < 0)
7598 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007599 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007600}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007601#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007603
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007605/*[clinic input]
7606os.tcgetpgrp
7607
7608 fd: int
7609 /
7610
7611Return the process group associated with the terminal specified by fd.
7612[clinic start generated code]*/
7613
Larry Hastings2f936352014-08-05 14:04:04 +10007614static PyObject *
7615os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007616/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007617{
7618 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 if (pgid < 0)
7620 return posix_error();
7621 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007622}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007627/*[clinic input]
7628os.tcsetpgrp
7629
7630 fd: int
7631 pgid: pid_t
7632 /
7633
7634Set the process group associated with the terminal specified by fd.
7635[clinic start generated code]*/
7636
Larry Hastings2f936352014-08-05 14:04:04 +10007637static PyObject *
7638os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007639/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007640{
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 if (tcsetpgrp(fd, pgid) < 0)
7642 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007643 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007644}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007645#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007646
Guido van Rossum687dd131993-05-17 08:34:16 +00007647/* Functions acting on file descriptors */
7648
Victor Stinnerdaf45552013-08-28 00:53:59 +02007649#ifdef O_CLOEXEC
7650extern int _Py_open_cloexec_works;
7651#endif
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653
7654/*[clinic input]
7655os.open -> int
7656 path: path_t
7657 flags: int
7658 mode: int = 0o777
7659 *
7660 dir_fd: dir_fd(requires='openat') = None
7661
7662# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7663
7664Open a file for low level IO. Returns a file descriptor (integer).
7665
7666If dir_fd is not None, it should be a file descriptor open to a directory,
7667 and path should be relative; path will then be relative to that directory.
7668dir_fd may not be implemented on your platform.
7669 If it is unavailable, using it will raise a NotImplementedError.
7670[clinic start generated code]*/
7671
Larry Hastings2f936352014-08-05 14:04:04 +10007672static int
7673os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007674/*[clinic end generated code: output=c95a64f0e62f199b input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007675{
7676 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007677 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007678
Victor Stinnerdaf45552013-08-28 00:53:59 +02007679#ifdef O_CLOEXEC
7680 int *atomic_flag_works = &_Py_open_cloexec_works;
7681#elif !defined(MS_WINDOWS)
7682 int *atomic_flag_works = NULL;
7683#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007684
Victor Stinnerdaf45552013-08-28 00:53:59 +02007685#ifdef MS_WINDOWS
7686 flags |= O_NOINHERIT;
7687#elif defined(O_CLOEXEC)
7688 flags |= O_CLOEXEC;
7689#endif
7690
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007691 do {
7692 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007693#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007694 if (path->wide)
7695 fd = _wopen(path->wide, flags, mode);
7696 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697#endif
7698#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007699 if (dir_fd != DEFAULT_DIR_FD)
7700 fd = openat(dir_fd, path->narrow, flags, mode);
7701 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007702#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007703 fd = open(path->narrow, flags, mode);
7704 Py_END_ALLOW_THREADS
7705 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Guido van Rossum687dd131993-05-17 08:34:16 +00007706
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707 if (fd == -1) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007708 if (!async_err)
7709 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007710 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007711 }
7712
Victor Stinnerdaf45552013-08-28 00:53:59 +02007713#ifndef MS_WINDOWS
7714 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7715 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007716 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007717 }
7718#endif
7719
Larry Hastings2f936352014-08-05 14:04:04 +10007720 return fd;
7721}
7722
7723
7724/*[clinic input]
7725os.close
7726
7727 fd: int
7728
7729Close a file descriptor.
7730[clinic start generated code]*/
7731
Barry Warsaw53699e91996-12-10 23:23:01 +00007732static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007733os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007734/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007735{
Larry Hastings2f936352014-08-05 14:04:04 +10007736 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 if (!_PyVerify_fd(fd))
7738 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007739 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7740 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7741 * for more details.
7742 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 Py_BEGIN_ALLOW_THREADS
7744 res = close(fd);
7745 Py_END_ALLOW_THREADS
7746 if (res < 0)
7747 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007748 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007749}
7750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007751
Larry Hastings2f936352014-08-05 14:04:04 +10007752/*[clinic input]
7753os.closerange
7754
7755 fd_low: int
7756 fd_high: int
7757 /
7758
7759Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7760[clinic start generated code]*/
7761
Larry Hastings2f936352014-08-05 14:04:04 +10007762static PyObject *
7763os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007764/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007765{
7766 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007768 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 if (_PyVerify_fd(i))
7770 close(i);
7771 Py_END_ALLOW_THREADS
7772 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007773}
7774
7775
Larry Hastings2f936352014-08-05 14:04:04 +10007776/*[clinic input]
7777os.dup -> int
7778
7779 fd: int
7780 /
7781
7782Return a duplicate of a file descriptor.
7783[clinic start generated code]*/
7784
Larry Hastings2f936352014-08-05 14:04:04 +10007785static int
7786os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007787/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007788{
7789 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007790}
7791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007792
Larry Hastings2f936352014-08-05 14:04:04 +10007793/*[clinic input]
7794os.dup2
7795 fd: int
7796 fd2: int
7797 inheritable: bool=True
7798
7799Duplicate file descriptor.
7800[clinic start generated code]*/
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802static PyObject *
7803os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007804/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007805{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007806 int res;
7807#if defined(HAVE_DUP3) && \
7808 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7809 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7810 int dup3_works = -1;
7811#endif
7812
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 if (!_PyVerify_fd_dup2(fd, fd2))
7814 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007815
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007816 /* dup2() can fail with EINTR if the target FD is already open, because it
7817 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7818 * upon close(), and therefore below.
7819 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007820#ifdef MS_WINDOWS
7821 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007823 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 if (res < 0)
7825 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007826
7827 /* Character files like console cannot be make non-inheritable */
7828 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7829 close(fd2);
7830 return NULL;
7831 }
7832
7833#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7834 Py_BEGIN_ALLOW_THREADS
7835 if (!inheritable)
7836 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7837 else
7838 res = dup2(fd, fd2);
7839 Py_END_ALLOW_THREADS
7840 if (res < 0)
7841 return posix_error();
7842
7843#else
7844
7845#ifdef HAVE_DUP3
7846 if (!inheritable && dup3_works != 0) {
7847 Py_BEGIN_ALLOW_THREADS
7848 res = dup3(fd, fd2, O_CLOEXEC);
7849 Py_END_ALLOW_THREADS
7850 if (res < 0) {
7851 if (dup3_works == -1)
7852 dup3_works = (errno != ENOSYS);
7853 if (dup3_works)
7854 return posix_error();
7855 }
7856 }
7857
7858 if (inheritable || dup3_works == 0)
7859 {
7860#endif
7861 Py_BEGIN_ALLOW_THREADS
7862 res = dup2(fd, fd2);
7863 Py_END_ALLOW_THREADS
7864 if (res < 0)
7865 return posix_error();
7866
7867 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7868 close(fd2);
7869 return NULL;
7870 }
7871#ifdef HAVE_DUP3
7872 }
7873#endif
7874
7875#endif
7876
Larry Hastings2f936352014-08-05 14:04:04 +10007877 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007878}
7879
Larry Hastings2f936352014-08-05 14:04:04 +10007880
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007882/*[clinic input]
7883os.lockf
7884
7885 fd: int
7886 An open file descriptor.
7887 command: int
7888 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7889 length: Py_off_t
7890 The number of bytes to lock, starting at the current position.
7891 /
7892
7893Apply, test or remove a POSIX lock on an open file descriptor.
7894
7895[clinic start generated code]*/
7896
Larry Hastings2f936352014-08-05 14:04:04 +10007897static PyObject *
7898os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007899/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007900{
7901 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007902
7903 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007904 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007905 Py_END_ALLOW_THREADS
7906
7907 if (res < 0)
7908 return posix_error();
7909
7910 Py_RETURN_NONE;
7911}
Larry Hastings2f936352014-08-05 14:04:04 +10007912#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007914
Larry Hastings2f936352014-08-05 14:04:04 +10007915/*[clinic input]
7916os.lseek -> Py_off_t
7917
7918 fd: int
7919 position: Py_off_t
7920 how: int
7921 /
7922
7923Set the position of a file descriptor. Return the new position.
7924
7925Return the new cursor position in number of bytes
7926relative to the beginning of the file.
7927[clinic start generated code]*/
7928
Larry Hastings2f936352014-08-05 14:04:04 +10007929static Py_off_t
7930os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007931/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007932{
7933 Py_off_t result;
7934
7935 if (!_PyVerify_fd(fd)) {
7936 posix_error();
7937 return -1;
7938 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007939#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7941 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007942 case 0: how = SEEK_SET; break;
7943 case 1: how = SEEK_CUR; break;
7944 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007946#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007947
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007949 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007950
Larry Hastings2f936352014-08-05 14:04:04 +10007951 if (!_PyVerify_fd(fd)) {
7952 posix_error();
7953 return -1;
7954 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007956#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007957 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007958#else
Larry Hastings2f936352014-08-05 14:04:04 +10007959 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007960#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007962 if (result < 0)
7963 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007964
Larry Hastings2f936352014-08-05 14:04:04 +10007965 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007966}
7967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007968
Larry Hastings2f936352014-08-05 14:04:04 +10007969/*[clinic input]
7970os.read
7971 fd: int
7972 length: Py_ssize_t
7973 /
7974
7975Read from a file descriptor. Returns a bytes object.
7976[clinic start generated code]*/
7977
Larry Hastings2f936352014-08-05 14:04:04 +10007978static PyObject *
7979os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007980/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007981{
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 Py_ssize_t n;
7983 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007984
7985 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 errno = EINVAL;
7987 return posix_error();
7988 }
Larry Hastings2f936352014-08-05 14:04:04 +10007989
7990#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007991 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007992 if (length > INT_MAX)
7993 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007994#endif
7995
7996 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 if (buffer == NULL)
7998 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007999
Victor Stinner66aab0c2015-03-19 22:53:20 +01008000 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8001 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008003 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 }
Larry Hastings2f936352014-08-05 14:04:04 +10008005
8006 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008008
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008010}
8011
Ross Lagerwall7807c352011-03-17 20:20:30 +02008012#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8013 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008014static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8016{
8017 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008018 Py_ssize_t blen, total = 0;
8019
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008020 *iov = PyMem_New(struct iovec, cnt);
8021 if (*iov == NULL) {
8022 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008023 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008024 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008025
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008026 *buf = PyMem_New(Py_buffer, cnt);
8027 if (*buf == NULL) {
8028 PyMem_Del(*iov);
8029 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008030 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008031 }
8032
8033 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008034 PyObject *item = PySequence_GetItem(seq, i);
8035 if (item == NULL)
8036 goto fail;
8037 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8038 Py_DECREF(item);
8039 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008041 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008043 blen = (*buf)[i].len;
8044 (*iov)[i].iov_len = blen;
8045 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008046 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008047 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008048
8049fail:
8050 PyMem_Del(*iov);
8051 for (j = 0; j < i; j++) {
8052 PyBuffer_Release(&(*buf)[j]);
8053 }
8054 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008055 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008056}
8057
8058static void
8059iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8060{
8061 int i;
8062 PyMem_Del(iov);
8063 for (i = 0; i < cnt; i++) {
8064 PyBuffer_Release(&buf[i]);
8065 }
8066 PyMem_Del(buf);
8067}
8068#endif
8069
Larry Hastings2f936352014-08-05 14:04:04 +10008070
Ross Lagerwall7807c352011-03-17 20:20:30 +02008071#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008072/*[clinic input]
8073os.readv -> Py_ssize_t
8074
8075 fd: int
8076 buffers: object
8077 /
8078
8079Read from a file descriptor fd into an iterable of buffers.
8080
8081The buffers should be mutable buffers accepting bytes.
8082readv will transfer data into each buffer until it is full
8083and then move on to the next buffer in the sequence to hold
8084the rest of the data.
8085
8086readv returns the total number of bytes read,
8087which may be less than the total capacity of all the buffers.
8088[clinic start generated code]*/
8089
Larry Hastings2f936352014-08-05 14:04:04 +10008090static Py_ssize_t
8091os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008092/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008093{
8094 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008095 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008096 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008097 struct iovec *iov;
8098 Py_buffer *buf;
8099
Larry Hastings2f936352014-08-05 14:04:04 +10008100 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008101 PyErr_SetString(PyExc_TypeError,
8102 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008103 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008104 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008105
Larry Hastings2f936352014-08-05 14:04:04 +10008106 cnt = PySequence_Size(buffers);
8107
8108 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8109 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008110
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008111 do {
8112 Py_BEGIN_ALLOW_THREADS
8113 n = readv(fd, iov, cnt);
8114 Py_END_ALLOW_THREADS
8115 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008116
8117 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008118 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008119 if (!async_err)
8120 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008121 return -1;
8122 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008123
Larry Hastings2f936352014-08-05 14:04:04 +10008124 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125}
Larry Hastings2f936352014-08-05 14:04:04 +10008126#endif /* HAVE_READV */
8127
Ross Lagerwall7807c352011-03-17 20:20:30 +02008128
8129#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008130/*[clinic input]
8131# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8132os.pread
8133
8134 fd: int
8135 length: int
8136 offset: Py_off_t
8137 /
8138
8139Read a number of bytes from a file descriptor starting at a particular offset.
8140
8141Read length bytes from file descriptor fd, starting at offset bytes from
8142the beginning of the file. The file offset remains unchanged.
8143[clinic start generated code]*/
8144
Larry Hastings2f936352014-08-05 14:04:04 +10008145static PyObject *
8146os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008147/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008148{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008150 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008152
Larry Hastings2f936352014-08-05 14:04:04 +10008153 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154 errno = EINVAL;
8155 return posix_error();
8156 }
Larry Hastings2f936352014-08-05 14:04:04 +10008157 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008158 if (buffer == NULL)
8159 return NULL;
8160 if (!_PyVerify_fd(fd)) {
8161 Py_DECREF(buffer);
8162 return posix_error();
8163 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008164
8165 do {
8166 Py_BEGIN_ALLOW_THREADS
8167 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
8168 Py_END_ALLOW_THREADS
8169 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8170
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 if (n < 0) {
8172 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008173 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174 }
Larry Hastings2f936352014-08-05 14:04:04 +10008175 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008176 _PyBytes_Resize(&buffer, n);
8177 return buffer;
8178}
Larry Hastings2f936352014-08-05 14:04:04 +10008179#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008180
Larry Hastings2f936352014-08-05 14:04:04 +10008181
8182/*[clinic input]
8183os.write -> Py_ssize_t
8184
8185 fd: int
8186 data: Py_buffer
8187 /
8188
8189Write a bytes object to a file descriptor.
8190[clinic start generated code]*/
8191
Larry Hastings2f936352014-08-05 14:04:04 +10008192static Py_ssize_t
8193os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008194/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008195{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008196 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008197}
8198
8199#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200PyDoc_STRVAR(posix_sendfile__doc__,
8201"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8202sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8203 -> byteswritten\n\
8204Copy nbytes bytes from file descriptor in to file descriptor out.");
8205
Larry Hastings2f936352014-08-05 14:04:04 +10008206/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207static PyObject *
8208posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8209{
8210 int in, out;
8211 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008212 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008213 off_t offset;
8214
8215#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8216#ifndef __APPLE__
8217 Py_ssize_t len;
8218#endif
8219 PyObject *headers = NULL, *trailers = NULL;
8220 Py_buffer *hbuf, *tbuf;
8221 off_t sbytes;
8222 struct sf_hdtr sf;
8223 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008224 static char *keywords[] = {"out", "in",
8225 "offset", "count",
8226 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008227
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008228 sf.headers = NULL;
8229 sf.trailers = NULL;
8230
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231#ifdef __APPLE__
8232 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008233 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008234#else
8235 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008236 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008237#endif
8238 &headers, &trailers, &flags))
8239 return NULL;
8240 if (headers != NULL) {
8241 if (!PySequence_Check(headers)) {
8242 PyErr_SetString(PyExc_TypeError,
8243 "sendfile() headers must be a sequence or None");
8244 return NULL;
8245 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008246 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008248 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008249 (i = iov_setup(&(sf.headers), &hbuf,
8250 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008251 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008252#ifdef __APPLE__
8253 sbytes += i;
8254#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 }
8256 }
8257 if (trailers != NULL) {
8258 if (!PySequence_Check(trailers)) {
8259 PyErr_SetString(PyExc_TypeError,
8260 "sendfile() trailers must be a sequence or None");
8261 return NULL;
8262 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008263 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008264 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008265 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008266 (i = iov_setup(&(sf.trailers), &tbuf,
8267 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008269#ifdef __APPLE__
8270 sbytes += i;
8271#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272 }
8273 }
8274
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008275 do {
8276 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008278 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008280 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008281#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008282 Py_END_ALLOW_THREADS
8283 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008284
8285 if (sf.headers != NULL)
8286 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8287 if (sf.trailers != NULL)
8288 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8289
8290 if (ret < 0) {
8291 if ((errno == EAGAIN) || (errno == EBUSY)) {
8292 if (sbytes != 0) {
8293 // some data has been sent
8294 goto done;
8295 }
8296 else {
8297 // no data has been sent; upper application is supposed
8298 // to retry on EAGAIN or EBUSY
8299 return posix_error();
8300 }
8301 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008302 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008303 }
8304 goto done;
8305
8306done:
8307 #if !defined(HAVE_LARGEFILE_SUPPORT)
8308 return Py_BuildValue("l", sbytes);
8309 #else
8310 return Py_BuildValue("L", sbytes);
8311 #endif
8312
8313#else
8314 Py_ssize_t count;
8315 PyObject *offobj;
8316 static char *keywords[] = {"out", "in",
8317 "offset", "count", NULL};
8318 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8319 keywords, &out, &in, &offobj, &count))
8320 return NULL;
8321#ifdef linux
8322 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008323 do {
8324 Py_BEGIN_ALLOW_THREADS
8325 ret = sendfile(out, in, NULL, count);
8326 Py_END_ALLOW_THREADS
8327 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008328 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008329 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008330 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331 }
8332#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008333 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008334 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008335
8336 do {
8337 Py_BEGIN_ALLOW_THREADS
8338 ret = sendfile(out, in, &offset, count);
8339 Py_END_ALLOW_THREADS
8340 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008341 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008342 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008343 return Py_BuildValue("n", ret);
8344#endif
8345}
Larry Hastings2f936352014-08-05 14:04:04 +10008346#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008347
Larry Hastings2f936352014-08-05 14:04:04 +10008348
8349/*[clinic input]
8350os.fstat
8351
8352 fd : int
8353
8354Perform a stat system call on the given file descriptor.
8355
8356Like stat(), but for an open file descriptor.
8357Equivalent to os.stat(fd).
8358[clinic start generated code]*/
8359
Larry Hastings2f936352014-08-05 14:04:04 +10008360static PyObject *
8361os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008362/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008363{
Victor Stinner8c62be82010-05-06 00:08:46 +00008364 STRUCT_STAT st;
8365 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008367
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 do {
8369 Py_BEGIN_ALLOW_THREADS
8370 res = FSTAT(fd, &st);
8371 Py_END_ALLOW_THREADS
8372 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008374#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008375 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008376#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008377 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008378#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 }
Tim Peters5aa91602002-01-30 05:46:57 +00008380
Victor Stinner4195b5c2012-02-08 23:03:19 +01008381 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008382}
8383
Larry Hastings2f936352014-08-05 14:04:04 +10008384
8385/*[clinic input]
8386os.isatty -> bool
8387 fd: int
8388 /
8389
8390Return True if the fd is connected to a terminal.
8391
8392Return True if the file descriptor is an open file descriptor
8393connected to the slave end of a terminal.
8394[clinic start generated code]*/
8395
Larry Hastings2f936352014-08-05 14:04:04 +10008396static int
8397os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008398/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008399{
8400 if (!_PyVerify_fd(fd))
8401 return 0;
8402 return isatty(fd);
8403}
8404
8405
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008406#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008407/*[clinic input]
8408os.pipe
8409
8410Create a pipe.
8411
8412Returns a tuple of two file descriptors:
8413 (read_fd, write_fd)
8414[clinic start generated code]*/
8415
Larry Hastings2f936352014-08-05 14:04:04 +10008416static PyObject *
8417os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008418/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008419{
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008421#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008423 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008425#else
8426 int res;
8427#endif
8428
8429#ifdef MS_WINDOWS
8430 attr.nLength = sizeof(attr);
8431 attr.lpSecurityDescriptor = NULL;
8432 attr.bInheritHandle = FALSE;
8433
8434 Py_BEGIN_ALLOW_THREADS
8435 ok = CreatePipe(&read, &write, &attr, 0);
8436 if (ok) {
8437 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8438 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8439 if (fds[0] == -1 || fds[1] == -1) {
8440 CloseHandle(read);
8441 CloseHandle(write);
8442 ok = 0;
8443 }
8444 }
8445 Py_END_ALLOW_THREADS
8446
Victor Stinner8c62be82010-05-06 00:08:46 +00008447 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008448 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008449#else
8450
8451#ifdef HAVE_PIPE2
8452 Py_BEGIN_ALLOW_THREADS
8453 res = pipe2(fds, O_CLOEXEC);
8454 Py_END_ALLOW_THREADS
8455
8456 if (res != 0 && errno == ENOSYS)
8457 {
8458#endif
8459 Py_BEGIN_ALLOW_THREADS
8460 res = pipe(fds);
8461 Py_END_ALLOW_THREADS
8462
8463 if (res == 0) {
8464 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8465 close(fds[0]);
8466 close(fds[1]);
8467 return NULL;
8468 }
8469 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8470 close(fds[0]);
8471 close(fds[1]);
8472 return NULL;
8473 }
8474 }
8475#ifdef HAVE_PIPE2
8476 }
8477#endif
8478
8479 if (res != 0)
8480 return PyErr_SetFromErrno(PyExc_OSError);
8481#endif /* !MS_WINDOWS */
8482 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008483}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008484#endif /* HAVE_PIPE */
8485
Larry Hastings2f936352014-08-05 14:04:04 +10008486
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008487#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008488/*[clinic input]
8489os.pipe2
8490
8491 flags: int
8492 /
8493
8494Create a pipe with flags set atomically.
8495
8496Returns a tuple of two file descriptors:
8497 (read_fd, write_fd)
8498
8499flags can be constructed by ORing together one or more of these values:
8500O_NONBLOCK, O_CLOEXEC.
8501[clinic start generated code]*/
8502
Larry Hastings2f936352014-08-05 14:04:04 +10008503static PyObject *
8504os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008505/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008506{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008507 int fds[2];
8508 int res;
8509
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008510 res = pipe2(fds, flags);
8511 if (res != 0)
8512 return posix_error();
8513 return Py_BuildValue("(ii)", fds[0], fds[1]);
8514}
8515#endif /* HAVE_PIPE2 */
8516
Larry Hastings2f936352014-08-05 14:04:04 +10008517
Ross Lagerwall7807c352011-03-17 20:20:30 +02008518#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008519/*[clinic input]
8520os.writev -> Py_ssize_t
8521 fd: int
8522 buffers: object
8523 /
8524
8525Iterate over buffers, and write the contents of each to a file descriptor.
8526
8527Returns the total number of bytes written.
8528buffers must be a sequence of bytes-like objects.
8529[clinic start generated code]*/
8530
Larry Hastings2f936352014-08-05 14:04:04 +10008531static Py_ssize_t
8532os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008533/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008534{
8535 int cnt;
8536 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008537 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008538 struct iovec *iov;
8539 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008540
8541 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008542 PyErr_SetString(PyExc_TypeError,
8543 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008544 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008545 }
Larry Hastings2f936352014-08-05 14:04:04 +10008546 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008547
Larry Hastings2f936352014-08-05 14:04:04 +10008548 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8549 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550 }
8551
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008552 do {
8553 Py_BEGIN_ALLOW_THREADS
8554 result = writev(fd, iov, cnt);
8555 Py_END_ALLOW_THREADS
8556 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008557
8558 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008559 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008560 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008561
Georg Brandl306336b2012-06-24 12:55:33 +02008562 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008563}
Larry Hastings2f936352014-08-05 14:04:04 +10008564#endif /* HAVE_WRITEV */
8565
8566
8567#ifdef HAVE_PWRITE
8568/*[clinic input]
8569os.pwrite -> Py_ssize_t
8570
8571 fd: int
8572 buffer: Py_buffer
8573 offset: Py_off_t
8574 /
8575
8576Write bytes to a file descriptor starting at a particular offset.
8577
8578Write buffer to fd, starting at offset bytes from the beginning of
8579the file. Returns the number of bytes writte. Does not change the
8580current file offset.
8581[clinic start generated code]*/
8582
Larry Hastings2f936352014-08-05 14:04:04 +10008583static Py_ssize_t
8584os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008585/*[clinic end generated code: output=95225f3b496feaf3 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008586{
8587 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008588 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008589
8590 if (!_PyVerify_fd(fd)) {
8591 posix_error();
8592 return -1;
8593 }
8594
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008595 do {
8596 Py_BEGIN_ALLOW_THREADS
8597 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
8598 Py_END_ALLOW_THREADS
8599 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008600
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008601 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008602 posix_error();
8603 return size;
8604}
8605#endif /* HAVE_PWRITE */
8606
8607
8608#ifdef HAVE_MKFIFO
8609/*[clinic input]
8610os.mkfifo
8611
8612 path: path_t
8613 mode: int=0o666
8614 *
8615 dir_fd: dir_fd(requires='mkfifoat')=None
8616
8617Create a "fifo" (a POSIX named pipe).
8618
8619If dir_fd is not None, it should be a file descriptor open to a directory,
8620 and path should be relative; path will then be relative to that directory.
8621dir_fd may not be implemented on your platform.
8622 If it is unavailable, using it will raise a NotImplementedError.
8623[clinic start generated code]*/
8624
Larry Hastings2f936352014-08-05 14:04:04 +10008625static PyObject *
8626os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008627/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008628{
8629 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008630 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008631
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008632 do {
8633 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008634#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 if (dir_fd != DEFAULT_DIR_FD)
8636 result = mkfifoat(dir_fd, path->narrow, mode);
8637 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008638#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008639 result = mkfifo(path->narrow, mode);
8640 Py_END_ALLOW_THREADS
8641 } while (result != 0 && errno == EINTR &&
8642 !(async_err = PyErr_CheckSignals()));
8643 if (result != 0)
8644 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008645
8646 Py_RETURN_NONE;
8647}
8648#endif /* HAVE_MKFIFO */
8649
8650
8651#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8652/*[clinic input]
8653os.mknod
8654
8655 path: path_t
8656 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008657 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008658 *
8659 dir_fd: dir_fd(requires='mknodat')=None
8660
8661Create a node in the file system.
8662
8663Create a node in the file system (file, device special file or named pipe)
8664at path. mode specifies both the permissions to use and the
8665type of node to be created, being combined (bitwise OR) with one of
8666S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8667device defines the newly created device special file (probably using
8668os.makedev()). Otherwise device is ignored.
8669
8670If dir_fd is not None, it should be a file descriptor open to a directory,
8671 and path should be relative; path will then be relative to that directory.
8672dir_fd may not be implemented on your platform.
8673 If it is unavailable, using it will raise a NotImplementedError.
8674[clinic start generated code]*/
8675
Larry Hastings2f936352014-08-05 14:04:04 +10008676static PyObject *
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008677os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008678/*[clinic end generated code: output=f7f813e8847de12f input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008679{
8680 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008682
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008683 do {
8684 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008685#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 if (dir_fd != DEFAULT_DIR_FD)
8687 result = mknodat(dir_fd, path->narrow, mode, device);
8688 else
Larry Hastings2f936352014-08-05 14:04:04 +10008689#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 result = mknod(path->narrow, mode, device);
8691 Py_END_ALLOW_THREADS
8692 } while (result != 0 && errno == EINTR &&
8693 !(async_err = PyErr_CheckSignals()));
8694 if (result != 0)
8695 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008696
8697 Py_RETURN_NONE;
8698}
8699#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8700
8701
8702#ifdef HAVE_DEVICE_MACROS
8703/*[clinic input]
8704os.major -> unsigned_int
8705
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008706 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008707 /
8708
8709Extracts a device major number from a raw device number.
8710[clinic start generated code]*/
8711
Larry Hastings2f936352014-08-05 14:04:04 +10008712static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008713os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008714/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008715{
8716 return major(device);
8717}
8718
8719
8720/*[clinic input]
8721os.minor -> unsigned_int
8722
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008723 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008724 /
8725
8726Extracts a device minor number from a raw device number.
8727[clinic start generated code]*/
8728
Larry Hastings2f936352014-08-05 14:04:04 +10008729static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008730os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008731/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008732{
8733 return minor(device);
8734}
8735
8736
8737/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008738os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008739
8740 major: int
8741 minor: int
8742 /
8743
8744Composes a raw device number from the major and minor device numbers.
8745[clinic start generated code]*/
8746
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008747static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008748os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008749/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008750{
8751 return makedev(major, minor);
8752}
8753#endif /* HAVE_DEVICE_MACROS */
8754
8755
8756#ifdef HAVE_FTRUNCATE
8757/*[clinic input]
8758os.ftruncate
8759
8760 fd: int
8761 length: Py_off_t
8762 /
8763
8764Truncate a file, specified by file descriptor, to a specific length.
8765[clinic start generated code]*/
8766
Larry Hastings2f936352014-08-05 14:04:04 +10008767static PyObject *
8768os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008769/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008770{
8771 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008772 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008773
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008774 do {
8775 Py_BEGIN_ALLOW_THREADS
8776 result = ftruncate(fd, length);
8777 Py_END_ALLOW_THREADS
8778 } while (result != 0 && errno == EINTR &&
8779 !(async_err = PyErr_CheckSignals()));
8780 if (result != 0)
8781 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008782 Py_RETURN_NONE;
8783}
8784#endif /* HAVE_FTRUNCATE */
8785
8786
8787#ifdef HAVE_TRUNCATE
8788/*[clinic input]
8789os.truncate
8790 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8791 length: Py_off_t
8792
8793Truncate a file, specified by path, to a specific length.
8794
8795On some platforms, path may also be specified as an open file descriptor.
8796 If this functionality is unavailable, using it raises an exception.
8797[clinic start generated code]*/
8798
Larry Hastings2f936352014-08-05 14:04:04 +10008799static PyObject *
8800os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008801/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008802{
8803 int result;
8804
8805 Py_BEGIN_ALLOW_THREADS
8806#ifdef HAVE_FTRUNCATE
8807 if (path->fd != -1)
8808 result = ftruncate(path->fd, length);
8809 else
8810#endif
8811 result = truncate(path->narrow, length);
8812 Py_END_ALLOW_THREADS
8813 if (result < 0)
8814 return path_error(path);
8815
8816 Py_RETURN_NONE;
8817}
8818#endif /* HAVE_TRUNCATE */
8819
Ross Lagerwall7807c352011-03-17 20:20:30 +02008820
Victor Stinnerd6b17692014-09-30 12:20:05 +02008821/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8822 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8823 defined, which is the case in Python on AIX. AIX bug report:
8824 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8825#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8826# define POSIX_FADVISE_AIX_BUG
8827#endif
8828
Victor Stinnerec39e262014-09-30 12:35:58 +02008829
Victor Stinnerd6b17692014-09-30 12:20:05 +02008830#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008831/*[clinic input]
8832os.posix_fallocate
8833
8834 fd: int
8835 offset: Py_off_t
8836 length: Py_off_t
8837 /
8838
8839Ensure a file has allocated at least a particular number of bytes on disk.
8840
8841Ensure that the file specified by fd encompasses a range of bytes
8842starting at offset bytes from the beginning and continuing for length bytes.
8843[clinic start generated code]*/
8844
Larry Hastings2f936352014-08-05 14:04:04 +10008845static PyObject *
8846os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008847/*[clinic end generated code: output=8ae5f7837004d454 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008848{
8849 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008850 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008852 do {
8853 Py_BEGIN_ALLOW_THREADS
8854 result = posix_fallocate(fd, offset, length);
8855 Py_END_ALLOW_THREADS
8856 } while (result != 0 && errno == EINTR &&
8857 !(async_err = PyErr_CheckSignals()));
8858 if (result != 0)
8859 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008860 Py_RETURN_NONE;
8861}
Victor Stinnerec39e262014-09-30 12:35:58 +02008862#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008863
Ross Lagerwall7807c352011-03-17 20:20:30 +02008864
Victor Stinnerd6b17692014-09-30 12:20:05 +02008865#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008866/*[clinic input]
8867os.posix_fadvise
8868
8869 fd: int
8870 offset: Py_off_t
8871 length: Py_off_t
8872 advice: int
8873 /
8874
8875Announce an intention to access data in a specific pattern.
8876
8877Announce an intention to access data in a specific pattern, thus allowing
8878the kernel to make optimizations.
8879The advice applies to the region of the file specified by fd starting at
8880offset and continuing for length bytes.
8881advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8882POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8883POSIX_FADV_DONTNEED.
8884[clinic start generated code]*/
8885
Larry Hastings2f936352014-08-05 14:04:04 +10008886static PyObject *
8887os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008888/*[clinic end generated code: output=0e3f09f651661257 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008889{
8890 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008891 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008892
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008893 do {
8894 Py_BEGIN_ALLOW_THREADS
8895 result = posix_fadvise(fd, offset, length, advice);
8896 Py_END_ALLOW_THREADS
8897 } while (result != 0 && errno == EINTR &&
8898 !(async_err = PyErr_CheckSignals()));
8899 if (result != 0)
8900 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008901 Py_RETURN_NONE;
8902}
Victor Stinnerec39e262014-09-30 12:35:58 +02008903#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008904
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008905#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008906
Fred Drake762e2061999-08-26 17:23:54 +00008907/* Save putenv() parameters as values here, so we can collect them when they
8908 * get re-set with another call for the same key. */
8909static PyObject *posix_putenv_garbage;
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static void
8912posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008913{
Larry Hastings2f936352014-08-05 14:04:04 +10008914 /* Install the first arg and newstr in posix_putenv_garbage;
8915 * this will cause previous value to be collected. This has to
8916 * happen after the real putenv() call because the old value
8917 * was still accessible until then. */
8918 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8919 /* really not much we can do; just leak */
8920 PyErr_Clear();
8921 else
8922 Py_DECREF(value);
8923}
8924
8925
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008926#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008927/*[clinic input]
8928os.putenv
8929
8930 name: unicode
8931 value: unicode
8932 /
8933
8934Change or add an environment variable.
8935[clinic start generated code]*/
8936
Larry Hastings2f936352014-08-05 14:04:04 +10008937static PyObject *
8938os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008939/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008940{
8941 wchar_t *env;
8942
8943 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8944 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008945 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008946 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008947 }
Larry Hastings2f936352014-08-05 14:04:04 +10008948 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008949 PyErr_Format(PyExc_ValueError,
8950 "the environment variable is longer than %u characters",
8951 _MAX_ENV);
8952 goto error;
8953 }
8954
Larry Hastings2f936352014-08-05 14:04:04 +10008955 env = PyUnicode_AsUnicode(unicode);
8956 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008957 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008958 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008960 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008962
Larry Hastings2f936352014-08-05 14:04:04 +10008963 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008964 Py_RETURN_NONE;
8965
8966error:
Larry Hastings2f936352014-08-05 14:04:04 +10008967 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008968 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008969}
Larry Hastings2f936352014-08-05 14:04:04 +10008970#else /* MS_WINDOWS */
8971/*[clinic input]
8972os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008973
Larry Hastings2f936352014-08-05 14:04:04 +10008974 name: FSConverter
8975 value: FSConverter
8976 /
8977
8978Change or add an environment variable.
8979[clinic start generated code]*/
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981static PyObject *
8982os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008983/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008984{
8985 PyObject *bytes = NULL;
8986 char *env;
8987 char *name_string = PyBytes_AsString(name);
8988 char *value_string = PyBytes_AsString(value);
8989
8990 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8991 if (bytes == NULL) {
8992 PyErr_NoMemory();
8993 return NULL;
8994 }
8995
8996 env = PyBytes_AS_STRING(bytes);
8997 if (putenv(env)) {
8998 Py_DECREF(bytes);
8999 return posix_error();
9000 }
9001
9002 posix_putenv_garbage_setitem(name, bytes);
9003 Py_RETURN_NONE;
9004}
9005#endif /* MS_WINDOWS */
9006#endif /* HAVE_PUTENV */
9007
9008
9009#ifdef HAVE_UNSETENV
9010/*[clinic input]
9011os.unsetenv
9012 name: FSConverter
9013 /
9014
9015Delete an environment variable.
9016[clinic start generated code]*/
9017
Larry Hastings2f936352014-08-05 14:04:04 +10009018static PyObject *
9019os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009020/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009021{
Victor Stinner984890f2011-11-24 13:53:38 +01009022#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009023 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009024#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009025
Victor Stinner984890f2011-11-24 13:53:38 +01009026#ifdef HAVE_BROKEN_UNSETENV
9027 unsetenv(PyBytes_AS_STRING(name));
9028#else
Victor Stinner65170952011-11-22 22:16:17 +01009029 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009030 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009031 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009032#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009033
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 /* Remove the key from posix_putenv_garbage;
9035 * this will cause it to be collected. This has to
9036 * happen after the real unsetenv() call because the
9037 * old value was still accessible until then.
9038 */
Victor Stinner65170952011-11-22 22:16:17 +01009039 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 /* really not much we can do; just leak */
9041 PyErr_Clear();
9042 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009043 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009044}
Larry Hastings2f936352014-08-05 14:04:04 +10009045#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009046
Larry Hastings2f936352014-08-05 14:04:04 +10009047
9048/*[clinic input]
9049os.strerror
9050
9051 code: int
9052 /
9053
9054Translate an error code to a message string.
9055[clinic start generated code]*/
9056
Larry Hastings2f936352014-08-05 14:04:04 +10009057static PyObject *
9058os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009059/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009060{
9061 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 if (message == NULL) {
9063 PyErr_SetString(PyExc_ValueError,
9064 "strerror() argument out of range");
9065 return NULL;
9066 }
Victor Stinner1b579672011-12-17 05:47:23 +01009067 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009068}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009069
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009070
Guido van Rossumc9641791998-08-04 15:26:23 +00009071#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009072#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009073/*[clinic input]
9074os.WCOREDUMP -> bool
9075
9076 status: int
9077 /
9078
9079Return True if the process returning status was dumped to a core file.
9080[clinic start generated code]*/
9081
Larry Hastings2f936352014-08-05 14:04:04 +10009082static int
9083os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009084/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009085{
9086 WAIT_TYPE wait_status;
9087 WAIT_STATUS_INT(wait_status) = status;
9088 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009089}
9090#endif /* WCOREDUMP */
9091
Larry Hastings2f936352014-08-05 14:04:04 +10009092
Fred Drake106c1a02002-04-23 15:58:02 +00009093#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009094/*[clinic input]
9095os.WIFCONTINUED -> bool
9096
9097 status: int
9098
9099Return True if a particular process was continued from a job control stop.
9100
9101Return True if the process returning status was continued from a
9102job control stop.
9103[clinic start generated code]*/
9104
Larry Hastings2f936352014-08-05 14:04:04 +10009105static int
9106os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009107/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009108{
9109 WAIT_TYPE wait_status;
9110 WAIT_STATUS_INT(wait_status) = status;
9111 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009112}
9113#endif /* WIFCONTINUED */
9114
Larry Hastings2f936352014-08-05 14:04:04 +10009115
Guido van Rossumc9641791998-08-04 15:26:23 +00009116#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009117/*[clinic input]
9118os.WIFSTOPPED -> bool
9119
9120 status: int
9121
9122Return True if the process returning status was stopped.
9123[clinic start generated code]*/
9124
Larry Hastings2f936352014-08-05 14:04:04 +10009125static int
9126os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009127/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009128{
9129 WAIT_TYPE wait_status;
9130 WAIT_STATUS_INT(wait_status) = status;
9131 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009132}
9133#endif /* WIFSTOPPED */
9134
Larry Hastings2f936352014-08-05 14:04:04 +10009135
Guido van Rossumc9641791998-08-04 15:26:23 +00009136#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009137/*[clinic input]
9138os.WIFSIGNALED -> bool
9139
9140 status: int
9141
9142Return True if the process returning status was terminated by a signal.
9143[clinic start generated code]*/
9144
Larry Hastings2f936352014-08-05 14:04:04 +10009145static int
9146os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009147/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009148{
9149 WAIT_TYPE wait_status;
9150 WAIT_STATUS_INT(wait_status) = status;
9151 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009152}
9153#endif /* WIFSIGNALED */
9154
Larry Hastings2f936352014-08-05 14:04:04 +10009155
Guido van Rossumc9641791998-08-04 15:26:23 +00009156#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009157/*[clinic input]
9158os.WIFEXITED -> bool
9159
9160 status: int
9161
9162Return True if the process returning status exited via the exit() system call.
9163[clinic start generated code]*/
9164
Larry Hastings2f936352014-08-05 14:04:04 +10009165static int
9166os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009167/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009168{
9169 WAIT_TYPE wait_status;
9170 WAIT_STATUS_INT(wait_status) = status;
9171 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009172}
9173#endif /* WIFEXITED */
9174
Larry Hastings2f936352014-08-05 14:04:04 +10009175
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009176#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009177/*[clinic input]
9178os.WEXITSTATUS -> int
9179
9180 status: int
9181
9182Return the process return code from status.
9183[clinic start generated code]*/
9184
Larry Hastings2f936352014-08-05 14:04:04 +10009185static int
9186os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009187/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009188{
9189 WAIT_TYPE wait_status;
9190 WAIT_STATUS_INT(wait_status) = status;
9191 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009192}
9193#endif /* WEXITSTATUS */
9194
Larry Hastings2f936352014-08-05 14:04:04 +10009195
Guido van Rossumc9641791998-08-04 15:26:23 +00009196#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009197/*[clinic input]
9198os.WTERMSIG -> int
9199
9200 status: int
9201
9202Return the signal that terminated the process that provided the status value.
9203[clinic start generated code]*/
9204
Larry Hastings2f936352014-08-05 14:04:04 +10009205static int
9206os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009207/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009208{
9209 WAIT_TYPE wait_status;
9210 WAIT_STATUS_INT(wait_status) = status;
9211 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009212}
9213#endif /* WTERMSIG */
9214
Larry Hastings2f936352014-08-05 14:04:04 +10009215
Guido van Rossumc9641791998-08-04 15:26:23 +00009216#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009217/*[clinic input]
9218os.WSTOPSIG -> int
9219
9220 status: int
9221
9222Return the signal that stopped the process that provided the status value.
9223[clinic start generated code]*/
9224
Larry Hastings2f936352014-08-05 14:04:04 +10009225static int
9226os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009227/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009228{
9229 WAIT_TYPE wait_status;
9230 WAIT_STATUS_INT(wait_status) = status;
9231 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009232}
9233#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009234#endif /* HAVE_SYS_WAIT_H */
9235
9236
Thomas Wouters477c8d52006-05-27 19:21:47 +00009237#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009238#ifdef _SCO_DS
9239/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9240 needed definitions in sys/statvfs.h */
9241#define _SVID3
9242#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009243#include <sys/statvfs.h>
9244
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009245static PyObject*
9246_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9248 if (v == NULL)
9249 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009250
9251#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9253 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9254 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9255 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9256 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9257 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9258 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9259 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9260 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9261 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009262#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9264 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9265 PyStructSequence_SET_ITEM(v, 2,
9266 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9267 PyStructSequence_SET_ITEM(v, 3,
9268 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9269 PyStructSequence_SET_ITEM(v, 4,
9270 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9271 PyStructSequence_SET_ITEM(v, 5,
9272 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9273 PyStructSequence_SET_ITEM(v, 6,
9274 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9275 PyStructSequence_SET_ITEM(v, 7,
9276 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9277 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9278 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009279#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009280 if (PyErr_Occurred()) {
9281 Py_DECREF(v);
9282 return NULL;
9283 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009284
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009286}
9287
Larry Hastings2f936352014-08-05 14:04:04 +10009288
9289/*[clinic input]
9290os.fstatvfs
9291 fd: int
9292 /
9293
9294Perform an fstatvfs system call on the given fd.
9295
9296Equivalent to statvfs(fd).
9297[clinic start generated code]*/
9298
Larry Hastings2f936352014-08-05 14:04:04 +10009299static PyObject *
9300os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009301/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009302{
9303 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009304 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009306
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009307 do {
9308 Py_BEGIN_ALLOW_THREADS
9309 result = fstatvfs(fd, &st);
9310 Py_END_ALLOW_THREADS
9311 } while (result != 0 && errno == EINTR &&
9312 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009313 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009314 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009315
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009317}
Larry Hastings2f936352014-08-05 14:04:04 +10009318#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009319
9320
Thomas Wouters477c8d52006-05-27 19:21:47 +00009321#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009322#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009323/*[clinic input]
9324os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009325
Larry Hastings2f936352014-08-05 14:04:04 +10009326 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9327
9328Perform a statvfs system call on the given path.
9329
9330path may always be specified as a string.
9331On some platforms, path may also be specified as an open file descriptor.
9332 If this functionality is unavailable, using it raises an exception.
9333[clinic start generated code]*/
9334
Larry Hastings2f936352014-08-05 14:04:04 +10009335static PyObject *
9336os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009337/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009338{
9339 int result;
9340 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009341
9342 Py_BEGIN_ALLOW_THREADS
9343#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009344 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009345#ifdef __APPLE__
9346 /* handle weak-linking on Mac OS X 10.3 */
9347 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009348 fd_specified("statvfs", path->fd);
9349 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009350 }
9351#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009352 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009353 }
9354 else
9355#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009356 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009357 Py_END_ALLOW_THREADS
9358
9359 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009360 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009361 }
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009364}
Larry Hastings2f936352014-08-05 14:04:04 +10009365#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9366
Guido van Rossum94f6f721999-01-06 18:42:14 +00009367
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009368#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009369/*[clinic input]
9370os._getdiskusage
9371
9372 path: Py_UNICODE
9373
9374Return disk usage statistics about the given path as a (total, free) tuple.
9375[clinic start generated code]*/
9376
Larry Hastings2f936352014-08-05 14:04:04 +10009377static PyObject *
9378os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009379/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009380{
9381 BOOL retval;
9382 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009383
9384 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009385 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009386 Py_END_ALLOW_THREADS
9387 if (retval == 0)
9388 return PyErr_SetFromWindowsErr(0);
9389
9390 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9391}
Larry Hastings2f936352014-08-05 14:04:04 +10009392#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009393
9394
Fred Drakec9680921999-12-13 16:37:25 +00009395/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9396 * It maps strings representing configuration variable names to
9397 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009398 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009399 * rarely-used constants. There are three separate tables that use
9400 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009401 *
9402 * This code is always included, even if none of the interfaces that
9403 * need it are included. The #if hackery needed to avoid it would be
9404 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009405 */
9406struct constdef {
9407 char *name;
9408 long value;
9409};
9410
Fred Drake12c6e2d1999-12-14 21:25:03 +00009411static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009412conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009413 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009414{
Christian Heimes217cfd12007-12-02 14:31:20 +00009415 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009416 *valuep = PyLong_AS_LONG(arg);
9417 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009418 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009419 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009420 /* look up the value in the table using a binary search */
9421 size_t lo = 0;
9422 size_t mid;
9423 size_t hi = tablesize;
9424 int cmp;
9425 const char *confname;
9426 if (!PyUnicode_Check(arg)) {
9427 PyErr_SetString(PyExc_TypeError,
9428 "configuration names must be strings or integers");
9429 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009431 confname = _PyUnicode_AsString(arg);
9432 if (confname == NULL)
9433 return 0;
9434 while (lo < hi) {
9435 mid = (lo + hi) / 2;
9436 cmp = strcmp(confname, table[mid].name);
9437 if (cmp < 0)
9438 hi = mid;
9439 else if (cmp > 0)
9440 lo = mid + 1;
9441 else {
9442 *valuep = table[mid].value;
9443 return 1;
9444 }
9445 }
9446 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9447 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009449}
9450
9451
9452#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9453static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009454#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009456#endif
9457#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009459#endif
Fred Drakec9680921999-12-13 16:37:25 +00009460#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
9475#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009477#endif
9478#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009480#endif
9481#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
9484#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
9487#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009505#ifdef _PC_ACL_ENABLED
9506 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9507#endif
9508#ifdef _PC_MIN_HOLE_SIZE
9509 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9510#endif
9511#ifdef _PC_ALLOC_SIZE_MIN
9512 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9513#endif
9514#ifdef _PC_REC_INCR_XFER_SIZE
9515 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9516#endif
9517#ifdef _PC_REC_MAX_XFER_SIZE
9518 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9519#endif
9520#ifdef _PC_REC_MIN_XFER_SIZE
9521 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9522#endif
9523#ifdef _PC_REC_XFER_ALIGN
9524 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9525#endif
9526#ifdef _PC_SYMLINK_MAX
9527 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9528#endif
9529#ifdef _PC_XATTR_ENABLED
9530 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9531#endif
9532#ifdef _PC_XATTR_EXISTS
9533 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9534#endif
9535#ifdef _PC_TIMESTAMP_RESOLUTION
9536 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9537#endif
Fred Drakec9680921999-12-13 16:37:25 +00009538};
9539
Fred Drakec9680921999-12-13 16:37:25 +00009540static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009541conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009542{
9543 return conv_confname(arg, valuep, posix_constants_pathconf,
9544 sizeof(posix_constants_pathconf)
9545 / sizeof(struct constdef));
9546}
9547#endif
9548
Larry Hastings2f936352014-08-05 14:04:04 +10009549
Fred Drakec9680921999-12-13 16:37:25 +00009550#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009551/*[clinic input]
9552os.fpathconf -> long
9553
9554 fd: int
9555 name: path_confname
9556 /
9557
9558Return the configuration limit name for the file descriptor fd.
9559
9560If there is no limit, return -1.
9561[clinic start generated code]*/
9562
Larry Hastings2f936352014-08-05 14:04:04 +10009563static long
9564os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009565/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009566{
9567 long limit;
9568
9569 errno = 0;
9570 limit = fpathconf(fd, name);
9571 if (limit == -1 && errno != 0)
9572 posix_error();
9573
9574 return limit;
9575}
9576#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009577
9578
9579#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009580/*[clinic input]
9581os.pathconf -> long
9582 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9583 name: path_confname
9584
9585Return the configuration limit name for the file or directory path.
9586
9587If there is no limit, return -1.
9588On some platforms, path may also be specified as an open file descriptor.
9589 If this functionality is unavailable, using it raises an exception.
9590[clinic start generated code]*/
9591
Larry Hastings2f936352014-08-05 14:04:04 +10009592static long
9593os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009594/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009595{
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009597
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009599#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009600 if (path->fd != -1)
9601 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009602 else
9603#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009604 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 if (limit == -1 && errno != 0) {
9606 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009607 /* could be a path or name problem */
9608 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009609 else
Larry Hastings2f936352014-08-05 14:04:04 +10009610 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 }
Larry Hastings2f936352014-08-05 14:04:04 +10009612
9613 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009614}
Larry Hastings2f936352014-08-05 14:04:04 +10009615#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009616
9617#ifdef HAVE_CONFSTR
9618static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009619#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009621#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009622#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009624#endif
9625#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009627#endif
Fred Draked86ed291999-12-15 15:34:33 +00009628#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009630#endif
9631#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
9634#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009636#endif
9637#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
Fred Drakec9680921999-12-13 16:37:25 +00009640#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
9649#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
9652#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
9661#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
Fred Draked86ed291999-12-15 15:34:33 +00009664#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009666#endif
Fred Drakec9680921999-12-13 16:37:25 +00009667#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
Fred Draked86ed291999-12-15 15:34:33 +00009670#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009672#endif
9673#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009675#endif
9676#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009678#endif
9679#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009681#endif
Fred Drakec9680921999-12-13 16:37:25 +00009682#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
9691#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009693#endif
9694#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
9712#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
9718#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
Fred Draked86ed291999-12-15 15:34:33 +00009730#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009732#endif
9733#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
9736#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009738#endif
9739#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009741#endif
9742#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009744#endif
9745#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009747#endif
9748#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009750#endif
9751#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009753#endif
9754#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009756#endif
9757#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009759#endif
9760#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009762#endif
9763#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009765#endif
9766#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009768#endif
Fred Drakec9680921999-12-13 16:37:25 +00009769};
9770
9771static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009772conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009773{
9774 return conv_confname(arg, valuep, posix_constants_confstr,
9775 sizeof(posix_constants_confstr)
9776 / sizeof(struct constdef));
9777}
9778
Larry Hastings2f936352014-08-05 14:04:04 +10009779
9780/*[clinic input]
9781os.confstr
9782
9783 name: confstr_confname
9784 /
9785
9786Return a string-valued system configuration variable.
9787[clinic start generated code]*/
9788
Larry Hastings2f936352014-08-05 14:04:04 +10009789static PyObject *
9790os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009791/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009792{
9793 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009794 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009795 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009796
Victor Stinnercb043522010-09-10 23:49:04 +00009797 errno = 0;
9798 len = confstr(name, buffer, sizeof(buffer));
9799 if (len == 0) {
9800 if (errno) {
9801 posix_error();
9802 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009803 }
9804 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009805 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009806 }
9807 }
Victor Stinnercb043522010-09-10 23:49:04 +00009808
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009809 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009810 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009811 char *buf = PyMem_Malloc(len);
9812 if (buf == NULL)
9813 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009814 len2 = confstr(name, buf, len);
9815 assert(len == len2);
Victor Stinnercb043522010-09-10 23:49:04 +00009816 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9817 PyMem_Free(buf);
9818 }
9819 else
9820 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009821 return result;
9822}
Larry Hastings2f936352014-08-05 14:04:04 +10009823#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009824
9825
9826#ifdef HAVE_SYSCONF
9827static struct constdef posix_constants_sysconf[] = {
9828#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
Fred Draked86ed291999-12-15 15:34:33 +00009858#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009860#endif
9861#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009863#endif
Fred Drakec9680921999-12-13 16:37:25 +00009864#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
Fred Drakec9680921999-12-13 16:37:25 +00009867#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
Fred Draked86ed291999-12-15 15:34:33 +00009882#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009884#endif
Fred Drakec9680921999-12-13 16:37:25 +00009885#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
Fred Draked86ed291999-12-15 15:34:33 +00009900#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009902#endif
Fred Drakec9680921999-12-13 16:37:25 +00009903#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
Fred Draked86ed291999-12-15 15:34:33 +00009972#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
Fred Drakec9680921999-12-13 16:37:25 +00009975#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
Fred Draked86ed291999-12-15 15:34:33 +00009984#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009986#endif
Fred Drakec9680921999-12-13 16:37:25 +00009987#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
Fred Draked86ed291999-12-15 15:34:33 +00009990#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009992#endif
9993#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009995#endif
Fred Drakec9680921999-12-13 16:37:25 +00009996#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
Fred Draked86ed291999-12-15 15:34:33 +000010008#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010010#endif
Fred Drakec9680921999-12-13 16:37:25 +000010011#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
Fred Draked86ed291999-12-15 15:34:33 +000010032#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
Fred Drakec9680921999-12-13 16:37:25 +000010035#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
Fred Draked86ed291999-12-15 15:34:33 +000010041#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
Fred Drakec9680921999-12-13 16:37:25 +000010044#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
Fred Draked86ed291999-12-15 15:34:33 +000010071#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010073#endif
10074#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010076#endif
Fred Drakec9680921999-12-13 16:37:25 +000010077#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
Fred Draked86ed291999-12-15 15:34:33 +000010182#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010184#endif
Fred Drakec9680921999-12-13 16:37:25 +000010185#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320};
10321
10322static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010323conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010324{
10325 return conv_confname(arg, valuep, posix_constants_sysconf,
10326 sizeof(posix_constants_sysconf)
10327 / sizeof(struct constdef));
10328}
10329
Larry Hastings2f936352014-08-05 14:04:04 +100010330
10331/*[clinic input]
10332os.sysconf -> long
10333 name: sysconf_confname
10334 /
10335
10336Return an integer-valued system configuration variable.
10337[clinic start generated code]*/
10338
Larry Hastings2f936352014-08-05 14:04:04 +100010339static long
10340os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010341/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010342{
10343 long value;
10344
10345 errno = 0;
10346 value = sysconf(name);
10347 if (value == -1 && errno != 0)
10348 posix_error();
10349 return value;
10350}
10351#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010352
10353
Fred Drakebec628d1999-12-15 18:31:10 +000010354/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010355 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010356 * the exported dictionaries that are used to publish information about the
10357 * names available on the host platform.
10358 *
10359 * Sorting the table at runtime ensures that the table is properly ordered
10360 * when used, even for platforms we're not able to test on. It also makes
10361 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010362 */
Fred Drakebec628d1999-12-15 18:31:10 +000010363
10364static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010365cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010366{
10367 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010369 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010371
10372 return strcmp(c1->name, c2->name);
10373}
10374
10375static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010376setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010378{
Fred Drakebec628d1999-12-15 18:31:10 +000010379 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010380 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010381
10382 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10383 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010384 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010386
Barry Warsaw3155db32000-04-13 15:20:40 +000010387 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 PyObject *o = PyLong_FromLong(table[i].value);
10389 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10390 Py_XDECREF(o);
10391 Py_DECREF(d);
10392 return -1;
10393 }
10394 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010395 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010396 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010397}
10398
Fred Drakebec628d1999-12-15 18:31:10 +000010399/* Return -1 on failure, 0 on success. */
10400static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010401setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010402{
10403#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010404 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010405 sizeof(posix_constants_pathconf)
10406 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010407 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010408 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010409#endif
10410#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010411 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010412 sizeof(posix_constants_confstr)
10413 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010414 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010415 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010416#endif
10417#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010418 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010419 sizeof(posix_constants_sysconf)
10420 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010421 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010422 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010423#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010424 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010425}
Fred Draked86ed291999-12-15 15:34:33 +000010426
10427
Larry Hastings2f936352014-08-05 14:04:04 +100010428/*[clinic input]
10429os.abort
10430
10431Abort the interpreter immediately.
10432
10433This function 'dumps core' or otherwise fails in the hardest way possible
10434on the hosting operating system. This function never returns.
10435[clinic start generated code]*/
10436
Larry Hastings2f936352014-08-05 14:04:04 +100010437static PyObject *
10438os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010439/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010440{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010441 abort();
10442 /*NOTREACHED*/
10443 Py_FatalError("abort() called from Python code didn't abort!");
10444 return NULL;
10445}
Fred Drakebec628d1999-12-15 18:31:10 +000010446
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010447#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010448/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010449PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010450"startfile(filepath [, operation])\n\
10451\n\
10452Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010453\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010454When \"operation\" is not specified or \"open\", this acts like\n\
10455double-clicking the file in Explorer, or giving the file name as an\n\
10456argument to the DOS \"start\" command: the file is opened with whatever\n\
10457application (if any) its extension is associated.\n\
10458When another \"operation\" is given, it specifies what should be done with\n\
10459the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010460\n\
10461startfile returns as soon as the associated application is launched.\n\
10462There is no option to wait for the application to close, and no way\n\
10463to retrieve the application's exit status.\n\
10464\n\
10465The filepath is relative to the current directory. If you want to use\n\
10466an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010467the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010468
Steve Dower7d0e0c92015-01-24 08:18:24 -080010469/* Grab ShellExecute dynamically from shell32 */
10470static int has_ShellExecute = -1;
10471static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10472 LPCSTR, INT);
10473static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10474 LPCWSTR, INT);
10475static int
10476check_ShellExecute()
10477{
10478 HINSTANCE hShell32;
10479
10480 /* only recheck */
10481 if (-1 == has_ShellExecute) {
10482 Py_BEGIN_ALLOW_THREADS
10483 hShell32 = LoadLibraryW(L"SHELL32");
10484 Py_END_ALLOW_THREADS
10485 if (hShell32) {
10486 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10487 "ShellExecuteA");
10488 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10489 "ShellExecuteW");
10490 has_ShellExecute = Py_ShellExecuteA &&
10491 Py_ShellExecuteW;
10492 } else {
10493 has_ShellExecute = 0;
10494 }
10495 }
10496 return has_ShellExecute;
10497}
10498
10499
Tim Petersf58a7aa2000-09-22 10:05:54 +000010500static PyObject *
10501win32_startfile(PyObject *self, PyObject *args)
10502{
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 PyObject *ofilepath;
10504 char *filepath;
10505 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010506 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010508
Victor Stinnereb5657a2011-09-30 01:44:27 +020010509 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010510
10511 if(!check_ShellExecute()) {
10512 /* If the OS doesn't have ShellExecute, return a
10513 NotImplementedError. */
10514 return PyErr_Format(PyExc_NotImplementedError,
10515 "startfile not available on this platform");
10516 }
10517
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 if (!PyArg_ParseTuple(args, "U|s:startfile",
10519 &unipath, &operation)) {
10520 PyErr_Clear();
10521 goto normal;
10522 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010523
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010525 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010527 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 PyErr_Clear();
10529 operation = NULL;
10530 goto normal;
10531 }
10532 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010533
Victor Stinnereb5657a2011-09-30 01:44:27 +020010534 wpath = PyUnicode_AsUnicode(unipath);
10535 if (wpath == NULL)
10536 goto normal;
10537 if (uoperation) {
10538 woperation = PyUnicode_AsUnicode(uoperation);
10539 if (woperation == NULL)
10540 goto normal;
10541 }
10542 else
10543 woperation = NULL;
10544
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010546 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10547 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 Py_END_ALLOW_THREADS
10549
Victor Stinnereb5657a2011-09-30 01:44:27 +020010550 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010552 win32_error_object("startfile", unipath);
10553 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 }
10555 Py_INCREF(Py_None);
10556 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010557
10558normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10560 PyUnicode_FSConverter, &ofilepath,
10561 &operation))
10562 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010563 if (win32_warn_bytes_api()) {
10564 Py_DECREF(ofilepath);
10565 return NULL;
10566 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 filepath = PyBytes_AsString(ofilepath);
10568 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010569 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10570 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 Py_END_ALLOW_THREADS
10572 if (rc <= (HINSTANCE)32) {
10573 PyObject *errval = win32_error("startfile", filepath);
10574 Py_DECREF(ofilepath);
10575 return errval;
10576 }
10577 Py_DECREF(ofilepath);
10578 Py_INCREF(Py_None);
10579 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010580}
Larry Hastings2f936352014-08-05 14:04:04 +100010581#endif /* MS_WINDOWS */
10582
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010583
Martin v. Löwis438b5342002-12-27 10:16:42 +000010584#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010585/*[clinic input]
10586os.getloadavg
10587
10588Return average recent system load information.
10589
10590Return the number of processes in the system run queue averaged over
10591the last 1, 5, and 15 minutes as a tuple of three floats.
10592Raises OSError if the load average was unobtainable.
10593[clinic start generated code]*/
10594
Larry Hastings2f936352014-08-05 14:04:04 +100010595static PyObject *
10596os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010597/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010598{
10599 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010600 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010601 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10602 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010603 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010604 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010605}
Larry Hastings2f936352014-08-05 14:04:04 +100010606#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010607
Larry Hastings2f936352014-08-05 14:04:04 +100010608
10609/*[clinic input]
10610os.device_encoding
10611 fd: int
10612
10613Return a string describing the encoding of a terminal's file descriptor.
10614
10615The file descriptor must be attached to a terminal.
10616If the device is not a terminal, return None.
10617[clinic start generated code]*/
10618
Larry Hastings2f936352014-08-05 14:04:04 +100010619static PyObject *
10620os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010621/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010622{
Brett Cannonefb00c02012-02-29 18:31:31 -050010623 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010624}
10625
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010626
Larry Hastings2f936352014-08-05 14:04:04 +100010627#ifdef HAVE_SETRESUID
10628/*[clinic input]
10629os.setresuid
10630
10631 ruid: uid_t
10632 euid: uid_t
10633 suid: uid_t
10634 /
10635
10636Set the current process's real, effective, and saved user ids.
10637[clinic start generated code]*/
10638
Larry Hastings2f936352014-08-05 14:04:04 +100010639static PyObject *
10640os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010641/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010642{
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 if (setresuid(ruid, euid, suid) < 0)
10644 return posix_error();
10645 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010646}
Larry Hastings2f936352014-08-05 14:04:04 +100010647#endif /* HAVE_SETRESUID */
10648
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010649
10650#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010651/*[clinic input]
10652os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010653
Larry Hastings2f936352014-08-05 14:04:04 +100010654 rgid: gid_t
10655 egid: gid_t
10656 sgid: gid_t
10657 /
10658
10659Set the current process's real, effective, and saved group ids.
10660[clinic start generated code]*/
10661
Larry Hastings2f936352014-08-05 14:04:04 +100010662static PyObject *
10663os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010664/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010665{
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 if (setresgid(rgid, egid, sgid) < 0)
10667 return posix_error();
10668 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010669}
Larry Hastings2f936352014-08-05 14:04:04 +100010670#endif /* HAVE_SETRESGID */
10671
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010672
10673#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010674/*[clinic input]
10675os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010676
Larry Hastings2f936352014-08-05 14:04:04 +100010677Return a tuple of the current process's real, effective, and saved user ids.
10678[clinic start generated code]*/
10679
Larry Hastings2f936352014-08-05 14:04:04 +100010680static PyObject *
10681os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010682/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010683{
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 if (getresuid(&ruid, &euid, &suid) < 0)
10686 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010687 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10688 _PyLong_FromUid(euid),
10689 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010690}
Larry Hastings2f936352014-08-05 14:04:04 +100010691#endif /* HAVE_GETRESUID */
10692
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010693
10694#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010695/*[clinic input]
10696os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010697
Larry Hastings2f936352014-08-05 14:04:04 +100010698Return a tuple of the current process's real, effective, and saved group ids.
10699[clinic start generated code]*/
10700
Larry Hastings2f936352014-08-05 14:04:04 +100010701static PyObject *
10702os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010703/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010704{
10705 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 if (getresgid(&rgid, &egid, &sgid) < 0)
10707 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010708 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10709 _PyLong_FromGid(egid),
10710 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010711}
Larry Hastings2f936352014-08-05 14:04:04 +100010712#endif /* HAVE_GETRESGID */
10713
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010714
Benjamin Peterson9428d532011-09-14 11:45:52 -040010715#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010716/*[clinic input]
10717os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010718
Larry Hastings2f936352014-08-05 14:04:04 +100010719 path: path_t(allow_fd=True)
10720 attribute: path_t
10721 *
10722 follow_symlinks: bool = True
10723
10724Return the value of extended attribute attribute on path.
10725
10726path may be either a string or an open file descriptor.
10727If follow_symlinks is False, and the last element of the path is a symbolic
10728 link, getxattr will examine the symbolic link itself instead of the file
10729 the link points to.
10730
10731[clinic start generated code]*/
10732
Larry Hastings2f936352014-08-05 14:04:04 +100010733static PyObject *
10734os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010735/*[clinic end generated code: output=d90086b314859f8b input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010736{
10737 Py_ssize_t i;
10738 PyObject *buffer = NULL;
10739
10740 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10741 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 for (i = 0; ; i++) {
10744 void *ptr;
10745 ssize_t result;
10746 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10747 Py_ssize_t buffer_size = buffer_sizes[i];
10748 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010749 path_error(path);
10750 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 }
10752 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10753 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010754 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010756
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010758 if (path->fd >= 0)
10759 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010761 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762 else
Larry Hastings2f936352014-08-05 14:04:04 +100010763 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010764 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010765
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766 if (result < 0) {
10767 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 if (errno == ERANGE)
10769 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010770 path_error(path);
10771 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010773
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 if (result != buffer_size) {
10775 /* Can only shrink. */
10776 _PyBytes_Resize(&buffer, result);
10777 }
10778 break;
10779 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010780
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782}
10783
Larry Hastings2f936352014-08-05 14:04:04 +100010784
10785/*[clinic input]
10786os.setxattr
10787
10788 path: path_t(allow_fd=True)
10789 attribute: path_t
10790 value: Py_buffer
10791 flags: int = 0
10792 *
10793 follow_symlinks: bool = True
10794
10795Set extended attribute attribute on path to value.
10796
10797path may be either a string or an open file descriptor.
10798If follow_symlinks is False, and the last element of the path is a symbolic
10799 link, setxattr will modify the symbolic link itself instead of the file
10800 the link points to.
10801
10802[clinic start generated code]*/
10803
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010805os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010806/*[clinic end generated code: output=e3defa5c4b1ad0ae input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010807{
Larry Hastings2f936352014-08-05 14:04:04 +100010808 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809
Larry Hastings2f936352014-08-05 14:04:04 +100010810 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010811 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010812
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010814 if (path->fd > -1)
10815 result = fsetxattr(path->fd, attribute->narrow,
10816 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010818 result = setxattr(path->narrow, attribute->narrow,
10819 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 else
Larry Hastings2f936352014-08-05 14:04:04 +100010821 result = lsetxattr(path->narrow, attribute->narrow,
10822 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010824
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010826 path_error(path);
10827 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010828 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010829
Larry Hastings2f936352014-08-05 14:04:04 +100010830 Py_RETURN_NONE;
10831}
10832
10833
10834/*[clinic input]
10835os.removexattr
10836
10837 path: path_t(allow_fd=True)
10838 attribute: path_t
10839 *
10840 follow_symlinks: bool = True
10841
10842Remove extended attribute attribute on path.
10843
10844path may be either a string or an open file descriptor.
10845If follow_symlinks is False, and the last element of the path is a symbolic
10846 link, removexattr will modify the symbolic link itself instead of the file
10847 the link points to.
10848
10849[clinic start generated code]*/
10850
Larry Hastings2f936352014-08-05 14:04:04 +100010851static PyObject *
10852os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010853/*[clinic end generated code: output=4870ec90249af875 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010854{
10855 ssize_t result;
10856
10857 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10858 return NULL;
10859
10860 Py_BEGIN_ALLOW_THREADS;
10861 if (path->fd > -1)
10862 result = fremovexattr(path->fd, attribute->narrow);
10863 else if (follow_symlinks)
10864 result = removexattr(path->narrow, attribute->narrow);
10865 else
10866 result = lremovexattr(path->narrow, attribute->narrow);
10867 Py_END_ALLOW_THREADS;
10868
10869 if (result) {
10870 return path_error(path);
10871 }
10872
10873 Py_RETURN_NONE;
10874}
10875
10876
10877/*[clinic input]
10878os.listxattr
10879
10880 path: path_t(allow_fd=True, nullable=True) = None
10881 *
10882 follow_symlinks: bool = True
10883
10884Return a list of extended attributes on path.
10885
10886path may be either None, a string, or an open file descriptor.
10887if path is None, listxattr will examine the current directory.
10888If follow_symlinks is False, and the last element of the path is a symbolic
10889 link, listxattr will examine the symbolic link itself instead of the file
10890 the link points to.
10891[clinic start generated code]*/
10892
Larry Hastings2f936352014-08-05 14:04:04 +100010893static PyObject *
10894os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010895/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010896{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010897 Py_ssize_t i;
10898 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010899 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010900 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010901
Larry Hastings2f936352014-08-05 14:04:04 +100010902 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010903 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904
Larry Hastings2f936352014-08-05 14:04:04 +100010905 name = path->narrow ? path->narrow : ".";
10906
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 for (i = 0; ; i++) {
10908 char *start, *trace, *end;
10909 ssize_t length;
10910 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10911 Py_ssize_t buffer_size = buffer_sizes[i];
10912 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010913 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010914 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010915 break;
10916 }
10917 buffer = PyMem_MALLOC(buffer_size);
10918 if (!buffer) {
10919 PyErr_NoMemory();
10920 break;
10921 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010922
Larry Hastings9cf065c2012-06-22 16:30:09 -070010923 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010924 if (path->fd > -1)
10925 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926 else if (follow_symlinks)
10927 length = listxattr(name, buffer, buffer_size);
10928 else
10929 length = llistxattr(name, buffer, buffer_size);
10930 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010931
Larry Hastings9cf065c2012-06-22 16:30:09 -070010932 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010933 if (errno == ERANGE) {
10934 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010935 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010936 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010937 }
Larry Hastings2f936352014-08-05 14:04:04 +100010938 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010939 break;
10940 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010941
Larry Hastings9cf065c2012-06-22 16:30:09 -070010942 result = PyList_New(0);
10943 if (!result) {
10944 goto exit;
10945 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010946
Larry Hastings9cf065c2012-06-22 16:30:09 -070010947 end = buffer + length;
10948 for (trace = start = buffer; trace != end; trace++) {
10949 if (!*trace) {
10950 int error;
10951 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10952 trace - start);
10953 if (!attribute) {
10954 Py_DECREF(result);
10955 result = NULL;
10956 goto exit;
10957 }
10958 error = PyList_Append(result, attribute);
10959 Py_DECREF(attribute);
10960 if (error) {
10961 Py_DECREF(result);
10962 result = NULL;
10963 goto exit;
10964 }
10965 start = trace + 1;
10966 }
10967 }
10968 break;
10969 }
10970exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010971 if (buffer)
10972 PyMem_FREE(buffer);
10973 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010974}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010975#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010976
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010977
Larry Hastings2f936352014-08-05 14:04:04 +100010978/*[clinic input]
10979os.urandom
10980
10981 size: Py_ssize_t
10982 /
10983
10984Return a bytes object containing random bytes suitable for cryptographic use.
10985[clinic start generated code]*/
10986
Larry Hastings2f936352014-08-05 14:04:04 +100010987static PyObject *
10988os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010989/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010990{
10991 PyObject *bytes;
10992 int result;
10993
Georg Brandl2fb477c2012-02-21 00:33:36 +010010994 if (size < 0)
10995 return PyErr_Format(PyExc_ValueError,
10996 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010997 bytes = PyBytes_FromStringAndSize(NULL, size);
10998 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010999 return NULL;
11000
Larry Hastings2f936352014-08-05 14:04:04 +100011001 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11002 PyBytes_GET_SIZE(bytes));
11003 if (result == -1) {
11004 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011005 return NULL;
11006 }
Larry Hastings2f936352014-08-05 14:04:04 +100011007 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011008}
11009
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011010/* Terminal size querying */
11011
11012static PyTypeObject TerminalSizeType;
11013
11014PyDoc_STRVAR(TerminalSize_docstring,
11015 "A tuple of (columns, lines) for holding terminal window size");
11016
11017static PyStructSequence_Field TerminalSize_fields[] = {
11018 {"columns", "width of the terminal window in characters"},
11019 {"lines", "height of the terminal window in characters"},
11020 {NULL, NULL}
11021};
11022
11023static PyStructSequence_Desc TerminalSize_desc = {
11024 "os.terminal_size",
11025 TerminalSize_docstring,
11026 TerminalSize_fields,
11027 2,
11028};
11029
11030#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011031/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011032PyDoc_STRVAR(termsize__doc__,
11033 "Return the size of the terminal window as (columns, lines).\n" \
11034 "\n" \
11035 "The optional argument fd (default standard output) specifies\n" \
11036 "which file descriptor should be queried.\n" \
11037 "\n" \
11038 "If the file descriptor is not connected to a terminal, an OSError\n" \
11039 "is thrown.\n" \
11040 "\n" \
11041 "This function will only be defined if an implementation is\n" \
11042 "available for this system.\n" \
11043 "\n" \
11044 "shutil.get_terminal_size is the high-level function which should \n" \
11045 "normally be used, os.get_terminal_size is the low-level implementation.");
11046
11047static PyObject*
11048get_terminal_size(PyObject *self, PyObject *args)
11049{
11050 int columns, lines;
11051 PyObject *termsize;
11052
11053 int fd = fileno(stdout);
11054 /* Under some conditions stdout may not be connected and
11055 * fileno(stdout) may point to an invalid file descriptor. For example
11056 * GUI apps don't have valid standard streams by default.
11057 *
11058 * If this happens, and the optional fd argument is not present,
11059 * the ioctl below will fail returning EBADF. This is what we want.
11060 */
11061
11062 if (!PyArg_ParseTuple(args, "|i", &fd))
11063 return NULL;
11064
11065#ifdef TERMSIZE_USE_IOCTL
11066 {
11067 struct winsize w;
11068 if (ioctl(fd, TIOCGWINSZ, &w))
11069 return PyErr_SetFromErrno(PyExc_OSError);
11070 columns = w.ws_col;
11071 lines = w.ws_row;
11072 }
11073#endif /* TERMSIZE_USE_IOCTL */
11074
11075#ifdef TERMSIZE_USE_CONIO
11076 {
11077 DWORD nhandle;
11078 HANDLE handle;
11079 CONSOLE_SCREEN_BUFFER_INFO csbi;
11080 switch (fd) {
11081 case 0: nhandle = STD_INPUT_HANDLE;
11082 break;
11083 case 1: nhandle = STD_OUTPUT_HANDLE;
11084 break;
11085 case 2: nhandle = STD_ERROR_HANDLE;
11086 break;
11087 default:
11088 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11089 }
11090 handle = GetStdHandle(nhandle);
11091 if (handle == NULL)
11092 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11093 if (handle == INVALID_HANDLE_VALUE)
11094 return PyErr_SetFromWindowsErr(0);
11095
11096 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11097 return PyErr_SetFromWindowsErr(0);
11098
11099 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11100 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11101 }
11102#endif /* TERMSIZE_USE_CONIO */
11103
11104 termsize = PyStructSequence_New(&TerminalSizeType);
11105 if (termsize == NULL)
11106 return NULL;
11107 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11108 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11109 if (PyErr_Occurred()) {
11110 Py_DECREF(termsize);
11111 return NULL;
11112 }
11113 return termsize;
11114}
11115#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11116
Larry Hastings2f936352014-08-05 14:04:04 +100011117
11118/*[clinic input]
11119os.cpu_count
11120
11121Return the number of CPUs in the system; return None if indeterminable.
11122[clinic start generated code]*/
11123
Larry Hastings2f936352014-08-05 14:04:04 +100011124static PyObject *
11125os_cpu_count_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011126/*[clinic end generated code: output=c59ee7f6bce832b8 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011127{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011128 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011129#ifdef MS_WINDOWS
11130 SYSTEM_INFO sysinfo;
11131 GetSystemInfo(&sysinfo);
11132 ncpu = sysinfo.dwNumberOfProcessors;
11133#elif defined(__hpux)
11134 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11135#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11136 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011137#elif defined(__DragonFly__) || \
11138 defined(__OpenBSD__) || \
11139 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011140 defined(__NetBSD__) || \
11141 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011142 int mib[2];
11143 size_t len = sizeof(ncpu);
11144 mib[0] = CTL_HW;
11145 mib[1] = HW_NCPU;
11146 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11147 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011148#endif
11149 if (ncpu >= 1)
11150 return PyLong_FromLong(ncpu);
11151 else
11152 Py_RETURN_NONE;
11153}
11154
Victor Stinnerdaf45552013-08-28 00:53:59 +020011155
Larry Hastings2f936352014-08-05 14:04:04 +100011156/*[clinic input]
11157os.get_inheritable -> bool
11158
11159 fd: int
11160 /
11161
11162Get the close-on-exe flag of the specified file descriptor.
11163[clinic start generated code]*/
11164
Larry Hastings2f936352014-08-05 14:04:04 +100011165static int
11166os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011167/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011168{
11169 if (!_PyVerify_fd(fd)){
11170 posix_error();
11171 return -1;
11172 }
11173
11174 return _Py_get_inheritable(fd);
11175}
11176
11177
11178/*[clinic input]
11179os.set_inheritable
11180 fd: int
11181 inheritable: int
11182 /
11183
11184Set the inheritable flag of the specified file descriptor.
11185[clinic start generated code]*/
11186
Larry Hastings2f936352014-08-05 14:04:04 +100011187static PyObject *
11188os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011189/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011190{
Victor Stinnerdaf45552013-08-28 00:53:59 +020011191 if (!_PyVerify_fd(fd))
11192 return posix_error();
11193
11194 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11195 return NULL;
11196 Py_RETURN_NONE;
11197}
11198
11199
11200#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011201/*[clinic input]
11202os.get_handle_inheritable -> bool
11203 handle: Py_intptr_t
11204 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011205
Larry Hastings2f936352014-08-05 14:04:04 +100011206Get the close-on-exe flag of the specified file descriptor.
11207[clinic start generated code]*/
11208
Larry Hastings2f936352014-08-05 14:04:04 +100011209static int
11210os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011211/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011212{
11213 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011214
11215 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11216 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011217 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011218 }
11219
Larry Hastings2f936352014-08-05 14:04:04 +100011220 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011221}
11222
Victor Stinnerdaf45552013-08-28 00:53:59 +020011223
Larry Hastings2f936352014-08-05 14:04:04 +100011224/*[clinic input]
11225os.set_handle_inheritable
11226 handle: Py_intptr_t
11227 inheritable: bool
11228 /
11229
11230Set the inheritable flag of the specified handle.
11231[clinic start generated code]*/
11232
Larry Hastings2f936352014-08-05 14:04:04 +100011233static PyObject *
11234os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011235/*[clinic end generated code: output=627aa5b158b69338 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011236{
11237 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011238 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11239 PyErr_SetFromWindowsErr(0);
11240 return NULL;
11241 }
11242 Py_RETURN_NONE;
11243}
Larry Hastings2f936352014-08-05 14:04:04 +100011244#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011245
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011246#ifndef MS_WINDOWS
11247PyDoc_STRVAR(get_blocking__doc__,
11248 "get_blocking(fd) -> bool\n" \
11249 "\n" \
11250 "Get the blocking mode of the file descriptor:\n" \
11251 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11252
11253static PyObject*
11254posix_get_blocking(PyObject *self, PyObject *args)
11255{
11256 int fd;
11257 int blocking;
11258
11259 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11260 return NULL;
11261
11262 if (!_PyVerify_fd(fd))
11263 return posix_error();
11264
11265 blocking = _Py_get_blocking(fd);
11266 if (blocking < 0)
11267 return NULL;
11268 return PyBool_FromLong(blocking);
11269}
11270
11271PyDoc_STRVAR(set_blocking__doc__,
11272 "set_blocking(fd, blocking)\n" \
11273 "\n" \
11274 "Set the blocking mode of the specified file descriptor.\n" \
11275 "Set the O_NONBLOCK flag if blocking is False,\n" \
11276 "clear the O_NONBLOCK flag otherwise.");
11277
11278static PyObject*
11279posix_set_blocking(PyObject *self, PyObject *args)
11280{
11281 int fd, blocking;
11282
11283 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11284 return NULL;
11285
11286 if (!_PyVerify_fd(fd))
11287 return posix_error();
11288
11289 if (_Py_set_blocking(fd, blocking) < 0)
11290 return NULL;
11291 Py_RETURN_NONE;
11292}
11293#endif /* !MS_WINDOWS */
11294
11295
Victor Stinner6036e442015-03-08 01:58:04 +010011296PyDoc_STRVAR(posix_scandir__doc__,
11297"scandir(path='.') -> iterator of DirEntry objects for given path");
11298
11299static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11300
11301typedef struct {
11302 PyObject_HEAD
11303 PyObject *name;
11304 PyObject *path;
11305 PyObject *stat;
11306 PyObject *lstat;
11307#ifdef MS_WINDOWS
11308 struct _Py_stat_struct win32_lstat;
11309 __int64 win32_file_index;
11310 int got_file_index;
11311#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011312#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011313 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011314#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011315 ino_t d_ino;
11316#endif
11317} DirEntry;
11318
11319static void
11320DirEntry_dealloc(DirEntry *entry)
11321{
11322 Py_XDECREF(entry->name);
11323 Py_XDECREF(entry->path);
11324 Py_XDECREF(entry->stat);
11325 Py_XDECREF(entry->lstat);
11326 Py_TYPE(entry)->tp_free((PyObject *)entry);
11327}
11328
11329/* Forward reference */
11330static int
11331DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11332
11333/* Set exception and return -1 on error, 0 for False, 1 for True */
11334static int
11335DirEntry_is_symlink(DirEntry *self)
11336{
11337#ifdef MS_WINDOWS
11338 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011339#elif defined(HAVE_DIRENT_D_TYPE)
11340 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011341 if (self->d_type != DT_UNKNOWN)
11342 return self->d_type == DT_LNK;
11343 else
11344 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011345#else
11346 /* POSIX without d_type */
11347 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011348#endif
11349}
11350
11351static PyObject *
11352DirEntry_py_is_symlink(DirEntry *self)
11353{
11354 int result;
11355
11356 result = DirEntry_is_symlink(self);
11357 if (result == -1)
11358 return NULL;
11359 return PyBool_FromLong(result);
11360}
11361
11362static PyObject *
11363DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11364{
11365 int result;
11366 struct _Py_stat_struct st;
11367
11368#ifdef MS_WINDOWS
11369 wchar_t *path;
11370
11371 path = PyUnicode_AsUnicode(self->path);
11372 if (!path)
11373 return NULL;
11374
11375 if (follow_symlinks)
11376 result = win32_stat_w(path, &st);
11377 else
11378 result = win32_lstat_w(path, &st);
11379
11380 if (result != 0) {
11381 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11382 0, self->path);
11383 }
11384#else /* POSIX */
11385 PyObject *bytes;
11386 char *path;
11387
11388 if (!PyUnicode_FSConverter(self->path, &bytes))
11389 return NULL;
11390 path = PyBytes_AS_STRING(bytes);
11391
11392 if (follow_symlinks)
11393 result = STAT(path, &st);
11394 else
11395 result = LSTAT(path, &st);
11396 Py_DECREF(bytes);
11397
11398 if (result != 0)
11399 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11400#endif
11401
11402 return _pystat_fromstructstat(&st);
11403}
11404
11405static PyObject *
11406DirEntry_get_lstat(DirEntry *self)
11407{
11408 if (!self->lstat) {
11409#ifdef MS_WINDOWS
11410 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11411#else /* POSIX */
11412 self->lstat = DirEntry_fetch_stat(self, 0);
11413#endif
11414 }
11415 Py_XINCREF(self->lstat);
11416 return self->lstat;
11417}
11418
11419static PyObject *
11420DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11421{
11422 if (!follow_symlinks)
11423 return DirEntry_get_lstat(self);
11424
11425 if (!self->stat) {
11426 int result = DirEntry_is_symlink(self);
11427 if (result == -1)
11428 return NULL;
11429 else if (result)
11430 self->stat = DirEntry_fetch_stat(self, 1);
11431 else
11432 self->stat = DirEntry_get_lstat(self);
11433 }
11434
11435 Py_XINCREF(self->stat);
11436 return self->stat;
11437}
11438
11439static PyObject *
11440DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11441{
11442 int follow_symlinks = 1;
11443
11444 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11445 follow_symlinks_keywords, &follow_symlinks))
11446 return NULL;
11447
11448 return DirEntry_get_stat(self, follow_symlinks);
11449}
11450
11451/* Set exception and return -1 on error, 0 for False, 1 for True */
11452static int
11453DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11454{
11455 PyObject *stat = NULL;
11456 PyObject *st_mode = NULL;
11457 long mode;
11458 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011459#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011460 int is_symlink;
11461 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011462#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011463#ifdef MS_WINDOWS
11464 unsigned long dir_bits;
11465#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011466 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011467
11468#ifdef MS_WINDOWS
11469 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11470 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011471#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011472 is_symlink = self->d_type == DT_LNK;
11473 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11474#endif
11475
Victor Stinner35a97c02015-03-08 02:59:09 +010011476#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011477 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011478#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011479 stat = DirEntry_get_stat(self, follow_symlinks);
11480 if (!stat) {
11481 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11482 /* If file doesn't exist (anymore), then return False
11483 (i.e., say it's not a file/directory) */
11484 PyErr_Clear();
11485 return 0;
11486 }
11487 goto error;
11488 }
11489 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11490 if (!st_mode)
11491 goto error;
11492
11493 mode = PyLong_AsLong(st_mode);
11494 if (mode == -1 && PyErr_Occurred())
11495 goto error;
11496 Py_CLEAR(st_mode);
11497 Py_CLEAR(stat);
11498 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011499#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011500 }
11501 else if (is_symlink) {
11502 assert(mode_bits != S_IFLNK);
11503 result = 0;
11504 }
11505 else {
11506 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11507#ifdef MS_WINDOWS
11508 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11509 if (mode_bits == S_IFDIR)
11510 result = dir_bits != 0;
11511 else
11512 result = dir_bits == 0;
11513#else /* POSIX */
11514 if (mode_bits == S_IFDIR)
11515 result = self->d_type == DT_DIR;
11516 else
11517 result = self->d_type == DT_REG;
11518#endif
11519 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011520#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011521
11522 return result;
11523
11524error:
11525 Py_XDECREF(st_mode);
11526 Py_XDECREF(stat);
11527 return -1;
11528}
11529
11530static PyObject *
11531DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11532{
11533 int result;
11534
11535 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11536 if (result == -1)
11537 return NULL;
11538 return PyBool_FromLong(result);
11539}
11540
11541static PyObject *
11542DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11543{
11544 int follow_symlinks = 1;
11545
11546 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11547 follow_symlinks_keywords, &follow_symlinks))
11548 return NULL;
11549
11550 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11551}
11552
11553static PyObject *
11554DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11555{
11556 int follow_symlinks = 1;
11557
11558 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11559 follow_symlinks_keywords, &follow_symlinks))
11560 return NULL;
11561
11562 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11563}
11564
11565static PyObject *
11566DirEntry_inode(DirEntry *self)
11567{
11568#ifdef MS_WINDOWS
11569 if (!self->got_file_index) {
11570 wchar_t *path;
11571 struct _Py_stat_struct stat;
11572
11573 path = PyUnicode_AsUnicode(self->path);
11574 if (!path)
11575 return NULL;
11576
11577 if (win32_lstat_w(path, &stat) != 0) {
11578 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11579 0, self->path);
11580 }
11581
11582 self->win32_file_index = stat.st_ino;
11583 self->got_file_index = 1;
11584 }
11585 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11586#else /* POSIX */
11587#ifdef HAVE_LARGEFILE_SUPPORT
11588 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11589#else
11590 return PyLong_FromLong((long)self->d_ino);
11591#endif
11592#endif
11593}
11594
11595static PyObject *
11596DirEntry_repr(DirEntry *self)
11597{
11598 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11599}
11600
11601static PyMemberDef DirEntry_members[] = {
11602 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11603 "the entry's base filename, relative to scandir() \"path\" argument"},
11604 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11605 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11606 {NULL}
11607};
11608
11609static PyMethodDef DirEntry_methods[] = {
11610 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11611 "return True if the entry is a directory; cached per entry"
11612 },
11613 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11614 "return True if the entry is a file; cached per entry"
11615 },
11616 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11617 "return True if the entry is a symbolic link; cached per entry"
11618 },
11619 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11620 "return stat_result object for the entry; cached per entry"
11621 },
11622 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11623 "return inode of the entry; cached per entry",
11624 },
11625 {NULL}
11626};
11627
11628PyTypeObject DirEntryType = {
11629 PyVarObject_HEAD_INIT(NULL, 0)
11630 MODNAME ".DirEntry", /* tp_name */
11631 sizeof(DirEntry), /* tp_basicsize */
11632 0, /* tp_itemsize */
11633 /* methods */
11634 (destructor)DirEntry_dealloc, /* tp_dealloc */
11635 0, /* tp_print */
11636 0, /* tp_getattr */
11637 0, /* tp_setattr */
11638 0, /* tp_compare */
11639 (reprfunc)DirEntry_repr, /* tp_repr */
11640 0, /* tp_as_number */
11641 0, /* tp_as_sequence */
11642 0, /* tp_as_mapping */
11643 0, /* tp_hash */
11644 0, /* tp_call */
11645 0, /* tp_str */
11646 0, /* tp_getattro */
11647 0, /* tp_setattro */
11648 0, /* tp_as_buffer */
11649 Py_TPFLAGS_DEFAULT, /* tp_flags */
11650 0, /* tp_doc */
11651 0, /* tp_traverse */
11652 0, /* tp_clear */
11653 0, /* tp_richcompare */
11654 0, /* tp_weaklistoffset */
11655 0, /* tp_iter */
11656 0, /* tp_iternext */
11657 DirEntry_methods, /* tp_methods */
11658 DirEntry_members, /* tp_members */
11659};
11660
11661#ifdef MS_WINDOWS
11662
11663static wchar_t *
11664join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11665{
11666 Py_ssize_t path_len;
11667 Py_ssize_t size;
11668 wchar_t *result;
11669 wchar_t ch;
11670
11671 if (!path_wide) { /* Default arg: "." */
11672 path_wide = L".";
11673 path_len = 1;
11674 }
11675 else {
11676 path_len = wcslen(path_wide);
11677 }
11678
11679 /* The +1's are for the path separator and the NUL */
11680 size = path_len + 1 + wcslen(filename) + 1;
11681 result = PyMem_New(wchar_t, size);
11682 if (!result) {
11683 PyErr_NoMemory();
11684 return NULL;
11685 }
11686 wcscpy(result, path_wide);
11687 if (path_len > 0) {
11688 ch = result[path_len - 1];
11689 if (ch != SEP && ch != ALTSEP && ch != L':')
11690 result[path_len++] = SEP;
11691 wcscpy(result + path_len, filename);
11692 }
11693 return result;
11694}
11695
11696static PyObject *
11697DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11698{
11699 DirEntry *entry;
11700 BY_HANDLE_FILE_INFORMATION file_info;
11701 ULONG reparse_tag;
11702 wchar_t *joined_path;
11703
11704 entry = PyObject_New(DirEntry, &DirEntryType);
11705 if (!entry)
11706 return NULL;
11707 entry->name = NULL;
11708 entry->path = NULL;
11709 entry->stat = NULL;
11710 entry->lstat = NULL;
11711 entry->got_file_index = 0;
11712
11713 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11714 if (!entry->name)
11715 goto error;
11716
11717 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11718 if (!joined_path)
11719 goto error;
11720
11721 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11722 PyMem_Free(joined_path);
11723 if (!entry->path)
11724 goto error;
11725
11726 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11727 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11728
11729 return (PyObject *)entry;
11730
11731error:
11732 Py_DECREF(entry);
11733 return NULL;
11734}
11735
11736#else /* POSIX */
11737
11738static char *
11739join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11740{
11741 Py_ssize_t path_len;
11742 Py_ssize_t size;
11743 char *result;
11744
11745 if (!path_narrow) { /* Default arg: "." */
11746 path_narrow = ".";
11747 path_len = 1;
11748 }
11749 else {
11750 path_len = strlen(path_narrow);
11751 }
11752
11753 if (filename_len == -1)
11754 filename_len = strlen(filename);
11755
11756 /* The +1's are for the path separator and the NUL */
11757 size = path_len + 1 + filename_len + 1;
11758 result = PyMem_New(char, size);
11759 if (!result) {
11760 PyErr_NoMemory();
11761 return NULL;
11762 }
11763 strcpy(result, path_narrow);
11764 if (path_len > 0 && result[path_len - 1] != '/')
11765 result[path_len++] = '/';
11766 strcpy(result + path_len, filename);
11767 return result;
11768}
11769
11770static PyObject *
11771DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011772 ino_t d_ino
11773#ifdef HAVE_DIRENT_D_TYPE
11774 , unsigned char d_type
11775#endif
11776 )
Victor Stinner6036e442015-03-08 01:58:04 +010011777{
11778 DirEntry *entry;
11779 char *joined_path;
11780
11781 entry = PyObject_New(DirEntry, &DirEntryType);
11782 if (!entry)
11783 return NULL;
11784 entry->name = NULL;
11785 entry->path = NULL;
11786 entry->stat = NULL;
11787 entry->lstat = NULL;
11788
11789 joined_path = join_path_filename(path->narrow, name, name_len);
11790 if (!joined_path)
11791 goto error;
11792
11793 if (!path->narrow || !PyBytes_Check(path->object)) {
11794 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11795 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11796 }
11797 else {
11798 entry->name = PyBytes_FromStringAndSize(name, name_len);
11799 entry->path = PyBytes_FromString(joined_path);
11800 }
11801 PyMem_Free(joined_path);
11802 if (!entry->name || !entry->path)
11803 goto error;
11804
Victor Stinner35a97c02015-03-08 02:59:09 +010011805#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011806 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011807#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011808 entry->d_ino = d_ino;
11809
11810 return (PyObject *)entry;
11811
11812error:
11813 Py_XDECREF(entry);
11814 return NULL;
11815}
11816
11817#endif
11818
11819
11820typedef struct {
11821 PyObject_HEAD
11822 path_t path;
11823#ifdef MS_WINDOWS
11824 HANDLE handle;
11825 WIN32_FIND_DATAW file_data;
11826 int first_time;
11827#else /* POSIX */
11828 DIR *dirp;
11829#endif
11830} ScandirIterator;
11831
11832#ifdef MS_WINDOWS
11833
11834static void
11835ScandirIterator_close(ScandirIterator *iterator)
11836{
11837 if (iterator->handle == INVALID_HANDLE_VALUE)
11838 return;
11839
11840 Py_BEGIN_ALLOW_THREADS
11841 FindClose(iterator->handle);
11842 Py_END_ALLOW_THREADS
11843 iterator->handle = INVALID_HANDLE_VALUE;
11844}
11845
11846static PyObject *
11847ScandirIterator_iternext(ScandirIterator *iterator)
11848{
11849 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11850 BOOL success;
11851
11852 /* Happens if the iterator is iterated twice */
11853 if (iterator->handle == INVALID_HANDLE_VALUE) {
11854 PyErr_SetNone(PyExc_StopIteration);
11855 return NULL;
11856 }
11857
11858 while (1) {
11859 if (!iterator->first_time) {
11860 Py_BEGIN_ALLOW_THREADS
11861 success = FindNextFileW(iterator->handle, file_data);
11862 Py_END_ALLOW_THREADS
11863 if (!success) {
11864 if (GetLastError() != ERROR_NO_MORE_FILES)
11865 return path_error(&iterator->path);
11866 /* No more files found in directory, stop iterating */
11867 break;
11868 }
11869 }
11870 iterator->first_time = 0;
11871
11872 /* Skip over . and .. */
11873 if (wcscmp(file_data->cFileName, L".") != 0 &&
11874 wcscmp(file_data->cFileName, L"..") != 0)
11875 return DirEntry_from_find_data(&iterator->path, file_data);
11876
11877 /* Loop till we get a non-dot directory or finish iterating */
11878 }
11879
11880 ScandirIterator_close(iterator);
11881
11882 PyErr_SetNone(PyExc_StopIteration);
11883 return NULL;
11884}
11885
11886#else /* POSIX */
11887
11888static void
11889ScandirIterator_close(ScandirIterator *iterator)
11890{
11891 if (!iterator->dirp)
11892 return;
11893
11894 Py_BEGIN_ALLOW_THREADS
11895 closedir(iterator->dirp);
11896 Py_END_ALLOW_THREADS
11897 iterator->dirp = NULL;
11898 return;
11899}
11900
11901static PyObject *
11902ScandirIterator_iternext(ScandirIterator *iterator)
11903{
11904 struct dirent *direntp;
11905 Py_ssize_t name_len;
11906 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010011907
11908 /* Happens if the iterator is iterated twice */
11909 if (!iterator->dirp) {
11910 PyErr_SetNone(PyExc_StopIteration);
11911 return NULL;
11912 }
11913
11914 while (1) {
11915 errno = 0;
11916 Py_BEGIN_ALLOW_THREADS
11917 direntp = readdir(iterator->dirp);
11918 Py_END_ALLOW_THREADS
11919
11920 if (!direntp) {
11921 if (errno != 0)
11922 return path_error(&iterator->path);
11923 /* No more files found in directory, stop iterating */
11924 break;
11925 }
11926
11927 /* Skip over . and .. */
11928 name_len = NAMLEN(direntp);
11929 is_dot = direntp->d_name[0] == '.' &&
11930 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11931 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010011932 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011933 name_len, direntp->d_ino
11934#ifdef HAVE_DIRENT_D_TYPE
11935 , direntp->d_type
11936#endif
11937 );
Victor Stinner6036e442015-03-08 01:58:04 +010011938 }
11939
11940 /* Loop till we get a non-dot directory or finish iterating */
11941 }
11942
11943 ScandirIterator_close(iterator);
11944
11945 PyErr_SetNone(PyExc_StopIteration);
11946 return NULL;
11947}
11948
11949#endif
11950
11951static void
11952ScandirIterator_dealloc(ScandirIterator *iterator)
11953{
11954 ScandirIterator_close(iterator);
11955 Py_XDECREF(iterator->path.object);
11956 path_cleanup(&iterator->path);
11957 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11958}
11959
11960PyTypeObject ScandirIteratorType = {
11961 PyVarObject_HEAD_INIT(NULL, 0)
11962 MODNAME ".ScandirIterator", /* tp_name */
11963 sizeof(ScandirIterator), /* tp_basicsize */
11964 0, /* tp_itemsize */
11965 /* methods */
11966 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11967 0, /* tp_print */
11968 0, /* tp_getattr */
11969 0, /* tp_setattr */
11970 0, /* tp_compare */
11971 0, /* tp_repr */
11972 0, /* tp_as_number */
11973 0, /* tp_as_sequence */
11974 0, /* tp_as_mapping */
11975 0, /* tp_hash */
11976 0, /* tp_call */
11977 0, /* tp_str */
11978 0, /* tp_getattro */
11979 0, /* tp_setattro */
11980 0, /* tp_as_buffer */
11981 Py_TPFLAGS_DEFAULT, /* tp_flags */
11982 0, /* tp_doc */
11983 0, /* tp_traverse */
11984 0, /* tp_clear */
11985 0, /* tp_richcompare */
11986 0, /* tp_weaklistoffset */
11987 PyObject_SelfIter, /* tp_iter */
11988 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
11989};
11990
11991static PyObject *
11992posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11993{
11994 ScandirIterator *iterator;
11995 static char *keywords[] = {"path", NULL};
11996#ifdef MS_WINDOWS
11997 wchar_t *path_strW;
11998#else
11999 char *path;
12000#endif
12001
12002 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12003 if (!iterator)
12004 return NULL;
12005 memset(&iterator->path, 0, sizeof(path_t));
12006 iterator->path.function_name = "scandir";
12007 iterator->path.nullable = 1;
12008
12009#ifdef MS_WINDOWS
12010 iterator->handle = INVALID_HANDLE_VALUE;
12011#else
12012 iterator->dirp = NULL;
12013#endif
12014
12015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12016 path_converter, &iterator->path))
12017 goto error;
12018
12019 /* path_converter doesn't keep path.object around, so do it
12020 manually for the lifetime of the iterator here (the refcount
12021 is decremented in ScandirIterator_dealloc)
12022 */
12023 Py_XINCREF(iterator->path.object);
12024
12025#ifdef MS_WINDOWS
12026 if (iterator->path.narrow) {
12027 PyErr_SetString(PyExc_TypeError,
12028 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12029 goto error;
12030 }
12031 iterator->first_time = 1;
12032
12033 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12034 if (!path_strW)
12035 goto error;
12036
12037 Py_BEGIN_ALLOW_THREADS
12038 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12039 Py_END_ALLOW_THREADS
12040
12041 PyMem_Free(path_strW);
12042
12043 if (iterator->handle == INVALID_HANDLE_VALUE) {
12044 path_error(&iterator->path);
12045 goto error;
12046 }
12047#else /* POSIX */
12048 if (iterator->path.narrow)
12049 path = iterator->path.narrow;
12050 else
12051 path = ".";
12052
12053 errno = 0;
12054 Py_BEGIN_ALLOW_THREADS
12055 iterator->dirp = opendir(path);
12056 Py_END_ALLOW_THREADS
12057
12058 if (!iterator->dirp) {
12059 path_error(&iterator->path);
12060 goto error;
12061 }
12062#endif
12063
12064 return (PyObject *)iterator;
12065
12066error:
12067 Py_DECREF(iterator);
12068 return NULL;
12069}
12070
12071
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012072#include "clinic/posixmodule.c.h"
12073
Larry Hastings7726ac92014-01-31 22:03:12 -080012074/*[clinic input]
12075dump buffer
12076[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012077/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012078
Larry Hastings31826802013-10-19 00:09:25 -070012079
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012080static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012081
12082 OS_STAT_METHODDEF
12083 OS_ACCESS_METHODDEF
12084 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012085 OS_CHDIR_METHODDEF
12086 OS_CHFLAGS_METHODDEF
12087 OS_CHMOD_METHODDEF
12088 OS_FCHMOD_METHODDEF
12089 OS_LCHMOD_METHODDEF
12090 OS_CHOWN_METHODDEF
12091 OS_FCHOWN_METHODDEF
12092 OS_LCHOWN_METHODDEF
12093 OS_LCHFLAGS_METHODDEF
12094 OS_CHROOT_METHODDEF
12095 OS_CTERMID_METHODDEF
12096 OS_GETCWD_METHODDEF
12097 OS_GETCWDB_METHODDEF
12098 OS_LINK_METHODDEF
12099 OS_LISTDIR_METHODDEF
12100 OS_LSTAT_METHODDEF
12101 OS_MKDIR_METHODDEF
12102 OS_NICE_METHODDEF
12103 OS_GETPRIORITY_METHODDEF
12104 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012105#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012106 {"readlink", (PyCFunction)posix_readlink,
12107 METH_VARARGS | METH_KEYWORDS,
12108 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012109#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012110#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012111 {"readlink", (PyCFunction)win_readlink,
12112 METH_VARARGS | METH_KEYWORDS,
12113 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012114#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012115 OS_RENAME_METHODDEF
12116 OS_REPLACE_METHODDEF
12117 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012119 OS_SYMLINK_METHODDEF
12120 OS_SYSTEM_METHODDEF
12121 OS_UMASK_METHODDEF
12122 OS_UNAME_METHODDEF
12123 OS_UNLINK_METHODDEF
12124 OS_REMOVE_METHODDEF
12125 OS_UTIME_METHODDEF
12126 OS_TIMES_METHODDEF
12127 OS__EXIT_METHODDEF
12128 OS_EXECV_METHODDEF
12129 OS_EXECVE_METHODDEF
12130 OS_SPAWNV_METHODDEF
12131 OS_SPAWNVE_METHODDEF
12132 OS_FORK1_METHODDEF
12133 OS_FORK_METHODDEF
12134 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12135 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12136 OS_SCHED_GETPARAM_METHODDEF
12137 OS_SCHED_GETSCHEDULER_METHODDEF
12138 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12139 OS_SCHED_SETPARAM_METHODDEF
12140 OS_SCHED_SETSCHEDULER_METHODDEF
12141 OS_SCHED_YIELD_METHODDEF
12142 OS_SCHED_SETAFFINITY_METHODDEF
12143 OS_SCHED_GETAFFINITY_METHODDEF
12144 OS_OPENPTY_METHODDEF
12145 OS_FORKPTY_METHODDEF
12146 OS_GETEGID_METHODDEF
12147 OS_GETEUID_METHODDEF
12148 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012149#ifdef HAVE_GETGROUPLIST
12150 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12151#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012152 OS_GETGROUPS_METHODDEF
12153 OS_GETPID_METHODDEF
12154 OS_GETPGRP_METHODDEF
12155 OS_GETPPID_METHODDEF
12156 OS_GETUID_METHODDEF
12157 OS_GETLOGIN_METHODDEF
12158 OS_KILL_METHODDEF
12159 OS_KILLPG_METHODDEF
12160 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012161#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012162 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012163#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012164 OS_SETUID_METHODDEF
12165 OS_SETEUID_METHODDEF
12166 OS_SETREUID_METHODDEF
12167 OS_SETGID_METHODDEF
12168 OS_SETEGID_METHODDEF
12169 OS_SETREGID_METHODDEF
12170 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012171#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012172 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012173#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012174 OS_GETPGID_METHODDEF
12175 OS_SETPGRP_METHODDEF
12176 OS_WAIT_METHODDEF
12177 OS_WAIT3_METHODDEF
12178 OS_WAIT4_METHODDEF
12179 OS_WAITID_METHODDEF
12180 OS_WAITPID_METHODDEF
12181 OS_GETSID_METHODDEF
12182 OS_SETSID_METHODDEF
12183 OS_SETPGID_METHODDEF
12184 OS_TCGETPGRP_METHODDEF
12185 OS_TCSETPGRP_METHODDEF
12186 OS_OPEN_METHODDEF
12187 OS_CLOSE_METHODDEF
12188 OS_CLOSERANGE_METHODDEF
12189 OS_DEVICE_ENCODING_METHODDEF
12190 OS_DUP_METHODDEF
12191 OS_DUP2_METHODDEF
12192 OS_LOCKF_METHODDEF
12193 OS_LSEEK_METHODDEF
12194 OS_READ_METHODDEF
12195 OS_READV_METHODDEF
12196 OS_PREAD_METHODDEF
12197 OS_WRITE_METHODDEF
12198 OS_WRITEV_METHODDEF
12199 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012200#ifdef HAVE_SENDFILE
12201 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12202 posix_sendfile__doc__},
12203#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012204 OS_FSTAT_METHODDEF
12205 OS_ISATTY_METHODDEF
12206 OS_PIPE_METHODDEF
12207 OS_PIPE2_METHODDEF
12208 OS_MKFIFO_METHODDEF
12209 OS_MKNOD_METHODDEF
12210 OS_MAJOR_METHODDEF
12211 OS_MINOR_METHODDEF
12212 OS_MAKEDEV_METHODDEF
12213 OS_FTRUNCATE_METHODDEF
12214 OS_TRUNCATE_METHODDEF
12215 OS_POSIX_FALLOCATE_METHODDEF
12216 OS_POSIX_FADVISE_METHODDEF
12217 OS_PUTENV_METHODDEF
12218 OS_UNSETENV_METHODDEF
12219 OS_STRERROR_METHODDEF
12220 OS_FCHDIR_METHODDEF
12221 OS_FSYNC_METHODDEF
12222 OS_SYNC_METHODDEF
12223 OS_FDATASYNC_METHODDEF
12224 OS_WCOREDUMP_METHODDEF
12225 OS_WIFCONTINUED_METHODDEF
12226 OS_WIFSTOPPED_METHODDEF
12227 OS_WIFSIGNALED_METHODDEF
12228 OS_WIFEXITED_METHODDEF
12229 OS_WEXITSTATUS_METHODDEF
12230 OS_WTERMSIG_METHODDEF
12231 OS_WSTOPSIG_METHODDEF
12232 OS_FSTATVFS_METHODDEF
12233 OS_STATVFS_METHODDEF
12234 OS_CONFSTR_METHODDEF
12235 OS_SYSCONF_METHODDEF
12236 OS_FPATHCONF_METHODDEF
12237 OS_PATHCONF_METHODDEF
12238 OS_ABORT_METHODDEF
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012239#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012240 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050012241 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000012242#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012243 OS__GETDISKUSAGE_METHODDEF
12244 OS__GETFINALPATHNAME_METHODDEF
12245 OS__GETVOLUMEPATHNAME_METHODDEF
12246 OS_GETLOADAVG_METHODDEF
12247 OS_URANDOM_METHODDEF
12248 OS_SETRESUID_METHODDEF
12249 OS_SETRESGID_METHODDEF
12250 OS_GETRESUID_METHODDEF
12251 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012252
Larry Hastings2f936352014-08-05 14:04:04 +100012253 OS_GETXATTR_METHODDEF
12254 OS_SETXATTR_METHODDEF
12255 OS_REMOVEXATTR_METHODDEF
12256 OS_LISTXATTR_METHODDEF
12257
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012258#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12259 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12260#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012261 OS_CPU_COUNT_METHODDEF
12262 OS_GET_INHERITABLE_METHODDEF
12263 OS_SET_INHERITABLE_METHODDEF
12264 OS_GET_HANDLE_INHERITABLE_METHODDEF
12265 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012266#ifndef MS_WINDOWS
12267 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12268 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12269#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012270 {"scandir", (PyCFunction)posix_scandir,
12271 METH_VARARGS | METH_KEYWORDS,
12272 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012273 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012274};
12275
12276
Brian Curtin52173d42010-12-02 18:29:18 +000012277#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012278static int
Brian Curtin52173d42010-12-02 18:29:18 +000012279enable_symlink()
12280{
12281 HANDLE tok;
12282 TOKEN_PRIVILEGES tok_priv;
12283 LUID luid;
12284 int meth_idx = 0;
12285
12286 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012287 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012288
12289 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012290 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012291
12292 tok_priv.PrivilegeCount = 1;
12293 tok_priv.Privileges[0].Luid = luid;
12294 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12295
12296 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12297 sizeof(TOKEN_PRIVILEGES),
12298 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012299 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012300
Brian Curtin3b4499c2010-12-28 14:31:47 +000012301 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12302 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012303}
12304#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12305
Barry Warsaw4a342091996-12-19 23:50:02 +000012306static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012307all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012308{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012309#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012310 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012311#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012312#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012313 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012314#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012315#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012316 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012317#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012318#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012319 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012320#endif
Fred Drakec9680921999-12-13 16:37:25 +000012321#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012322 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012323#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012324#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012325 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012326#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012327#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012328 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012329#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012330#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012331 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012332#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012333#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012334 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012335#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012336#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012337 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012338#endif
12339#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012340 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012341#endif
12342#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012343 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012344#endif
12345#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012346 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012347#endif
12348#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012349 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012350#endif
12351#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012352 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012353#endif
12354#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012355 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012356#endif
12357#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012358 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012359#endif
12360#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012361 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012362#endif
12363#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012364 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012365#endif
12366#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012367 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012368#endif
12369#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012370 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012371#endif
12372#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012373 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012374#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012375#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012377#endif
12378#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012380#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012381#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012383#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012384#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012386#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012387#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012389#endif
12390#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012392#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012393#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012395#endif
12396#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012398#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012399#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012401#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012402#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012404#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012405#ifdef O_TMPFILE
12406 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12407#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012408#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012410#endif
12411#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012413#endif
12414#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012416#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012417#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012419#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012420#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012422#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012423
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012424
Jesus Cea94363612012-06-22 18:32:07 +020012425#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012427#endif
12428#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012430#endif
12431
Tim Peters5aa91602002-01-30 05:46:57 +000012432/* MS Windows */
12433#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012434 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012436#endif
12437#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012438 /* Optimize for short life (keep in memory). */
12439 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012441#endif
12442#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012443 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012445#endif
12446#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012447 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012449#endif
12450#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012451 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012453#endif
12454
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012455/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012456#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012457 /* Send a SIGIO signal whenever input or output
12458 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012460#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012461#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012462 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012464#endif
12465#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012466 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012468#endif
12469#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012470 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012472#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012473#ifdef O_NOLINKS
12474 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012476#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012477#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012478 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012480#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012481
Victor Stinner8c62be82010-05-06 00:08:46 +000012482 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012483#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012484 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012485#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012486#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012488#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012489#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012490 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012491#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012492#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012494#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012495#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012497#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012498#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012499 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012500#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012501#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012503#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012504#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012506#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012507#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012509#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012510#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012512#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012513#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012515#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012516#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012517 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012518#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012519#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012521#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012522#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012523 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012524#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012525#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012526 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012527#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012528#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012530#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012531#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012533#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012534
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012535 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012536#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012537 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012538#endif /* ST_RDONLY */
12539#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012540 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012541#endif /* ST_NOSUID */
12542
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012543 /* GNU extensions */
12544#ifdef ST_NODEV
12545 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12546#endif /* ST_NODEV */
12547#ifdef ST_NOEXEC
12548 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12549#endif /* ST_NOEXEC */
12550#ifdef ST_SYNCHRONOUS
12551 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12552#endif /* ST_SYNCHRONOUS */
12553#ifdef ST_MANDLOCK
12554 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12555#endif /* ST_MANDLOCK */
12556#ifdef ST_WRITE
12557 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12558#endif /* ST_WRITE */
12559#ifdef ST_APPEND
12560 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12561#endif /* ST_APPEND */
12562#ifdef ST_NOATIME
12563 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12564#endif /* ST_NOATIME */
12565#ifdef ST_NODIRATIME
12566 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12567#endif /* ST_NODIRATIME */
12568#ifdef ST_RELATIME
12569 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12570#endif /* ST_RELATIME */
12571
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012572 /* FreeBSD sendfile() constants */
12573#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012575#endif
12576#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012577 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012578#endif
12579#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012581#endif
12582
Ross Lagerwall7807c352011-03-17 20:20:30 +020012583 /* constants for posix_fadvise */
12584#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012586#endif
12587#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012589#endif
12590#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012592#endif
12593#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012595#endif
12596#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012598#endif
12599#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012601#endif
12602
12603 /* constants for waitid */
12604#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12606 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12607 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012608#endif
12609#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012611#endif
12612#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012614#endif
12615#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012617#endif
12618#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012620#endif
12621#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012623#endif
12624#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012626#endif
12627#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012629#endif
12630
12631 /* constants for lockf */
12632#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012634#endif
12635#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012637#endif
12638#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012639 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012640#endif
12641#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012643#endif
12644
Guido van Rossum246bc171999-02-01 23:54:31 +000012645#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12647 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12648 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12649 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12650 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012651#endif
12652
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012653#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12655 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12656 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012657#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012659#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012660#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012662#endif
12663#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012665#endif
12666#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012668#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012669#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012671#endif
12672#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012674#endif
12675#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012677#endif
12678#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012680#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012681#endif
12682
Benjamin Peterson9428d532011-09-14 11:45:52 -040012683#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12685 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12686 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012687#endif
12688
Victor Stinner8b905bd2011-10-25 13:34:04 +020012689#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012691#endif
12692#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012694#endif
12695#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012697#endif
12698#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012700#endif
12701#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012703#endif
12704#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012706#endif
12707#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012709#endif
12710
Victor Stinner8c62be82010-05-06 00:08:46 +000012711 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012712}
12713
12714
Martin v. Löwis1a214512008-06-11 05:26:20 +000012715static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012716 PyModuleDef_HEAD_INIT,
12717 MODNAME,
12718 posix__doc__,
12719 -1,
12720 posix_methods,
12721 NULL,
12722 NULL,
12723 NULL,
12724 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012725};
12726
12727
Larry Hastings9cf065c2012-06-22 16:30:09 -070012728static char *have_functions[] = {
12729
12730#ifdef HAVE_FACCESSAT
12731 "HAVE_FACCESSAT",
12732#endif
12733
12734#ifdef HAVE_FCHDIR
12735 "HAVE_FCHDIR",
12736#endif
12737
12738#ifdef HAVE_FCHMOD
12739 "HAVE_FCHMOD",
12740#endif
12741
12742#ifdef HAVE_FCHMODAT
12743 "HAVE_FCHMODAT",
12744#endif
12745
12746#ifdef HAVE_FCHOWN
12747 "HAVE_FCHOWN",
12748#endif
12749
Larry Hastings00964ed2013-08-12 13:49:30 -040012750#ifdef HAVE_FCHOWNAT
12751 "HAVE_FCHOWNAT",
12752#endif
12753
Larry Hastings9cf065c2012-06-22 16:30:09 -070012754#ifdef HAVE_FEXECVE
12755 "HAVE_FEXECVE",
12756#endif
12757
12758#ifdef HAVE_FDOPENDIR
12759 "HAVE_FDOPENDIR",
12760#endif
12761
Georg Brandl306336b2012-06-24 12:55:33 +020012762#ifdef HAVE_FPATHCONF
12763 "HAVE_FPATHCONF",
12764#endif
12765
Larry Hastings9cf065c2012-06-22 16:30:09 -070012766#ifdef HAVE_FSTATAT
12767 "HAVE_FSTATAT",
12768#endif
12769
12770#ifdef HAVE_FSTATVFS
12771 "HAVE_FSTATVFS",
12772#endif
12773
Georg Brandl306336b2012-06-24 12:55:33 +020012774#ifdef HAVE_FTRUNCATE
12775 "HAVE_FTRUNCATE",
12776#endif
12777
Larry Hastings9cf065c2012-06-22 16:30:09 -070012778#ifdef HAVE_FUTIMENS
12779 "HAVE_FUTIMENS",
12780#endif
12781
12782#ifdef HAVE_FUTIMES
12783 "HAVE_FUTIMES",
12784#endif
12785
12786#ifdef HAVE_FUTIMESAT
12787 "HAVE_FUTIMESAT",
12788#endif
12789
12790#ifdef HAVE_LINKAT
12791 "HAVE_LINKAT",
12792#endif
12793
12794#ifdef HAVE_LCHFLAGS
12795 "HAVE_LCHFLAGS",
12796#endif
12797
12798#ifdef HAVE_LCHMOD
12799 "HAVE_LCHMOD",
12800#endif
12801
12802#ifdef HAVE_LCHOWN
12803 "HAVE_LCHOWN",
12804#endif
12805
12806#ifdef HAVE_LSTAT
12807 "HAVE_LSTAT",
12808#endif
12809
12810#ifdef HAVE_LUTIMES
12811 "HAVE_LUTIMES",
12812#endif
12813
12814#ifdef HAVE_MKDIRAT
12815 "HAVE_MKDIRAT",
12816#endif
12817
12818#ifdef HAVE_MKFIFOAT
12819 "HAVE_MKFIFOAT",
12820#endif
12821
12822#ifdef HAVE_MKNODAT
12823 "HAVE_MKNODAT",
12824#endif
12825
12826#ifdef HAVE_OPENAT
12827 "HAVE_OPENAT",
12828#endif
12829
12830#ifdef HAVE_READLINKAT
12831 "HAVE_READLINKAT",
12832#endif
12833
12834#ifdef HAVE_RENAMEAT
12835 "HAVE_RENAMEAT",
12836#endif
12837
12838#ifdef HAVE_SYMLINKAT
12839 "HAVE_SYMLINKAT",
12840#endif
12841
12842#ifdef HAVE_UNLINKAT
12843 "HAVE_UNLINKAT",
12844#endif
12845
12846#ifdef HAVE_UTIMENSAT
12847 "HAVE_UTIMENSAT",
12848#endif
12849
12850#ifdef MS_WINDOWS
12851 "MS_WINDOWS",
12852#endif
12853
12854 NULL
12855};
12856
12857
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012858PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012859INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012860{
Victor Stinner8c62be82010-05-06 00:08:46 +000012861 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012862 PyObject *list;
12863 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012864
Brian Curtin52173d42010-12-02 18:29:18 +000012865#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012866 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012867#endif
12868
Victor Stinner8c62be82010-05-06 00:08:46 +000012869 m = PyModule_Create(&posixmodule);
12870 if (m == NULL)
12871 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012872
Victor Stinner8c62be82010-05-06 00:08:46 +000012873 /* Initialize environ dictionary */
12874 v = convertenviron();
12875 Py_XINCREF(v);
12876 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12877 return NULL;
12878 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012879
Victor Stinner8c62be82010-05-06 00:08:46 +000012880 if (all_ins(m))
12881 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882
Victor Stinner8c62be82010-05-06 00:08:46 +000012883 if (setup_confname_tables(m))
12884 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012885
Victor Stinner8c62be82010-05-06 00:08:46 +000012886 Py_INCREF(PyExc_OSError);
12887 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012888
Guido van Rossumb3d39562000-01-31 18:41:26 +000012889#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012890 if (posix_putenv_garbage == NULL)
12891 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012892#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012893
Victor Stinner8c62be82010-05-06 00:08:46 +000012894 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012895#if defined(HAVE_WAITID) && !defined(__APPLE__)
12896 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012897 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12898 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012899#endif
12900
Christian Heimes25827622013-10-12 01:27:08 +020012901 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012902 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12903 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12904 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012905 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12906 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012907 structseq_new = StatResultType.tp_new;
12908 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012909
Christian Heimes25827622013-10-12 01:27:08 +020012910 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012911 if (PyStructSequence_InitType2(&StatVFSResultType,
12912 &statvfs_result_desc) < 0)
12913 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012914#ifdef NEED_TICKS_PER_SECOND
12915# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012916 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012917# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012918 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012919# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012920 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012921# endif
12922#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012923
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012924#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012925 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012926 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12927 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012928 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012929#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012930
12931 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012932 if (PyStructSequence_InitType2(&TerminalSizeType,
12933 &TerminalSize_desc) < 0)
12934 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012935
12936 /* initialize scandir types */
12937 if (PyType_Ready(&ScandirIteratorType) < 0)
12938 return NULL;
12939 if (PyType_Ready(&DirEntryType) < 0)
12940 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012941 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012942#if defined(HAVE_WAITID) && !defined(__APPLE__)
12943 Py_INCREF((PyObject*) &WaitidResultType);
12944 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012946 Py_INCREF((PyObject*) &StatResultType);
12947 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12948 Py_INCREF((PyObject*) &StatVFSResultType);
12949 PyModule_AddObject(m, "statvfs_result",
12950 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012951
12952#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012953 Py_INCREF(&SchedParamType);
12954 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012955#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012956
Larry Hastings605a62d2012-06-24 04:33:36 -070012957 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012958 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12959 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012960 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12961
12962 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012963 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12964 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012965 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12966
Thomas Wouters477c8d52006-05-27 19:21:47 +000012967#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 /*
12969 * Step 2 of weak-linking support on Mac OS X.
12970 *
12971 * The code below removes functions that are not available on the
12972 * currently active platform.
12973 *
12974 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012975 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 * OSX 10.4.
12977 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012978#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 if (fstatvfs == NULL) {
12980 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12981 return NULL;
12982 }
12983 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012984#endif /* HAVE_FSTATVFS */
12985
12986#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 if (statvfs == NULL) {
12988 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12989 return NULL;
12990 }
12991 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012992#endif /* HAVE_STATVFS */
12993
12994# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012995 if (lchown == NULL) {
12996 if (PyObject_DelAttrString(m, "lchown") == -1) {
12997 return NULL;
12998 }
12999 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013000#endif /* HAVE_LCHOWN */
13001
13002
13003#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013004
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013005 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013006 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13007
Larry Hastings6fe20b32012-04-19 15:07:49 -070013008 billion = PyLong_FromLong(1000000000);
13009 if (!billion)
13010 return NULL;
13011
Larry Hastings9cf065c2012-06-22 16:30:09 -070013012 /* suppress "function not used" warnings */
13013 {
13014 int ignored;
13015 fd_specified("", -1);
13016 follow_symlinks_specified("", 1);
13017 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13018 dir_fd_converter(Py_None, &ignored);
13019 dir_fd_unavailable(Py_None, &ignored);
13020 }
13021
13022 /*
13023 * provide list of locally available functions
13024 * so os.py can populate support_* lists
13025 */
13026 list = PyList_New(0);
13027 if (!list)
13028 return NULL;
13029 for (trace = have_functions; *trace; trace++) {
13030 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13031 if (!unicode)
13032 return NULL;
13033 if (PyList_Append(list, unicode))
13034 return NULL;
13035 Py_DECREF(unicode);
13036 }
13037 PyModule_AddObject(m, "_have_functions", list);
13038
13039 initialized = 1;
13040
Victor Stinner8c62be82010-05-06 00:08:46 +000013041 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013042}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013043
13044#ifdef __cplusplus
13045}
13046#endif