blob: 9a44d4697566b72441652f00453a823135f6da67 [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
Steve Dowerf2f373f2015-02-21 08:44:05 -0800354# define FSTAT _Py_fstat
355# 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
2473PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002474"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2475"--\n"
2476"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002477"Perform a stat system call on the given path.\n"
2478"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002479" path\n"
2480" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2481" dir_fd\n"
2482" If not None, it should be a file descriptor open to a directory,\n"
2483" and path should be a relative string; path will then be relative to\n"
2484" that directory.\n"
2485" follow_symlinks\n"
2486" If False, and the last element of the path is a symbolic link,\n"
2487" stat will examine the symbolic link itself instead of the file\n"
2488" the link points to.\n"
2489"\n"
2490"dir_fd and follow_symlinks may not be implemented\n"
2491" on your platform. If they are unavailable, using them will raise a\n"
2492" NotImplementedError.\n"
2493"\n"
2494"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2495" an open file descriptor.");
2496
2497#define OS_STAT_METHODDEF \
2498 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002499
2500static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002501os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002502
2503static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002504os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002505{
Larry Hastings31826802013-10-19 00:09:25 -07002506 PyObject *return_value = NULL;
2507 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
Larry Hastings2f936352014-08-05 14:04:04 +10002508 path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002509 int dir_fd = DEFAULT_DIR_FD;
2510 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511
Larry Hastings31826802013-10-19 00:09:25 -07002512 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2513 "O&|$O&p:stat", _keywords,
Larry Hastings2f936352014-08-05 14:04:04 +10002514 path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
Larry Hastings31826802013-10-19 00:09:25 -07002515 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002516 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002517
2518exit:
2519 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002520 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002521
Larry Hastings9cf065c2012-06-22 16:30:09 -07002522 return return_value;
2523}
2524
Larry Hastings31826802013-10-19 00:09:25 -07002525static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002526os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002527/*[clinic end generated code: output=0e9f9508fa0c0607 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002528{
2529 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2530}
2531
Larry Hastings2f936352014-08-05 14:04:04 +10002532
2533/*[clinic input]
2534os.lstat
2535
2536 path : path_t
2537
2538 *
2539
2540 dir_fd : dir_fd(requires='fstatat') = None
2541
2542Perform a stat system call on the given path, without following symbolic links.
2543
2544Like stat(), but do not follow symbolic links.
2545Equivalent to stat(path, follow_symlinks=False).
2546[clinic start generated code]*/
2547
2548PyDoc_STRVAR(os_lstat__doc__,
2549"lstat($module, /, path, *, dir_fd=None)\n"
2550"--\n"
2551"\n"
2552"Perform a stat system call on the given path, without following symbolic links.\n"
2553"\n"
2554"Like stat(), but do not follow symbolic links.\n"
2555"Equivalent to stat(path, follow_symlinks=False).");
2556
2557#define OS_LSTAT_METHODDEF \
2558 {"lstat", (PyCFunction)os_lstat, METH_VARARGS|METH_KEYWORDS, os_lstat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559
2560static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002561os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
Larry Hastings2f936352014-08-05 14:04:04 +10002563static PyObject *
2564os_lstat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
2565{
2566 PyObject *return_value = NULL;
2567 static char *_keywords[] = {"path", "dir_fd", NULL};
2568 path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0);
2569 int dir_fd = DEFAULT_DIR_FD;
2570
2571 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2572 "O&|$O&:lstat", _keywords,
2573 path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd))
2574 goto exit;
2575 return_value = os_lstat_impl(module, &path, dir_fd);
2576
2577exit:
2578 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +10002580
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581 return return_value;
2582}
2583
Larry Hastings2f936352014-08-05 14:04:04 +10002584static PyObject *
2585os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
2586/*[clinic end generated code: output=85702247224a2b1c input=0b7474765927b925]*/
2587{
2588 int follow_symlinks = 0;
2589 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2590}
Larry Hastings31826802013-10-19 00:09:25 -07002591
Larry Hastings2f936352014-08-05 14:04:04 +10002592
Larry Hastings61272b72014-01-07 12:41:53 -08002593/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002594os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002595
2596 path: path_t(allow_fd=True)
2597 Path to be tested; can be string, bytes, or open-file-descriptor int.
2598
2599 mode: int
2600 Operating-system mode bitfield. Can be F_OK to test existence,
2601 or the inclusive-OR of R_OK, W_OK, and X_OK.
2602
2603 *
2604
Larry Hastings2f936352014-08-05 14:04:04 +10002605 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002606 If not None, it should be a file descriptor open to a directory,
2607 and path should be relative; path will then be relative to that
2608 directory.
2609
2610 effective_ids: bool = False
2611 If True, access will use the effective uid/gid instead of
2612 the real uid/gid.
2613
2614 follow_symlinks: bool = True
2615 If False, and the last element of the path is a symbolic link,
2616 access will examine the symbolic link itself instead of the file
2617 the link points to.
2618
2619Use the real uid/gid to test for access to a path.
2620
2621{parameters}
2622dir_fd, effective_ids, and follow_symlinks may not be implemented
2623 on your platform. If they are unavailable, using them will raise a
2624 NotImplementedError.
2625
2626Note that most operations will use the effective uid/gid, therefore this
2627 routine can be used in a suid/sgid environment to test if the invoking user
2628 has the specified access to the path.
2629
Larry Hastings61272b72014-01-07 12:41:53 -08002630[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002631
2632PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002633"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2634" follow_symlinks=True)\n"
2635"--\n"
2636"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002637"Use the real uid/gid to test for access to a path.\n"
2638"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002639" path\n"
2640" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2641" mode\n"
2642" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2643" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2644" dir_fd\n"
2645" If not None, it should be a file descriptor open to a directory,\n"
2646" and path should be relative; path will then be relative to that\n"
2647" directory.\n"
2648" effective_ids\n"
2649" If True, access will use the effective uid/gid instead of\n"
2650" the real uid/gid.\n"
2651" follow_symlinks\n"
2652" If False, and the last element of the path is a symbolic link,\n"
2653" access will examine the symbolic link itself instead of the file\n"
2654" the link points to.\n"
2655"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002656"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2657" on your platform. If they are unavailable, using them will raise a\n"
2658" NotImplementedError.\n"
2659"\n"
2660"Note that most operations will use the effective uid/gid, therefore this\n"
2661" routine can be used in a suid/sgid environment to test if the invoking user\n"
2662" has the specified access to the path.");
2663
2664#define OS_ACCESS_METHODDEF \
2665 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002666
Larry Hastings2f936352014-08-05 14:04:04 +10002667static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002668os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002669
2670static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002671os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002672{
Larry Hastings31826802013-10-19 00:09:25 -07002673 PyObject *return_value = NULL;
2674 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
Larry Hastings2f936352014-08-05 14:04:04 +10002675 path_t path = PATH_T_INITIALIZE("access", "path", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002676 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677 int dir_fd = DEFAULT_DIR_FD;
2678 int effective_ids = 0;
2679 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10002680 int _return_value;
Larry Hastings31826802013-10-19 00:09:25 -07002681
2682 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2683 "O&i|$O&pp:access", _keywords,
Larry Hastings2f936352014-08-05 14:04:04 +10002684 path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
Larry Hastings31826802013-10-19 00:09:25 -07002685 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +10002686 _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
2687 if ((_return_value == -1) && PyErr_Occurred())
2688 goto exit;
2689 return_value = PyBool_FromLong((long)_return_value);
Larry Hastings31826802013-10-19 00:09:25 -07002690
2691exit:
2692 /* Cleanup for path */
2693 path_cleanup(&path);
2694
2695 return return_value;
2696}
2697
Larry Hastings2f936352014-08-05 14:04:04 +10002698static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002699os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002700/*[clinic end generated code: output=dfd404666906f012 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002701{
Larry Hastings2f936352014-08-05 14:04:04 +10002702 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002703
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002704#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002705 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002706#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002707 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002708#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709
Larry Hastings9cf065c2012-06-22 16:30:09 -07002710#ifndef HAVE_FACCESSAT
2711 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002712 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002713
2714 if (effective_ids) {
2715 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002716 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717 }
2718#endif
2719
2720#ifdef MS_WINDOWS
2721 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002722 if (path->wide != NULL)
2723 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002725 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726 Py_END_ALLOW_THREADS
2727
2728 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002729 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730 * * we didn't get a -1, and
2731 * * write access wasn't requested,
2732 * * or the file isn't read-only,
2733 * * or it's a directory.
2734 * (Directories cannot be read-only on Windows.)
2735 */
Larry Hastings2f936352014-08-05 14:04:04 +10002736 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002737 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002738 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002739 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740#else
2741
2742 Py_BEGIN_ALLOW_THREADS
2743#ifdef HAVE_FACCESSAT
2744 if ((dir_fd != DEFAULT_DIR_FD) ||
2745 effective_ids ||
2746 !follow_symlinks) {
2747 int flags = 0;
2748 if (!follow_symlinks)
2749 flags |= AT_SYMLINK_NOFOLLOW;
2750 if (effective_ids)
2751 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002752 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753 }
2754 else
2755#endif
Larry Hastings31826802013-10-19 00:09:25 -07002756 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002757 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002758 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002759#endif
2760
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002762}
2763
Guido van Rossumd371ff11999-01-25 16:12:23 +00002764#ifndef F_OK
2765#define F_OK 0
2766#endif
2767#ifndef R_OK
2768#define R_OK 4
2769#endif
2770#ifndef W_OK
2771#define W_OK 2
2772#endif
2773#ifndef X_OK
2774#define X_OK 1
2775#endif
2776
Larry Hastings31826802013-10-19 00:09:25 -07002777
Guido van Rossumd371ff11999-01-25 16:12:23 +00002778#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002779/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002780os.ttyname -> DecodeFSDefault
2781
2782 fd: int
2783 Integer file descriptor handle.
2784
2785 /
2786
2787Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002788[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002789
2790PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002791"ttyname($module, fd, /)\n"
2792"--\n"
2793"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002794"Return the name of the terminal device connected to \'fd\'.\n"
2795"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002796" fd\n"
2797" Integer file descriptor handle.");
2798
2799#define OS_TTYNAME_METHODDEF \
2800 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2801
2802static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002803os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002804
2805static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002806os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002807{
Larry Hastings31826802013-10-19 00:09:25 -07002808 PyObject *return_value = NULL;
2809 int fd;
2810 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002811
Larry Hastings31826802013-10-19 00:09:25 -07002812 if (!PyArg_ParseTuple(args,
2813 "i:ttyname",
2814 &fd))
2815 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002816 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002817 if (_return_value == NULL)
2818 goto exit;
2819 return_value = PyUnicode_DecodeFSDefault(_return_value);
2820
2821exit:
2822 return return_value;
2823}
2824
2825static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002826os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002827/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002828{
2829 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002830
Larry Hastings31826802013-10-19 00:09:25 -07002831 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002832 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002833 posix_error();
2834 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002835}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002836#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002837
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002838#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002839/*[clinic input]
2840os.ctermid
2841
2842Return the name of the controlling terminal for this process.
2843[clinic start generated code]*/
2844
2845PyDoc_STRVAR(os_ctermid__doc__,
2846"ctermid($module, /)\n"
2847"--\n"
2848"\n"
2849"Return the name of the controlling terminal for this process.");
2850
2851#define OS_CTERMID_METHODDEF \
2852 {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002853
2854static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002855os_ctermid_impl(PyModuleDef *module);
2856
2857static PyObject *
2858os_ctermid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
2859{
2860 return os_ctermid_impl(module);
2861}
2862
2863static PyObject *
2864os_ctermid_impl(PyModuleDef *module)
2865/*[clinic end generated code: output=277bf7964ec2d782 input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002866{
Victor Stinner8c62be82010-05-06 00:08:46 +00002867 char *ret;
2868 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002869
Greg Wardb48bc172000-03-01 21:51:56 +00002870#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002872#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002873 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002874#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002875 if (ret == NULL)
2876 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002877 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002878}
Larry Hastings2f936352014-08-05 14:04:04 +10002879#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002880
Larry Hastings2f936352014-08-05 14:04:04 +10002881
2882/*[clinic input]
2883os.chdir
2884
2885 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2886
2887Change the current working directory to the specified path.
2888
2889path may always be specified as a string.
2890On some platforms, path may also be specified as an open file descriptor.
2891 If this functionality is unavailable, using it raises an exception.
2892[clinic start generated code]*/
2893
2894PyDoc_STRVAR(os_chdir__doc__,
2895"chdir($module, /, path)\n"
2896"--\n"
2897"\n"
2898"Change the current working directory to the specified path.\n"
2899"\n"
2900"path may always be specified as a string.\n"
2901"On some platforms, path may also be specified as an open file descriptor.\n"
2902" If this functionality is unavailable, using it raises an exception.");
2903
2904#define OS_CHDIR_METHODDEF \
2905 {"chdir", (PyCFunction)os_chdir, METH_VARARGS|METH_KEYWORDS, os_chdir__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002906
Barry Warsaw53699e91996-12-10 23:23:01 +00002907static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002908os_chdir_impl(PyModuleDef *module, path_t *path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909
Larry Hastings2f936352014-08-05 14:04:04 +10002910static PyObject *
2911os_chdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
2912{
2913 PyObject *return_value = NULL;
2914 static char *_keywords[] = {"path", NULL};
2915 path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR);
2916
2917 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2918 "O&:chdir", _keywords,
2919 path_converter, &path))
2920 goto exit;
2921 return_value = os_chdir_impl(module, &path);
2922
2923exit:
2924 /* Cleanup for path */
2925 path_cleanup(&path);
2926
2927 return return_value;
2928}
2929
2930static PyObject *
2931os_chdir_impl(PyModuleDef *module, path_t *path)
2932/*[clinic end generated code: output=cc07592dd23ca9e0 input=1a4a15b4d12cb15d]*/
2933{
2934 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002935
2936 Py_BEGIN_ALLOW_THREADS
2937#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002938 if (path->wide)
2939 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940 else
Larry Hastings2f936352014-08-05 14:04:04 +10002941 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002942 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943#else
2944#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002945 if (path->fd != -1)
2946 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002947 else
2948#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002949 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002950#endif
2951 Py_END_ALLOW_THREADS
2952
2953 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002954 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002955 }
2956
Larry Hastings2f936352014-08-05 14:04:04 +10002957 Py_RETURN_NONE;
2958}
2959
2960
2961#ifdef HAVE_FCHDIR
2962/*[clinic input]
2963os.fchdir
2964
2965 fd: fildes
2966
2967Change to the directory of the given file descriptor.
2968
2969fd must be opened on a directory, not a file.
2970Equivalent to os.chdir(fd).
2971
2972[clinic start generated code]*/
2973
2974PyDoc_STRVAR(os_fchdir__doc__,
2975"fchdir($module, /, fd)\n"
2976"--\n"
2977"\n"
2978"Change to the directory of the given file descriptor.\n"
2979"\n"
2980"fd must be opened on a directory, not a file.\n"
2981"Equivalent to os.chdir(fd).");
2982
2983#define OS_FCHDIR_METHODDEF \
2984 {"fchdir", (PyCFunction)os_fchdir, METH_VARARGS|METH_KEYWORDS, os_fchdir__doc__},
2985
2986static PyObject *
2987os_fchdir_impl(PyModuleDef *module, int fd);
2988
2989static PyObject *
2990os_fchdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
2991{
2992 PyObject *return_value = NULL;
2993 static char *_keywords[] = {"fd", NULL};
2994 int fd;
2995
2996 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2997 "O&:fchdir", _keywords,
2998 fildes_converter, &fd))
2999 goto exit;
3000 return_value = os_fchdir_impl(module, fd);
Georg Brandlf7875592012-06-24 13:58:31 +02003001
Larry Hastings9cf065c2012-06-22 16:30:09 -07003002exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003004}
3005
Fred Drake4d1e64b2002-04-15 19:40:07 +00003006static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003007os_fchdir_impl(PyModuleDef *module, int fd)
3008/*[clinic end generated code: output=9f6dbc89b2778834 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003009{
Larry Hastings2f936352014-08-05 14:04:04 +10003010 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003011}
3012#endif /* HAVE_FCHDIR */
3013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Larry Hastings2f936352014-08-05 14:04:04 +10003015/*[clinic input]
3016os.chmod
3017
3018 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
3019 Path to be modified. May always be specified as a str or bytes.
3020 On some platforms, path may also be specified as an open file descriptor.
3021 If this functionality is unavailable, using it raises an exception.
3022
3023 mode: int
3024 Operating-system mode bitfield.
3025
3026 *
3027
3028 dir_fd : dir_fd(requires='fchmodat') = None
3029 If not None, it should be a file descriptor open to a directory,
3030 and path should be relative; path will then be relative to that
3031 directory.
3032
3033 follow_symlinks: bool = True
3034 If False, and the last element of the path is a symbolic link,
3035 chmod will modify the symbolic link itself instead of the file
3036 the link points to.
3037
3038Change the access permissions of a file.
3039
3040It is an error to use dir_fd or follow_symlinks when specifying path as
3041 an open file descriptor.
3042dir_fd and follow_symlinks may not be implemented on your platform.
3043 If they are unavailable, using them will raise a NotImplementedError.
3044
3045[clinic start generated code]*/
3046
3047PyDoc_STRVAR(os_chmod__doc__,
3048"chmod($module, /, path, mode, *, dir_fd=None, follow_symlinks=True)\n"
3049"--\n"
3050"\n"
3051"Change the access permissions of a file.\n"
3052"\n"
3053" path\n"
3054" Path to be modified. May always be specified as a str or bytes.\n"
3055" On some platforms, path may also be specified as an open file descriptor.\n"
3056" If this functionality is unavailable, using it raises an exception.\n"
3057" mode\n"
3058" Operating-system mode bitfield.\n"
3059" dir_fd\n"
3060" If not None, it should be a file descriptor open to a directory,\n"
3061" and path should be relative; path will then be relative to that\n"
3062" directory.\n"
3063" follow_symlinks\n"
3064" If False, and the last element of the path is a symbolic link,\n"
3065" chmod will modify the symbolic link itself instead of the file\n"
3066" the link points to.\n"
3067"\n"
3068"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
3069" an open file descriptor.\n"
3070"dir_fd and follow_symlinks may not be implemented on your platform.\n"
3071" If they are unavailable, using them will raise a NotImplementedError.");
3072
3073#define OS_CHMOD_METHODDEF \
3074 {"chmod", (PyCFunction)os_chmod, METH_VARARGS|METH_KEYWORDS, os_chmod__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
Barry Warsaw53699e91996-12-10 23:23:01 +00003076static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003077os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks);
3078
3079static PyObject *
3080os_chmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003081{
Larry Hastings2f936352014-08-05 14:04:04 +10003082 PyObject *return_value = NULL;
3083 static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL};
3084 path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003085 int mode;
3086 int dir_fd = DEFAULT_DIR_FD;
3087 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10003088
3089 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3090 "O&i|$O&p:chmod", _keywords,
3091 path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
3092 goto exit;
3093 return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks);
3094
3095exit:
3096 /* Cleanup for path */
3097 path_cleanup(&path);
3098
3099 return return_value;
3100}
3101
3102static PyObject *
3103os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks)
3104/*[clinic end generated code: output=1e9db031aea46422 input=7f1618e5e15cc196]*/
3105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003106 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003108#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003111
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112#ifdef HAVE_FCHMODAT
3113 int fchmodat_nofollow_unsupported = 0;
3114#endif
3115
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3117 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003118 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119#endif
3120
3121#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003122 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003123 if (path->wide)
3124 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003125 else
Larry Hastings2f936352014-08-05 14:04:04 +10003126 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01003127 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003128 result = 0;
3129 else {
3130 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003131 attr &= ~FILE_ATTRIBUTE_READONLY;
3132 else
3133 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10003134 if (path->wide)
3135 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136 else
Larry Hastings2f936352014-08-05 14:04:04 +10003137 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138 }
3139 Py_END_ALLOW_THREADS
3140
3141 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003142 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003143 }
3144#else /* MS_WINDOWS */
3145 Py_BEGIN_ALLOW_THREADS
3146#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003147 if (path->fd != -1)
3148 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149 else
3150#endif
3151#ifdef HAVE_LCHMOD
3152 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003153 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003154 else
3155#endif
3156#ifdef HAVE_FCHMODAT
3157 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3158 /*
3159 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3160 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003161 * and then says it isn't implemented yet.
3162 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163 *
3164 * Once it is supported, os.chmod will automatically
3165 * support dir_fd and follow_symlinks=False. (Hopefully.)
3166 * Until then, we need to be careful what exception we raise.
3167 */
Larry Hastings2f936352014-08-05 14:04:04 +10003168 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3170 /*
3171 * But wait! We can't throw the exception without allowing threads,
3172 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3173 */
3174 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003175 result &&
3176 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3177 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 }
3179 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003180#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003181 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 Py_END_ALLOW_THREADS
3183
3184 if (result) {
3185#ifdef HAVE_FCHMODAT
3186 if (fchmodat_nofollow_unsupported) {
3187 if (dir_fd != DEFAULT_DIR_FD)
3188 dir_fd_and_follow_symlinks_invalid("chmod",
3189 dir_fd, follow_symlinks);
3190 else
3191 follow_symlinks_specified("chmod", follow_symlinks);
3192 }
3193 else
3194#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003195 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 }
3197#endif
3198
Larry Hastings2f936352014-08-05 14:04:04 +10003199 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003200}
3201
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
Christian Heimes4e30a842007-11-30 22:12:06 +00003203#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003204/*[clinic input]
3205os.fchmod
3206
3207 fd: int
3208 mode: int
3209
3210Change the access permissions of the file given by file descriptor fd.
3211
3212Equivalent to os.chmod(fd, mode).
3213[clinic start generated code]*/
3214
3215PyDoc_STRVAR(os_fchmod__doc__,
3216"fchmod($module, /, fd, mode)\n"
3217"--\n"
3218"\n"
3219"Change the access permissions of the file given by file descriptor fd.\n"
3220"\n"
3221"Equivalent to os.chmod(fd, mode).");
3222
3223#define OS_FCHMOD_METHODDEF \
3224 {"fchmod", (PyCFunction)os_fchmod, METH_VARARGS|METH_KEYWORDS, os_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00003225
3226static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003227os_fchmod_impl(PyModuleDef *module, int fd, int mode);
3228
3229static PyObject *
3230os_fchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00003231{
Larry Hastings2f936352014-08-05 14:04:04 +10003232 PyObject *return_value = NULL;
3233 static char *_keywords[] = {"fd", "mode", NULL};
3234 int fd;
3235 int mode;
3236
3237 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3238 "ii:fchmod", _keywords,
3239 &fd, &mode))
3240 goto exit;
3241 return_value = os_fchmod_impl(module, fd, mode);
3242
3243exit:
3244 return return_value;
3245}
3246
3247static PyObject *
3248os_fchmod_impl(PyModuleDef *module, int fd, int mode)
3249/*[clinic end generated code: output=3c19fbfd724a8e0f input=8ab11975ca01ee5b]*/
3250{
3251 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003252 int async_err = 0;
3253
3254 do {
3255 Py_BEGIN_ALLOW_THREADS
3256 res = fchmod(fd, mode);
3257 Py_END_ALLOW_THREADS
3258 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3259 if (res != 0)
3260 return (!async_err) ? posix_error() : NULL;
3261
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003263}
3264#endif /* HAVE_FCHMOD */
3265
Larry Hastings2f936352014-08-05 14:04:04 +10003266
Christian Heimes4e30a842007-11-30 22:12:06 +00003267#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003268/*[clinic input]
3269os.lchmod
3270
3271 path: path_t
3272 mode: int
3273
3274Change the access permissions of a file, without following symbolic links.
3275
3276If path is a symlink, this affects the link itself rather than the target.
3277Equivalent to chmod(path, mode, follow_symlinks=False)."
3278[clinic start generated code]*/
3279
3280PyDoc_STRVAR(os_lchmod__doc__,
3281"lchmod($module, /, path, mode)\n"
3282"--\n"
3283"\n"
3284"Change the access permissions of a file, without following symbolic links.\n"
3285"\n"
3286"If path is a symlink, this affects the link itself rather than the target.\n"
3287"Equivalent to chmod(path, mode, follow_symlinks=False).\"");
3288
3289#define OS_LCHMOD_METHODDEF \
3290 {"lchmod", (PyCFunction)os_lchmod, METH_VARARGS|METH_KEYWORDS, os_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00003291
3292static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003293os_lchmod_impl(PyModuleDef *module, path_t *path, int mode);
3294
3295static PyObject *
3296os_lchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00003297{
Larry Hastings2f936352014-08-05 14:04:04 +10003298 PyObject *return_value = NULL;
3299 static char *_keywords[] = {"path", "mode", NULL};
3300 path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0);
3301 int mode;
3302
3303 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3304 "O&i:lchmod", _keywords,
3305 path_converter, &path, &mode))
3306 goto exit;
3307 return_value = os_lchmod_impl(module, &path, mode);
3308
3309exit:
3310 /* Cleanup for path */
3311 path_cleanup(&path);
3312
3313 return return_value;
3314}
3315
3316static PyObject *
3317os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
3318/*[clinic end generated code: output=2849977d65f8c68c input=90c5663c7465d24f]*/
3319{
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003322 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003324 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003325 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003326 return NULL;
3327 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003329}
3330#endif /* HAVE_LCHMOD */
3331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003332
Thomas Wouterscf297e42007-02-23 15:07:44 +00003333#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003334/*[clinic input]
3335os.chflags
3336
3337 path: path_t
3338 flags: unsigned_long(bitwise=True)
3339 follow_symlinks: bool=True
3340
3341Set file flags.
3342
3343If follow_symlinks is False, and the last element of the path is a symbolic
3344 link, chflags will change flags on the symbolic link itself instead of the
3345 file the link points to.
3346follow_symlinks may not be implemented on your platform. If it is
3347unavailable, using it will raise a NotImplementedError.
3348
3349[clinic start generated code]*/
3350
3351PyDoc_STRVAR(os_chflags__doc__,
3352"chflags($module, /, path, flags, follow_symlinks=True)\n"
3353"--\n"
3354"\n"
3355"Set file flags.\n"
3356"\n"
3357"If follow_symlinks is False, and the last element of the path is a symbolic\n"
3358" link, chflags will change flags on the symbolic link itself instead of the\n"
3359" file the link points to.\n"
3360"follow_symlinks may not be implemented on your platform. If it is\n"
3361"unavailable, using it will raise a NotImplementedError.");
3362
3363#define OS_CHFLAGS_METHODDEF \
3364 {"chflags", (PyCFunction)os_chflags, METH_VARARGS|METH_KEYWORDS, os_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00003365
3366static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003367os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks);
3368
3369static PyObject *
3370os_chflags(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003371{
Larry Hastings2f936352014-08-05 14:04:04 +10003372 PyObject *return_value = NULL;
3373 static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL};
3374 path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377
Larry Hastings2f936352014-08-05 14:04:04 +10003378 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3379 "O&k|p:chflags", _keywords,
3380 path_converter, &path, &flags, &follow_symlinks))
3381 goto exit;
3382 return_value = os_chflags_impl(module, &path, flags, follow_symlinks);
3383
3384exit:
3385 /* Cleanup for path */
3386 path_cleanup(&path);
3387
3388 return return_value;
3389}
3390
3391static PyObject *
3392os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks)
3393/*[clinic end generated code: output=2767927bf071e3cf input=0327e29feb876236]*/
3394{
3395 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396
3397#ifndef HAVE_LCHFLAGS
3398 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003399 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400#endif
3401
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403#ifdef HAVE_LCHFLAGS
3404 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003405 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 else
3407#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003408 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410
Larry Hastings2f936352014-08-05 14:04:04 +10003411 if (result)
3412 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413
Larry Hastings2f936352014-08-05 14:04:04 +10003414 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003415}
3416#endif /* HAVE_CHFLAGS */
3417
Larry Hastings2f936352014-08-05 14:04:04 +10003418
Thomas Wouterscf297e42007-02-23 15:07:44 +00003419#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003420/*[clinic input]
3421os.lchflags
3422
3423 path: path_t
3424 flags: unsigned_long(bitwise=True)
3425
3426Set file flags.
3427
3428This function will not follow symbolic links.
3429Equivalent to chflags(path, flags, follow_symlinks=False).
3430[clinic start generated code]*/
3431
3432PyDoc_STRVAR(os_lchflags__doc__,
3433"lchflags($module, /, path, flags)\n"
3434"--\n"
3435"\n"
3436"Set file flags.\n"
3437"\n"
3438"This function will not follow symbolic links.\n"
3439"Equivalent to chflags(path, flags, follow_symlinks=False).");
3440
3441#define OS_LCHFLAGS_METHODDEF \
3442 {"lchflags", (PyCFunction)os_lchflags, METH_VARARGS|METH_KEYWORDS, os_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00003443
3444static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003445os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags);
3446
3447static PyObject *
3448os_lchflags(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003449{
Larry Hastings2f936352014-08-05 14:04:04 +10003450 PyObject *return_value = NULL;
3451 static char *_keywords[] = {"path", "flags", NULL};
3452 path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 unsigned long flags;
Larry Hastings2f936352014-08-05 14:04:04 +10003454
3455 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3456 "O&k:lchflags", _keywords,
3457 path_converter, &path, &flags))
3458 goto exit;
3459 return_value = os_lchflags_impl(module, &path, flags);
3460
3461exit:
3462 /* Cleanup for path */
3463 path_cleanup(&path);
3464
3465 return return_value;
3466}
3467
3468static PyObject *
3469os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
3470/*[clinic end generated code: output=bb93b6b8a5e45aa7 input=f9f82ea8b585ca9d]*/
3471{
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003473 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003474 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003476 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003477 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003478 }
Victor Stinner292c8352012-10-30 02:17:38 +01003479 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003480}
3481#endif /* HAVE_LCHFLAGS */
3482
Larry Hastings2f936352014-08-05 14:04:04 +10003483
Martin v. Löwis244edc82001-10-04 22:44:26 +00003484#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003485/*[clinic input]
3486os.chroot
3487 path: path_t
3488
3489Change root directory to path.
3490
3491[clinic start generated code]*/
3492
3493PyDoc_STRVAR(os_chroot__doc__,
3494"chroot($module, /, path)\n"
3495"--\n"
3496"\n"
3497"Change root directory to path.");
3498
3499#define OS_CHROOT_METHODDEF \
3500 {"chroot", (PyCFunction)os_chroot, METH_VARARGS|METH_KEYWORDS, os_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00003501
3502static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003503os_chroot_impl(PyModuleDef *module, path_t *path);
3504
3505static PyObject *
3506os_chroot(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis244edc82001-10-04 22:44:26 +00003507{
Larry Hastings2f936352014-08-05 14:04:04 +10003508 PyObject *return_value = NULL;
3509 static char *_keywords[] = {"path", NULL};
3510 path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0);
3511
3512 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3513 "O&:chroot", _keywords,
3514 path_converter, &path))
3515 goto exit;
3516 return_value = os_chroot_impl(module, &path);
3517
3518exit:
3519 /* Cleanup for path */
3520 path_cleanup(&path);
3521
3522 return return_value;
Martin v. Löwis244edc82001-10-04 22:44:26 +00003523}
Larry Hastings2f936352014-08-05 14:04:04 +10003524
3525static PyObject *
3526os_chroot_impl(PyModuleDef *module, path_t *path)
3527/*[clinic end generated code: output=15b1256cbe4f24a1 input=14822965652c3dc3]*/
3528{
3529 int res;
3530 Py_BEGIN_ALLOW_THREADS
3531 res = chroot(path->narrow);
3532 Py_END_ALLOW_THREADS
3533 if (res < 0)
3534 return path_error(path);
3535 Py_RETURN_NONE;
3536}
3537#endif /* HAVE_CHROOT */
3538
Martin v. Löwis244edc82001-10-04 22:44:26 +00003539
Guido van Rossum21142a01999-01-08 21:05:37 +00003540#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003541/*[clinic input]
3542os.fsync
3543
3544 fd: fildes
3545
3546Force write of fd to disk.
3547[clinic start generated code]*/
3548
3549PyDoc_STRVAR(os_fsync__doc__,
3550"fsync($module, /, fd)\n"
3551"--\n"
3552"\n"
3553"Force write of fd to disk.");
3554
3555#define OS_FSYNC_METHODDEF \
3556 {"fsync", (PyCFunction)os_fsync, METH_VARARGS|METH_KEYWORDS, os_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00003557
3558static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003559os_fsync_impl(PyModuleDef *module, int fd);
3560
3561static PyObject *
3562os_fsync(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum21142a01999-01-08 21:05:37 +00003563{
Larry Hastings2f936352014-08-05 14:04:04 +10003564 PyObject *return_value = NULL;
3565 static char *_keywords[] = {"fd", NULL};
3566 int fd;
3567
3568 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3569 "O&:fsync", _keywords,
3570 fildes_converter, &fd))
3571 goto exit;
3572 return_value = os_fsync_impl(module, fd);
3573
3574exit:
3575 return return_value;
3576}
3577
3578static PyObject *
3579os_fsync_impl(PyModuleDef *module, int fd)
3580/*[clinic end generated code: output=59f32d3a0b360133 input=21c3645c056967f2]*/
3581{
3582 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003583}
3584#endif /* HAVE_FSYNC */
3585
Larry Hastings2f936352014-08-05 14:04:04 +10003586
Ross Lagerwall7807c352011-03-17 20:20:30 +02003587#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003588/*[clinic input]
3589os.sync
3590
3591Force write of everything to disk.
3592[clinic start generated code]*/
3593
3594PyDoc_STRVAR(os_sync__doc__,
3595"sync($module, /)\n"
3596"--\n"
3597"\n"
3598"Force write of everything to disk.");
3599
3600#define OS_SYNC_METHODDEF \
3601 {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02003602
3603static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003604os_sync_impl(PyModuleDef *module);
3605
3606static PyObject *
3607os_sync(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
3608{
3609 return os_sync_impl(module);
3610}
3611
3612static PyObject *
3613os_sync_impl(PyModuleDef *module)
3614/*[clinic end generated code: output=526c495683d0bb38 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003615{
3616 Py_BEGIN_ALLOW_THREADS
3617 sync();
3618 Py_END_ALLOW_THREADS
3619 Py_RETURN_NONE;
3620}
Larry Hastings2f936352014-08-05 14:04:04 +10003621#endif /* HAVE_SYNC */
3622
Ross Lagerwall7807c352011-03-17 20:20:30 +02003623
Guido van Rossum21142a01999-01-08 21:05:37 +00003624#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003625#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003626extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3627#endif
3628
Larry Hastings2f936352014-08-05 14:04:04 +10003629/*[clinic input]
3630os.fdatasync
3631
3632 fd: fildes
3633
3634Force write of fd to disk without forcing update of metadata.
3635[clinic start generated code]*/
3636
3637PyDoc_STRVAR(os_fdatasync__doc__,
3638"fdatasync($module, /, fd)\n"
3639"--\n"
3640"\n"
3641"Force write of fd to disk without forcing update of metadata.");
3642
3643#define OS_FDATASYNC_METHODDEF \
3644 {"fdatasync", (PyCFunction)os_fdatasync, METH_VARARGS|METH_KEYWORDS, os_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00003645
3646static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003647os_fdatasync_impl(PyModuleDef *module, int fd);
3648
3649static PyObject *
3650os_fdatasync(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum21142a01999-01-08 21:05:37 +00003651{
Larry Hastings2f936352014-08-05 14:04:04 +10003652 PyObject *return_value = NULL;
3653 static char *_keywords[] = {"fd", NULL};
3654 int fd;
3655
3656 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3657 "O&:fdatasync", _keywords,
3658 fildes_converter, &fd))
3659 goto exit;
3660 return_value = os_fdatasync_impl(module, fd);
3661
3662exit:
3663 return return_value;
3664}
3665
3666static PyObject *
3667os_fdatasync_impl(PyModuleDef *module, int fd)
3668/*[clinic end generated code: output=2335fdfd37c92180 input=bc74791ee54dd291]*/
3669{
3670 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003671}
3672#endif /* HAVE_FDATASYNC */
3673
3674
Fredrik Lundh10723342000-07-10 16:38:09 +00003675#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003676/*[clinic input]
3677os.chown
3678
3679 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3680 Path to be examined; can be string, bytes, or open-file-descriptor int.
3681
3682 uid: uid_t
3683
3684 gid: gid_t
3685
3686 *
3687
3688 dir_fd : dir_fd(requires='fchownat') = None
3689 If not None, it should be a file descriptor open to a directory,
3690 and path should be relative; path will then be relative to that
3691 directory.
3692
3693 follow_symlinks: bool = True
3694 If False, and the last element of the path is a symbolic link,
3695 stat will examine the symbolic link itself instead of the file
3696 the link points to.
3697
3698Change the owner and group id of path to the numeric uid and gid.\
3699
3700path may always be specified as a string.
3701On some platforms, path may also be specified as an open file descriptor.
3702 If this functionality is unavailable, using it raises an exception.
3703If dir_fd is not None, it should be a file descriptor open to a directory,
3704 and path should be relative; path will then be relative to that directory.
3705If follow_symlinks is False, and the last element of the path is a symbolic
3706 link, chown will modify the symbolic link itself instead of the file the
3707 link points to.
3708It is an error to use dir_fd or follow_symlinks when specifying path as
3709 an open file descriptor.
3710dir_fd and follow_symlinks may not be implemented on your platform.
3711 If they are unavailable, using them will raise a NotImplementedError.
3712
3713[clinic start generated code]*/
3714
3715PyDoc_STRVAR(os_chown__doc__,
3716"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n"
3717"--\n"
3718"\n"
3719"Change the owner and group id of path to the numeric uid and gid.\\\n"
3720"\n"
3721" path\n"
3722" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
3723" dir_fd\n"
3724" If not None, it should be a file descriptor open to a directory,\n"
3725" and path should be relative; path will then be relative to that\n"
3726" directory.\n"
3727" follow_symlinks\n"
3728" If False, and the last element of the path is a symbolic link,\n"
3729" stat will examine the symbolic link itself instead of the file\n"
3730" the link points to.\n"
3731"\n"
3732"path may always be specified as a string.\n"
3733"On some platforms, path may also be specified as an open file descriptor.\n"
3734" If this functionality is unavailable, using it raises an exception.\n"
3735"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
3736" and path should be relative; path will then be relative to that directory.\n"
3737"If follow_symlinks is False, and the last element of the path is a symbolic\n"
3738" link, chown will modify the symbolic link itself instead of the file the\n"
3739" link points to.\n"
3740"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
3741" an open file descriptor.\n"
3742"dir_fd and follow_symlinks may not be implemented on your platform.\n"
3743" If they are unavailable, using them will raise a NotImplementedError.");
3744
3745#define OS_CHOWN_METHODDEF \
3746 {"chown", (PyCFunction)os_chown, METH_VARARGS|METH_KEYWORDS, os_chown__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003747
Barry Warsaw53699e91996-12-10 23:23:01 +00003748static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003749os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks);
3750
3751static PyObject *
3752os_chown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003753{
Larry Hastings2f936352014-08-05 14:04:04 +10003754 PyObject *return_value = NULL;
3755 static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL};
3756 path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003757 uid_t uid;
3758 gid_t gid;
3759 int dir_fd = DEFAULT_DIR_FD;
3760 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761
Larry Hastings2f936352014-08-05 14:04:04 +10003762 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3763 "O&O&O&|$O&p:chown", _keywords,
3764 path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
3765 goto exit;
3766 return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks);
3767
3768exit:
3769 /* Cleanup for path */
3770 path_cleanup(&path);
3771
3772 return return_value;
3773}
3774
3775static PyObject *
3776os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks)
3777/*[clinic end generated code: output=22f011e3b4f9ff49 input=a61cc35574814d5d]*/
3778{
3779 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003780
3781#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3782 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003783 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003784#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003785 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3786 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3787 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788
3789#ifdef __APPLE__
3790 /*
3791 * This is for Mac OS X 10.3, which doesn't have lchown.
3792 * (But we still have an lchown symbol because of weak-linking.)
3793 * It doesn't have fchownat either. So there's no possibility
3794 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003795 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003796 if ((!follow_symlinks) && (lchown == NULL)) {
3797 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003798 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003799 }
3800#endif
3801
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003803#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003804 if (path->fd != -1)
3805 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003806 else
3807#endif
3808#ifdef HAVE_LCHOWN
3809 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003810 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811 else
3812#endif
3813#ifdef HAVE_FCHOWNAT
3814 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003815 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003816 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3817 else
3818#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003819 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003821
Larry Hastings2f936352014-08-05 14:04:04 +10003822 if (result)
3823 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003824
Larry Hastings2f936352014-08-05 14:04:04 +10003825 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003826}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003827#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003828
Larry Hastings2f936352014-08-05 14:04:04 +10003829
Christian Heimes4e30a842007-11-30 22:12:06 +00003830#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003831/*[clinic input]
3832os.fchown
3833
3834 fd: int
3835 uid: uid_t
3836 gid: gid_t
3837
3838Change the owner and group id of the file specified by file descriptor.
3839
3840Equivalent to os.chown(fd, uid, gid).
3841
3842[clinic start generated code]*/
3843
3844PyDoc_STRVAR(os_fchown__doc__,
3845"fchown($module, /, fd, uid, gid)\n"
3846"--\n"
3847"\n"
3848"Change the owner and group id of the file specified by file descriptor.\n"
3849"\n"
3850"Equivalent to os.chown(fd, uid, gid).");
3851
3852#define OS_FCHOWN_METHODDEF \
3853 {"fchown", (PyCFunction)os_fchown, METH_VARARGS|METH_KEYWORDS, os_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00003854
3855static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003856os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid);
3857
3858static PyObject *
3859os_fchown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00003860{
Larry Hastings2f936352014-08-05 14:04:04 +10003861 PyObject *return_value = NULL;
3862 static char *_keywords[] = {"fd", "uid", "gid", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003864 uid_t uid;
3865 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10003866
3867 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3868 "iO&O&:fchown", _keywords,
3869 &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid))
3870 goto exit;
3871 return_value = os_fchown_impl(module, fd, uid, gid);
3872
3873exit:
3874 return return_value;
3875}
3876
3877static PyObject *
3878os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
3879/*[clinic end generated code: output=687781cb7d8974d6 input=3af544ba1b13a0d7]*/
3880{
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003882 int async_err = 0;
3883
3884 do {
3885 Py_BEGIN_ALLOW_THREADS
3886 res = fchown(fd, uid, gid);
3887 Py_END_ALLOW_THREADS
3888 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3889 if (res != 0)
3890 return (!async_err) ? posix_error() : NULL;
3891
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003893}
3894#endif /* HAVE_FCHOWN */
3895
Larry Hastings2f936352014-08-05 14:04:04 +10003896
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003897#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003898/*[clinic input]
3899os.lchown
3900
3901 path : path_t
3902 uid: uid_t
3903 gid: gid_t
3904
3905Change the owner and group id of path to the numeric uid and gid.
3906
3907This function will not follow symbolic links.
3908Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3909[clinic start generated code]*/
3910
3911PyDoc_STRVAR(os_lchown__doc__,
3912"lchown($module, /, path, uid, gid)\n"
3913"--\n"
3914"\n"
3915"Change the owner and group id of path to the numeric uid and gid.\n"
3916"\n"
3917"This function will not follow symbolic links.\n"
3918"Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
3919
3920#define OS_LCHOWN_METHODDEF \
3921 {"lchown", (PyCFunction)os_lchown, METH_VARARGS|METH_KEYWORDS, os_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003922
3923static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003924os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid);
3925
3926static PyObject *
3927os_lchown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003928{
Larry Hastings2f936352014-08-05 14:04:04 +10003929 PyObject *return_value = NULL;
3930 static char *_keywords[] = {"path", "uid", "gid", NULL};
3931 path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003932 uid_t uid;
3933 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10003934
3935 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3936 "O&O&O&:lchown", _keywords,
3937 path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid))
3938 goto exit;
3939 return_value = os_lchown_impl(module, &path, uid, gid);
3940
3941exit:
3942 /* Cleanup for path */
3943 path_cleanup(&path);
3944
3945 return return_value;
3946}
3947
3948static PyObject *
3949os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
3950/*[clinic end generated code: output=bf25fdb0d25130e2 input=b1c6014d563a7161]*/
3951{
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003953 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003954 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003955 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003956 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003957 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003958 }
Larry Hastings2f936352014-08-05 14:04:04 +10003959 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003960}
3961#endif /* HAVE_LCHOWN */
3962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003963
Barry Warsaw53699e91996-12-10 23:23:01 +00003964static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003965posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966{
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 char buf[1026];
3968 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003969
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003970#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003971 if (!use_bytes) {
3972 wchar_t wbuf[1026];
3973 wchar_t *wbuf2 = wbuf;
3974 PyObject *resobj;
3975 DWORD len;
3976 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003977 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 /* If the buffer is large enough, len does not include the
3979 terminating \0. If the buffer is too small, len includes
3980 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003981 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003982 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 if (wbuf2)
3984 len = GetCurrentDirectoryW(len, wbuf2);
3985 }
3986 Py_END_ALLOW_THREADS
3987 if (!wbuf2) {
3988 PyErr_NoMemory();
3989 return NULL;
3990 }
3991 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003992 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003993 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003994 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 }
3996 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003997 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003998 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003999 return resobj;
4000 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01004001
4002 if (win32_warn_bytes_api())
4003 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004004#endif
4005
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 Py_END_ALLOW_THREADS
4009 if (res == NULL)
4010 return posix_error();
4011 if (use_bytes)
4012 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00004013 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004014}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004015
Larry Hastings2f936352014-08-05 14:04:04 +10004016
4017/*[clinic input]
4018os.getcwd
4019
4020Return a unicode string representing the current working directory.
4021[clinic start generated code]*/
4022
4023PyDoc_STRVAR(os_getcwd__doc__,
4024"getcwd($module, /)\n"
4025"--\n"
4026"\n"
4027"Return a unicode string representing the current working directory.");
4028
4029#define OS_GETCWD_METHODDEF \
4030 {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__},
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004031
4032static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004033os_getcwd_impl(PyModuleDef *module);
4034
4035static PyObject *
4036os_getcwd(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
4037{
4038 return os_getcwd_impl(module);
4039}
4040
4041static PyObject *
4042os_getcwd_impl(PyModuleDef *module)
4043/*[clinic end generated code: output=d70b281db5c78ff7 input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004044{
4045 return posix_getcwd(0);
4046}
4047
Larry Hastings2f936352014-08-05 14:04:04 +10004048
4049/*[clinic input]
4050os.getcwdb
4051
4052Return a bytes string representing the current working directory.
4053[clinic start generated code]*/
4054
4055PyDoc_STRVAR(os_getcwdb__doc__,
4056"getcwdb($module, /)\n"
4057"--\n"
4058"\n"
4059"Return a bytes string representing the current working directory.");
4060
4061#define OS_GETCWDB_METHODDEF \
4062 {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__},
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004063
4064static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004065os_getcwdb_impl(PyModuleDef *module);
4066
4067static PyObject *
4068os_getcwdb(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
4069{
4070 return os_getcwdb_impl(module);
4071}
4072
4073static PyObject *
4074os_getcwdb_impl(PyModuleDef *module)
4075/*[clinic end generated code: output=75da47f2d75f9166 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004076{
4077 return posix_getcwd(1);
4078}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004079
Larry Hastings2f936352014-08-05 14:04:04 +10004080
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
4082#define HAVE_LINK 1
4083#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004084
Guido van Rossumb6775db1994-08-01 11:34:53 +00004085#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10004086/*[clinic input]
4087
4088os.link
4089
4090 src : path_t
4091 dst : path_t
4092 *
4093 src_dir_fd : dir_fd = None
4094 dst_dir_fd : dir_fd = None
4095 follow_symlinks: bool = True
4096
4097Create a hard link to a file.
4098
4099If either src_dir_fd or dst_dir_fd is not None, it should be a file
4100 descriptor open to a directory, and the respective path string (src or dst)
4101 should be relative; the path will then be relative to that directory.
4102If follow_symlinks is False, and the last element of src is a symbolic
4103 link, link will create a link to the symbolic link itself instead of the
4104 file the link points to.
4105src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
4106 platform. If they are unavailable, using them will raise a
4107 NotImplementedError.
4108[clinic start generated code]*/
4109
4110PyDoc_STRVAR(os_link__doc__,
4111"link($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None,\n"
4112" follow_symlinks=True)\n"
4113"--\n"
4114"\n"
4115"Create a hard link to a file.\n"
4116"\n"
4117"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
4118" descriptor open to a directory, and the respective path string (src or dst)\n"
4119" should be relative; the path will then be relative to that directory.\n"
4120"If follow_symlinks is False, and the last element of src is a symbolic\n"
4121" link, link will create a link to the symbolic link itself instead of the\n"
4122" file the link points to.\n"
4123"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n"
4124" platform. If they are unavailable, using them will raise a\n"
4125" NotImplementedError.");
4126
4127#define OS_LINK_METHODDEF \
4128 {"link", (PyCFunction)os_link, METH_VARARGS|METH_KEYWORDS, os_link__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Barry Warsaw53699e91996-12-10 23:23:01 +00004130static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004131os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks);
4132
4133static PyObject *
4134os_link(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004135{
Larry Hastings2f936352014-08-05 14:04:04 +10004136 PyObject *return_value = NULL;
4137 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL};
4138 path_t src = PATH_T_INITIALIZE("link", "src", 0, 0);
4139 path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 int src_dir_fd = DEFAULT_DIR_FD;
4141 int dst_dir_fd = DEFAULT_DIR_FD;
4142 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10004143
4144 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4145 "O&O&|$O&O&p:link", _keywords,
4146 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks))
4147 goto exit;
4148 return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks);
4149
4150exit:
4151 /* Cleanup for src */
4152 path_cleanup(&src);
4153 /* Cleanup for dst */
4154 path_cleanup(&dst);
4155
4156 return return_value;
4157}
4158
4159static PyObject *
4160os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks)
4161/*[clinic end generated code: output=53477662fe02e183 input=b0095ebbcbaa7e04]*/
4162{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163#ifdef MS_WINDOWS
4164 BOOL result;
4165#else
4166 int result;
4167#endif
4168
Larry Hastings9cf065c2012-06-22 16:30:09 -07004169#ifndef HAVE_LINKAT
4170 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
4171 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004172 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173 }
4174#endif
4175
Larry Hastings2f936352014-08-05 14:04:04 +10004176 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004177 PyErr_SetString(PyExc_NotImplementedError,
4178 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10004179 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004180 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004181
Brian Curtin1b9df392010-11-24 20:24:31 +00004182#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004183 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004184 if (src->wide)
4185 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004186 else
Larry Hastings2f936352014-08-05 14:04:04 +10004187 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004188 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00004189
Larry Hastings2f936352014-08-05 14:04:04 +10004190 if (!result)
4191 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004192#else
4193 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07004194#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07004195 if ((src_dir_fd != DEFAULT_DIR_FD) ||
4196 (dst_dir_fd != DEFAULT_DIR_FD) ||
4197 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004198 result = linkat(src_dir_fd, src->narrow,
4199 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004200 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
4201 else
4202#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004203 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004204 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00004205
Larry Hastings2f936352014-08-05 14:04:04 +10004206 if (result)
4207 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004208#endif
4209
Larry Hastings2f936352014-08-05 14:04:04 +10004210 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00004211}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004212#endif
4213
Brian Curtin1b9df392010-11-24 20:24:31 +00004214
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004215#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00004216static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004217_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00004218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004219 PyObject *v;
4220 HANDLE hFindFile = INVALID_HANDLE_VALUE;
4221 BOOL result;
4222 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01004223 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004224 char *bufptr = namebuf;
4225 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01004226 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227 PyObject *po = NULL;
4228 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229
Gregory P. Smith40a21602013-03-20 20:52:50 -07004230 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004231 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004233
Gregory P. Smith40a21602013-03-20 20:52:50 -07004234 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004235 po_wchars = L".";
4236 len = 1;
4237 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004238 po_wchars = path->wide;
4239 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004240 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004241 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004242 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 if (!wnamebuf) {
4244 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004245 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004246 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004247 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004248 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004249 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01004250 if (wch != SEP && wch != ALTSEP && wch != L':')
4251 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00004252 wcscpy(wnamebuf + len, L"*.*");
4253 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 if ((list = PyList_New(0)) == NULL) {
4255 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004256 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004257 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004259 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004260 if (hFindFile == INVALID_HANDLE_VALUE) {
4261 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262 if (error == ERROR_FILE_NOT_FOUND)
4263 goto exit;
4264 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004265 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004266 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 }
4268 do {
4269 /* Skip over . and .. */
4270 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4271 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004272 v = PyUnicode_FromWideChar(wFileData.cFileName,
4273 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004275 Py_DECREF(list);
4276 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004277 break;
4278 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004279 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004280 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004281 Py_DECREF(list);
4282 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004283 break;
4284 }
4285 Py_DECREF(v);
4286 }
4287 Py_BEGIN_ALLOW_THREADS
4288 result = FindNextFileW(hFindFile, &wFileData);
4289 Py_END_ALLOW_THREADS
4290 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4291 it got to the end of the directory. */
4292 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004293 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004294 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004295 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004296 }
4297 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00004298
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004300 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07004301 strcpy(namebuf, path->narrow);
4302 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 if (len > 0) {
4304 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01004305 if (ch != '\\' && ch != '/' && ch != ':')
4306 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 strcpy(namebuf + len, "*.*");
4308 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00004309
Larry Hastings9cf065c2012-06-22 16:30:09 -07004310 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00004311 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004312
Antoine Pitroub73caab2010-08-09 23:39:31 +00004313 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004314 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004315 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 if (hFindFile == INVALID_HANDLE_VALUE) {
4317 int error = GetLastError();
4318 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319 goto exit;
4320 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004321 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004322 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004323 }
4324 do {
4325 /* Skip over . and .. */
4326 if (strcmp(FileData.cFileName, ".") != 0 &&
4327 strcmp(FileData.cFileName, "..") != 0) {
4328 v = PyBytes_FromString(FileData.cFileName);
4329 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004330 Py_DECREF(list);
4331 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 break;
4333 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004335 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336 Py_DECREF(list);
4337 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 break;
4339 }
4340 Py_DECREF(v);
4341 }
4342 Py_BEGIN_ALLOW_THREADS
4343 result = FindNextFile(hFindFile, &FileData);
4344 Py_END_ALLOW_THREADS
4345 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4346 it got to the end of the directory. */
4347 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004348 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004349 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004350 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004351 }
4352 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004353
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354exit:
4355 if (hFindFile != INVALID_HANDLE_VALUE) {
4356 if (FindClose(hFindFile) == FALSE) {
4357 if (list != NULL) {
4358 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004359 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360 }
4361 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004362 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004363 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004364
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004366} /* end of _listdir_windows_no_opendir */
4367
4368#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4369
4370static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004371_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004372{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004373 PyObject *v;
4374 DIR *dirp = NULL;
4375 struct dirent *ep;
4376 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004377#ifdef HAVE_FDOPENDIR
4378 int fd = -1;
4379#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004380
Victor Stinner8c62be82010-05-06 00:08:46 +00004381 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004383 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004385 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004386 if (fd == -1)
4387 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388
Larry Hastingsfdaea062012-06-25 04:42:23 -07004389 return_str = 1;
4390
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391 Py_BEGIN_ALLOW_THREADS
4392 dirp = fdopendir(fd);
4393 Py_END_ALLOW_THREADS
4394 }
4395 else
4396#endif
4397 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07004398 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004399 if (path->narrow) {
4400 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004401 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07004402 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07004403 }
4404 else {
4405 name = ".";
4406 return_str = 1;
4407 }
4408
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409 Py_BEGIN_ALLOW_THREADS
4410 dirp = opendir(name);
4411 Py_END_ALLOW_THREADS
4412 }
4413
4414 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004415 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004416#ifdef HAVE_FDOPENDIR
4417 if (fd != -1) {
4418 Py_BEGIN_ALLOW_THREADS
4419 close(fd);
4420 Py_END_ALLOW_THREADS
4421 }
4422#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423 goto exit;
4424 }
4425 if ((list = PyList_New(0)) == NULL) {
4426 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004427 }
4428 for (;;) {
4429 errno = 0;
4430 Py_BEGIN_ALLOW_THREADS
4431 ep = readdir(dirp);
4432 Py_END_ALLOW_THREADS
4433 if (ep == NULL) {
4434 if (errno == 0) {
4435 break;
4436 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004438 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 }
4441 }
4442 if (ep->d_name[0] == '.' &&
4443 (NAMLEN(ep) == 1 ||
4444 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4445 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004446 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004447 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4448 else
4449 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004452 break;
4453 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004455 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004457 break;
4458 }
4459 Py_DECREF(v);
4460 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004461
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462exit:
4463 if (dirp != NULL) {
4464 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004465#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466 if (fd > -1)
4467 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004468#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 closedir(dirp);
4470 Py_END_ALLOW_THREADS
4471 }
4472
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004474} /* end of _posix_listdir */
4475#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004476
Larry Hastings2f936352014-08-05 14:04:04 +10004477
4478/*[clinic input]
4479os.listdir
4480
4481 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4482
4483Return a list containing the names of the files in the directory.
4484
4485path can be specified as either str or bytes. If path is bytes,
4486 the filenames returned will also be bytes; in all other circumstances
4487 the filenames returned will be str.
4488If path is None, uses the path='.'.
4489On some platforms, path may also be specified as an open file descriptor;\
4490 the file descriptor must refer to a directory.
4491 If this functionality is unavailable, using it raises NotImplementedError.
4492
4493The list is in arbitrary order. It does not include the special
4494entries '.' and '..' even if they are present in the directory.
4495
4496
4497[clinic start generated code]*/
4498
4499PyDoc_STRVAR(os_listdir__doc__,
4500"listdir($module, /, path=None)\n"
4501"--\n"
4502"\n"
4503"Return a list containing the names of the files in the directory.\n"
4504"\n"
4505"path can be specified as either str or bytes. If path is bytes,\n"
4506" the filenames returned will also be bytes; in all other circumstances\n"
4507" the filenames returned will be str.\n"
4508"If path is None, uses the path=\'.\'.\n"
4509"On some platforms, path may also be specified as an open file descriptor;\\\n"
4510" the file descriptor must refer to a directory.\n"
4511" If this functionality is unavailable, using it raises NotImplementedError.\n"
4512"\n"
4513"The list is in arbitrary order. It does not include the special\n"
4514"entries \'.\' and \'..\' even if they are present in the directory.");
4515
4516#define OS_LISTDIR_METHODDEF \
4517 {"listdir", (PyCFunction)os_listdir, METH_VARARGS|METH_KEYWORDS, os_listdir__doc__},
4518
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004519static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004520os_listdir_impl(PyModuleDef *module, path_t *path);
4521
4522static PyObject *
4523os_listdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004524{
Larry Hastings2f936352014-08-05 14:04:04 +10004525 PyObject *return_value = NULL;
4526 static char *_keywords[] = {"path", NULL};
4527 path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004528
Larry Hastings2f936352014-08-05 14:04:04 +10004529 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4530 "|O&:listdir", _keywords,
4531 path_converter, &path))
4532 goto exit;
4533 return_value = os_listdir_impl(module, &path);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004534
Larry Hastings2f936352014-08-05 14:04:04 +10004535exit:
4536 /* Cleanup for path */
Gregory P. Smith40a21602013-03-20 20:52:50 -07004537 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +10004538
Gregory P. Smith40a21602013-03-20 20:52:50 -07004539 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004540}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004541
Larry Hastings2f936352014-08-05 14:04:04 +10004542static PyObject *
4543os_listdir_impl(PyModuleDef *module, path_t *path)
4544/*[clinic end generated code: output=e159bd9be6909018 input=09e300416e3cd729]*/
4545{
4546#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4547 return _listdir_windows_no_opendir(path, NULL);
4548#else
4549 return _posix_listdir(path, NULL);
4550#endif
4551}
4552
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004553#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004554/* A helper function for abspath on win32 */
Larry Hastings2f936352014-08-05 14:04:04 +10004555/* AC 3.5: probably just convert to using path converter */
Mark Hammondef8b6542001-05-13 08:04:26 +00004556static PyObject *
4557posix__getfullpathname(PyObject *self, PyObject *args)
4558{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004559 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01004560 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00004561 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004562 PyObject *po;
4563
4564 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
4565 {
4566 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01004567 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004568 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00004569 DWORD result;
4570 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004571
4572 wpath = PyUnicode_AsUnicode(po);
4573 if (wpath == NULL)
4574 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02004576 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02004578 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004579 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00004580 if (!woutbufp)
4581 return PyErr_NoMemory();
4582 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
4583 }
4584 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004585 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00004586 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02004587 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02004589 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00004590 return v;
4591 }
4592 /* Drop the argument parsing error as narrow strings
4593 are also valid. */
4594 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02004595
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004596 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
4597 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00004598 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004599 if (win32_warn_bytes_api())
4600 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02004601 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00004602 outbuf, &temp)) {
4603 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 return NULL;
4605 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
4607 return PyUnicode_Decode(outbuf, strlen(outbuf),
4608 Py_FileSystemDefaultEncoding, NULL);
4609 }
4610 return PyBytes_FromString(outbuf);
Larry Hastings2f936352014-08-05 14:04:04 +10004611}
Brian Curtind40e6f72010-07-08 21:39:08 +00004612
Brian Curtind25aef52011-06-13 15:16:04 -05004613
Larry Hastings2f936352014-08-05 14:04:04 +10004614/*[clinic input]
4615os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004616
Larry Hastings2f936352014-08-05 14:04:04 +10004617 path: unicode
4618 /
4619
4620A helper function for samepath on windows.
4621[clinic start generated code]*/
4622
4623PyDoc_STRVAR(os__getfinalpathname__doc__,
4624"_getfinalpathname($module, path, /)\n"
4625"--\n"
4626"\n"
4627"A helper function for samepath on windows.");
4628
4629#define OS__GETFINALPATHNAME_METHODDEF \
4630 {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_VARARGS, os__getfinalpathname__doc__},
4631
Brian Curtind40e6f72010-07-08 21:39:08 +00004632static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004633os__getfinalpathname_impl(PyModuleDef *module, PyObject *path);
4634
4635static PyObject *
4636os__getfinalpathname(PyModuleDef *module, PyObject *args)
4637{
4638 PyObject *return_value = NULL;
4639 PyObject *path;
4640
4641 if (!PyArg_ParseTuple(args,
4642 "U:_getfinalpathname",
4643 &path))
4644 goto exit;
4645 return_value = os__getfinalpathname_impl(module, path);
4646
4647exit:
4648 return return_value;
4649}
4650
4651static PyObject *
4652os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
4653/*[clinic end generated code: output=4563c6eacf1b0881 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004654{
4655 HANDLE hFile;
4656 int buf_size;
4657 wchar_t *target_path;
4658 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004659 PyObject *result;
4660 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004661
Larry Hastings2f936352014-08-05 14:04:04 +10004662 path_wchar = PyUnicode_AsUnicode(path);
4663 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004664 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00004665
Brian Curtind40e6f72010-07-08 21:39:08 +00004666 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10004667 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00004668 0, /* desired access */
4669 0, /* share mode */
4670 NULL, /* security attributes */
4671 OPEN_EXISTING,
4672 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4673 FILE_FLAG_BACKUP_SEMANTICS,
4674 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004675
Victor Stinnereb5657a2011-09-30 01:44:27 +02004676 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10004677 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004678
4679 /* We have a good handle to the target, use it to determine the
4680 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07004681 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00004682
4683 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10004684 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004685
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004686 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00004687 if(!target_path)
4688 return PyErr_NoMemory();
4689
Steve Dower2ea51c92015-03-20 21:49:12 -07004690 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4691 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00004692 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10004693 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004694
4695 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10004696 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004697
4698 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004699 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004700 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004701 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004702}
Brian Curtin62857742010-09-06 17:07:27 +00004703
Brian Curtin95d028f2011-06-09 09:10:38 -05004704PyDoc_STRVAR(posix__isdir__doc__,
4705"Return true if the pathname refers to an existing directory.");
4706
Larry Hastings2f936352014-08-05 14:04:04 +10004707/* AC 3.5: convert using path converter */
Brian Curtin9c669cc2011-06-08 18:17:18 -05004708static PyObject *
4709posix__isdir(PyObject *self, PyObject *args)
4710{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004711 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004712 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004713 DWORD attributes;
4714
4715 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004716 wchar_t *wpath = PyUnicode_AsUnicode(po);
4717 if (wpath == NULL)
4718 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004719
4720 attributes = GetFileAttributesW(wpath);
4721 if (attributes == INVALID_FILE_ATTRIBUTES)
4722 Py_RETURN_FALSE;
4723 goto check;
4724 }
4725 /* Drop the argument parsing error as narrow strings
4726 are also valid. */
4727 PyErr_Clear();
4728
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004729 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004730 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004731 if (win32_warn_bytes_api())
4732 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004733 attributes = GetFileAttributesA(path);
4734 if (attributes == INVALID_FILE_ATTRIBUTES)
4735 Py_RETURN_FALSE;
4736
4737check:
4738 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4739 Py_RETURN_TRUE;
4740 else
4741 Py_RETURN_FALSE;
4742}
Tim Golden6b528062013-08-01 12:44:00 +01004743
Tim Golden6b528062013-08-01 12:44:00 +01004744
Larry Hastings2f936352014-08-05 14:04:04 +10004745/*[clinic input]
4746os._getvolumepathname
4747
4748 path: unicode
4749
4750A helper function for ismount on Win32.
4751[clinic start generated code]*/
4752
4753PyDoc_STRVAR(os__getvolumepathname__doc__,
4754"_getvolumepathname($module, /, path)\n"
4755"--\n"
4756"\n"
4757"A helper function for ismount on Win32.");
4758
4759#define OS__GETVOLUMEPATHNAME_METHODDEF \
4760 {"_getvolumepathname", (PyCFunction)os__getvolumepathname, METH_VARARGS|METH_KEYWORDS, os__getvolumepathname__doc__},
4761
Tim Golden6b528062013-08-01 12:44:00 +01004762static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004763os__getvolumepathname_impl(PyModuleDef *module, PyObject *path);
4764
4765static PyObject *
4766os__getvolumepathname(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Tim Golden6b528062013-08-01 12:44:00 +01004767{
Larry Hastings2f936352014-08-05 14:04:04 +10004768 PyObject *return_value = NULL;
4769 static char *_keywords[] = {"path", NULL};
4770 PyObject *path;
4771
4772 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4773 "U:_getvolumepathname", _keywords,
4774 &path))
4775 goto exit;
4776 return_value = os__getvolumepathname_impl(module, path);
4777
4778exit:
4779 return return_value;
4780}
4781
4782static PyObject *
4783os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
4784/*[clinic end generated code: output=ac0833b6d6da7657 input=7eacadc40acbda6b]*/
4785{
4786 PyObject *result;
4787 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004788 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004789 BOOL ret;
4790
Larry Hastings2f936352014-08-05 14:04:04 +10004791 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
4792 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01004793 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004794 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004795
4796 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004797 buflen = Py_MAX(buflen, MAX_PATH);
4798
4799 if (buflen > DWORD_MAX) {
4800 PyErr_SetString(PyExc_OverflowError, "path too long");
4801 return NULL;
4802 }
4803
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004804 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004805 if (mountpath == NULL)
4806 return PyErr_NoMemory();
4807
4808 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004809 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004810 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004811 Py_END_ALLOW_THREADS
4812
4813 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10004814 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01004815 goto exit;
4816 }
4817 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4818
4819exit:
4820 PyMem_Free(mountpath);
4821 return result;
4822}
Tim Golden6b528062013-08-01 12:44:00 +01004823
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004824#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004825
Larry Hastings2f936352014-08-05 14:04:04 +10004826
4827/*[clinic input]
4828os.mkdir
4829
4830 path : path_t
4831
4832 mode: int = 0o777
4833
4834 *
4835
4836 dir_fd : dir_fd(requires='mkdirat') = None
4837
4838# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4839
4840Create a directory.
4841
4842If dir_fd is not None, it should be a file descriptor open to a directory,
4843 and path should be relative; path will then be relative to that directory.
4844dir_fd may not be implemented on your platform.
4845 If it is unavailable, using it will raise a NotImplementedError.
4846
4847The mode argument is ignored on Windows.
4848[clinic start generated code]*/
4849
4850PyDoc_STRVAR(os_mkdir__doc__,
4851"mkdir($module, /, path, mode=511, *, dir_fd=None)\n"
4852"--\n"
4853"\n"
4854"Create a directory.\n"
4855"\n"
4856"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
4857" and path should be relative; path will then be relative to that directory.\n"
4858"dir_fd may not be implemented on your platform.\n"
4859" If it is unavailable, using it will raise a NotImplementedError.\n"
4860"\n"
4861"The mode argument is ignored on Windows.");
4862
4863#define OS_MKDIR_METHODDEF \
4864 {"mkdir", (PyCFunction)os_mkdir, METH_VARARGS|METH_KEYWORDS, os_mkdir__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004865
Barry Warsaw53699e91996-12-10 23:23:01 +00004866static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004867os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004868
Larry Hastings2f936352014-08-05 14:04:04 +10004869static PyObject *
4870os_mkdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
4871{
4872 PyObject *return_value = NULL;
4873 static char *_keywords[] = {"path", "mode", "dir_fd", NULL};
4874 path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0);
4875 int mode = 511;
4876 int dir_fd = DEFAULT_DIR_FD;
4877
4878 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4879 "O&|i$O&:mkdir", _keywords,
4880 path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd))
4881 goto exit;
4882 return_value = os_mkdir_impl(module, &path, mode, dir_fd);
4883
4884exit:
4885 /* Cleanup for path */
4886 path_cleanup(&path);
4887
4888 return return_value;
4889}
4890
4891static PyObject *
4892os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
4893/*[clinic end generated code: output=55c6ef2bc1b207e6 input=e965f68377e9b1ce]*/
4894{
4895 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004896
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004897#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004899 if (path->wide)
4900 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004901 else
Larry Hastings2f936352014-08-05 14:04:04 +10004902 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004904
Larry Hastings2f936352014-08-05 14:04:04 +10004905 if (!result)
4906 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909#if HAVE_MKDIRAT
4910 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004911 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 else
4913#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004914#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004915 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004916#else
Larry Hastings2f936352014-08-05 14:04:04 +10004917 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004920 if (result < 0)
4921 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004922#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004923 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004924}
4925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004926
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004927/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4928#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004929#include <sys/resource.h>
4930#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004931
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004932
4933#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004934/*[clinic input]
4935os.nice
4936
4937 increment: int
4938 /
4939
4940Add increment to the priority of process and return the new priority.
4941[clinic start generated code]*/
4942
4943PyDoc_STRVAR(os_nice__doc__,
4944"nice($module, increment, /)\n"
4945"--\n"
4946"\n"
4947"Add increment to the priority of process and return the new priority.");
4948
4949#define OS_NICE_METHODDEF \
4950 {"nice", (PyCFunction)os_nice, METH_VARARGS, os_nice__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Barry Warsaw53699e91996-12-10 23:23:01 +00004952static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004953os_nice_impl(PyModuleDef *module, int increment);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004954
Larry Hastings2f936352014-08-05 14:04:04 +10004955static PyObject *
4956os_nice(PyModuleDef *module, PyObject *args)
4957{
4958 PyObject *return_value = NULL;
4959 int increment;
4960
4961 if (!PyArg_ParseTuple(args,
4962 "i:nice",
4963 &increment))
4964 goto exit;
4965 return_value = os_nice_impl(module, increment);
4966
4967exit:
4968 return return_value;
4969}
4970
4971static PyObject *
4972os_nice_impl(PyModuleDef *module, int increment)
4973/*[clinic end generated code: output=c360dc2a3bd8e3d0 input=864be2d402a21da2]*/
4974{
4975 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 /* There are two flavours of 'nice': one that returns the new
4978 priority (as required by almost all standards out there) and the
4979 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4980 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 If we are of the nice family that returns the new priority, we
4983 need to clear errno before the call, and check if errno is filled
4984 before calling posix_error() on a returnvalue of -1, because the
4985 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004986
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 errno = 0;
4988 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004989#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 if (value == 0)
4991 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004992#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 if (value == -1 && errno != 0)
4994 /* either nice() or getpriority() returned an error */
4995 return posix_error();
4996 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004997}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004998#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004999
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005000
5001#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10005002/*[clinic input]
5003os.getpriority
5004
5005 which: int
5006 who: int
5007
5008Return program scheduling priority.
5009[clinic start generated code]*/
5010
5011PyDoc_STRVAR(os_getpriority__doc__,
5012"getpriority($module, /, which, who)\n"
5013"--\n"
5014"\n"
5015"Return program scheduling priority.");
5016
5017#define OS_GETPRIORITY_METHODDEF \
5018 {"getpriority", (PyCFunction)os_getpriority, METH_VARARGS|METH_KEYWORDS, os_getpriority__doc__},
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005019
5020static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005021os_getpriority_impl(PyModuleDef *module, int which, int who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005022
Larry Hastings2f936352014-08-05 14:04:04 +10005023static PyObject *
5024os_getpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5025{
5026 PyObject *return_value = NULL;
5027 static char *_keywords[] = {"which", "who", NULL};
5028 int which;
5029 int who;
5030
5031 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5032 "ii:getpriority", _keywords,
5033 &which, &who))
5034 goto exit;
5035 return_value = os_getpriority_impl(module, which, who);
5036
5037exit:
5038 return return_value;
5039}
5040
5041static PyObject *
5042os_getpriority_impl(PyModuleDef *module, int which, int who)
5043/*[clinic end generated code: output=81639cf765f05dae input=9be615d40e2544ef]*/
5044{
5045 int retval;
5046
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005047 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005048 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005049 if (errno != 0)
5050 return posix_error();
5051 return PyLong_FromLong((long)retval);
5052}
5053#endif /* HAVE_GETPRIORITY */
5054
5055
5056#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10005057/*[clinic input]
5058os.setpriority
5059
5060 which: int
5061 who: int
5062 priority: int
5063
5064Set program scheduling priority.
5065[clinic start generated code]*/
5066
5067PyDoc_STRVAR(os_setpriority__doc__,
5068"setpriority($module, /, which, who, priority)\n"
5069"--\n"
5070"\n"
5071"Set program scheduling priority.");
5072
5073#define OS_SETPRIORITY_METHODDEF \
5074 {"setpriority", (PyCFunction)os_setpriority, METH_VARARGS|METH_KEYWORDS, os_setpriority__doc__},
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005075
5076static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005077os_setpriority_impl(PyModuleDef *module, int which, int who, int priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005078
Larry Hastings2f936352014-08-05 14:04:04 +10005079static PyObject *
5080os_setpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5081{
5082 PyObject *return_value = NULL;
5083 static char *_keywords[] = {"which", "who", "priority", NULL};
5084 int which;
5085 int who;
5086 int priority;
5087
5088 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5089 "iii:setpriority", _keywords,
5090 &which, &who, &priority))
5091 goto exit;
5092 return_value = os_setpriority_impl(module, which, who, priority);
5093
5094exit:
5095 return return_value;
5096}
5097
5098static PyObject *
5099os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
5100/*[clinic end generated code: output=ddad62651fb2120c input=710ccbf65b9dc513]*/
5101{
5102 int retval;
5103
5104 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005105 if (retval == -1)
5106 return posix_error();
5107 Py_RETURN_NONE;
5108}
5109#endif /* HAVE_SETPRIORITY */
5110
5111
Barry Warsaw53699e91996-12-10 23:23:01 +00005112static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005113internal_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 +00005114{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005115 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005116 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005117
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005118#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005120 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005121#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005122 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005123#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124
Larry Hastings9cf065c2012-06-22 16:30:09 -07005125 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
5126 (dst_dir_fd != DEFAULT_DIR_FD);
5127#ifndef HAVE_RENAMEAT
5128 if (dir_fd_specified) {
5129 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10005130 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005131 }
5132#endif
5133
Larry Hastings2f936352014-08-05 14:04:04 +10005134 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005135 PyErr_Format(PyExc_ValueError,
5136 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10005137 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005138 }
5139
5140#ifdef MS_WINDOWS
5141 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005142 if (src->wide)
5143 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144 else
Larry Hastings2f936352014-08-05 14:04:04 +10005145 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005146 Py_END_ALLOW_THREADS
5147
Larry Hastings2f936352014-08-05 14:04:04 +10005148 if (!result)
5149 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150
5151#else
5152 Py_BEGIN_ALLOW_THREADS
5153#ifdef HAVE_RENAMEAT
5154 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10005155 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 else
5157#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005158 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005159 Py_END_ALLOW_THREADS
5160
Larry Hastings2f936352014-08-05 14:04:04 +10005161 if (result)
5162 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005164 Py_RETURN_NONE;
5165}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005166
Larry Hastings2f936352014-08-05 14:04:04 +10005167
5168/*[clinic input]
5169os.rename
5170
5171 src : path_t
5172 dst : path_t
5173 *
5174 src_dir_fd : dir_fd = None
5175 dst_dir_fd : dir_fd = None
5176
5177Rename a file or directory.
5178
5179If either src_dir_fd or dst_dir_fd is not None, it should be a file
5180 descriptor open to a directory, and the respective path string (src or dst)
5181 should be relative; the path will then be relative to that directory.
5182src_dir_fd and dst_dir_fd, may not be implemented on your platform.
5183 If they are unavailable, using them will raise a NotImplementedError.
5184[clinic start generated code]*/
5185
5186PyDoc_STRVAR(os_rename__doc__,
5187"rename($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n"
5188"--\n"
5189"\n"
5190"Rename a file or directory.\n"
5191"\n"
5192"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
5193" descriptor open to a directory, and the respective path string (src or dst)\n"
5194" should be relative; the path will then be relative to that directory.\n"
5195"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
5196" If they are unavailable, using them will raise a NotImplementedError.");
5197
5198#define OS_RENAME_METHODDEF \
5199 {"rename", (PyCFunction)os_rename, METH_VARARGS|METH_KEYWORDS, os_rename__doc__},
5200
5201static PyObject *
5202os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd);
5203
5204static PyObject *
5205os_rename(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5206{
5207 PyObject *return_value = NULL;
5208 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
5209 path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0);
5210 path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0);
5211 int src_dir_fd = DEFAULT_DIR_FD;
5212 int dst_dir_fd = DEFAULT_DIR_FD;
5213
5214 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5215 "O&O&|$O&O&:rename", _keywords,
5216 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd))
5217 goto exit;
5218 return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd);
5219
Larry Hastings9cf065c2012-06-22 16:30:09 -07005220exit:
Larry Hastings2f936352014-08-05 14:04:04 +10005221 /* Cleanup for src */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005222 path_cleanup(&src);
Larry Hastings2f936352014-08-05 14:04:04 +10005223 /* Cleanup for dst */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224 path_cleanup(&dst);
Larry Hastings2f936352014-08-05 14:04:04 +10005225
Larry Hastings9cf065c2012-06-22 16:30:09 -07005226 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005227}
5228
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005229static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005230os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
5231/*[clinic end generated code: output=c936bdc81f460a1e input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005232{
Larry Hastings2f936352014-08-05 14:04:04 +10005233 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005234}
5235
Larry Hastings2f936352014-08-05 14:04:04 +10005236
5237/*[clinic input]
5238os.replace = os.rename
5239
5240Rename a file or directory, overwriting the destination.
5241
5242If either src_dir_fd or dst_dir_fd is not None, it should be a file
5243 descriptor open to a directory, and the respective path string (src or dst)
5244 should be relative; the path will then be relative to that directory.
5245src_dir_fd and dst_dir_fd, may not be implemented on your platform.
5246 If they are unavailable, using them will raise a NotImplementedError."
5247[clinic start generated code]*/
5248
5249PyDoc_STRVAR(os_replace__doc__,
5250"replace($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n"
5251"--\n"
5252"\n"
5253"Rename a file or directory, overwriting the destination.\n"
5254"\n"
5255"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
5256" descriptor open to a directory, and the respective path string (src or dst)\n"
5257" should be relative; the path will then be relative to that directory.\n"
5258"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
5259" If they are unavailable, using them will raise a NotImplementedError.\"");
5260
5261#define OS_REPLACE_METHODDEF \
5262 {"replace", (PyCFunction)os_replace, METH_VARARGS|METH_KEYWORDS, os_replace__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005263
5264static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005265os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005266
Barry Warsaw53699e91996-12-10 23:23:01 +00005267static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005268os_replace(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005269{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005270 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005271 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
5272 path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0);
5273 path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0);
5274 int src_dir_fd = DEFAULT_DIR_FD;
5275 int dst_dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005276
Larry Hastings2f936352014-08-05 14:04:04 +10005277 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5278 "O&O&|$O&O&:replace", _keywords,
5279 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd))
5280 goto exit;
5281 return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd);
5282
5283exit:
5284 /* Cleanup for src */
5285 path_cleanup(&src);
5286 /* Cleanup for dst */
5287 path_cleanup(&dst);
5288
5289 return return_value;
5290}
5291
5292static PyObject *
5293os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
5294/*[clinic end generated code: output=224e4710d290d171 input=25515dfb107c8421]*/
5295{
5296 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
5297}
5298
5299
5300/*[clinic input]
5301os.rmdir
5302
5303 path: path_t
5304 *
5305 dir_fd: dir_fd(requires='unlinkat') = None
5306
5307Remove a directory.
5308
5309If dir_fd is not None, it should be a file descriptor open to a directory,
5310 and path should be relative; path will then be relative to that directory.
5311dir_fd may not be implemented on your platform.
5312 If it is unavailable, using it will raise a NotImplementedError.
5313[clinic start generated code]*/
5314
5315PyDoc_STRVAR(os_rmdir__doc__,
5316"rmdir($module, /, path, *, dir_fd=None)\n"
5317"--\n"
5318"\n"
5319"Remove a directory.\n"
5320"\n"
5321"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5322" and path should be relative; path will then be relative to that directory.\n"
5323"dir_fd may not be implemented on your platform.\n"
5324" If it is unavailable, using it will raise a NotImplementedError.");
5325
5326#define OS_RMDIR_METHODDEF \
5327 {"rmdir", (PyCFunction)os_rmdir, METH_VARARGS|METH_KEYWORDS, os_rmdir__doc__},
5328
5329static PyObject *
5330os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd);
5331
5332static PyObject *
5333os_rmdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5334{
5335 PyObject *return_value = NULL;
5336 static char *_keywords[] = {"path", "dir_fd", NULL};
5337 path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0);
5338 int dir_fd = DEFAULT_DIR_FD;
5339
5340 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5341 "O&|$O&:rmdir", _keywords,
5342 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5343 goto exit;
5344 return_value = os_rmdir_impl(module, &path, dir_fd);
5345
5346exit:
5347 /* Cleanup for path */
5348 path_cleanup(&path);
5349
5350 return return_value;
5351}
5352
5353static PyObject *
5354os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
5355/*[clinic end generated code: output=70b9fdbe3bee0591 input=38c8b375ca34a7e2]*/
5356{
5357 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005358
5359 Py_BEGIN_ALLOW_THREADS
5360#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10005361 if (path->wide)
5362 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005363 else
Larry Hastings2f936352014-08-05 14:04:04 +10005364 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005365 result = !result; /* Windows, success=1, UNIX, success=0 */
5366#else
5367#ifdef HAVE_UNLINKAT
5368 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10005369 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005370 else
5371#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005372 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005373#endif
5374 Py_END_ALLOW_THREADS
5375
Larry Hastings2f936352014-08-05 14:04:04 +10005376 if (result)
5377 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005378
Larry Hastings2f936352014-08-05 14:04:04 +10005379 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005380}
5381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005382
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005383#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10005384#ifdef MS_WINDOWS
5385/*[clinic input]
5386os.system -> long
5387
5388 command: Py_UNICODE
5389
5390Execute the command in a subshell.
5391[clinic start generated code]*/
5392
5393PyDoc_STRVAR(os_system__doc__,
5394"system($module, /, command)\n"
5395"--\n"
5396"\n"
5397"Execute the command in a subshell.");
5398
5399#define OS_SYSTEM_METHODDEF \
5400 {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__},
5401
5402static long
5403os_system_impl(PyModuleDef *module, Py_UNICODE *command);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Barry Warsaw53699e91996-12-10 23:23:01 +00005405static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005406os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005407{
Larry Hastings2f936352014-08-05 14:04:04 +10005408 PyObject *return_value = NULL;
5409 static char *_keywords[] = {"command", NULL};
5410 Py_UNICODE *command;
5411 long _return_value;
Victor Stinnercfa72782010-04-16 11:45:13 +00005412
Larry Hastings2f936352014-08-05 14:04:04 +10005413 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5414 "u:system", _keywords,
5415 &command))
5416 goto exit;
5417 _return_value = os_system_impl(module, command);
5418 if ((_return_value == -1) && PyErr_Occurred())
5419 goto exit;
5420 return_value = PyLong_FromLong(_return_value);
Victor Stinnercfa72782010-04-16 11:45:13 +00005421
Larry Hastings2f936352014-08-05 14:04:04 +10005422exit:
5423 return return_value;
5424}
5425
5426static long
5427os_system_impl(PyModuleDef *module, Py_UNICODE *command)
5428/*[clinic end generated code: output=29fe699c0b2e9d38 input=303f5ce97df606b0]*/
5429{
5430 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005432 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005434 return result;
5435}
5436#else /* MS_WINDOWS */
5437/*[clinic input]
5438os.system -> long
5439
5440 command: FSConverter
5441
5442Execute the command in a subshell.
5443[clinic start generated code]*/
5444
5445PyDoc_STRVAR(os_system__doc__,
5446"system($module, /, command)\n"
5447"--\n"
5448"\n"
5449"Execute the command in a subshell.");
5450
5451#define OS_SYSTEM_METHODDEF \
5452 {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__},
5453
5454static long
5455os_system_impl(PyModuleDef *module, PyObject *command);
5456
5457static PyObject *
5458os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5459{
5460 PyObject *return_value = NULL;
5461 static char *_keywords[] = {"command", NULL};
5462 PyObject *command = NULL;
5463 long _return_value;
5464
5465 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5466 "O&:system", _keywords,
5467 PyUnicode_FSConverter, &command))
5468 goto exit;
5469 _return_value = os_system_impl(module, command);
5470 if ((_return_value == -1) && PyErr_Occurred())
5471 goto exit;
5472 return_value = PyLong_FromLong(_return_value);
5473
5474exit:
5475 /* Cleanup for command */
5476 Py_XDECREF(command);
5477
5478 return return_value;
5479}
5480
5481static long
5482os_system_impl(PyModuleDef *module, PyObject *command)
5483/*[clinic end generated code: output=5be9f3c40ead3bad input=86a58554ba6094af]*/
5484{
5485 long result;
5486 char *bytes = PyBytes_AsString(command);
5487 Py_BEGIN_ALLOW_THREADS
5488 result = system(bytes);
5489 Py_END_ALLOW_THREADS
5490 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005491}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005492#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005493#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005495
Larry Hastings2f936352014-08-05 14:04:04 +10005496/*[clinic input]
5497os.umask
5498
5499 mask: int
5500 /
5501
5502Set the current numeric umask and return the previous umask.
5503[clinic start generated code]*/
5504
5505PyDoc_STRVAR(os_umask__doc__,
5506"umask($module, mask, /)\n"
5507"--\n"
5508"\n"
5509"Set the current numeric umask and return the previous umask.");
5510
5511#define OS_UMASK_METHODDEF \
5512 {"umask", (PyCFunction)os_umask, METH_VARARGS, os_umask__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005513
Barry Warsaw53699e91996-12-10 23:23:01 +00005514static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005515os_umask_impl(PyModuleDef *module, int mask);
5516
5517static PyObject *
5518os_umask(PyModuleDef *module, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005519{
Larry Hastings2f936352014-08-05 14:04:04 +10005520 PyObject *return_value = NULL;
5521 int mask;
5522
5523 if (!PyArg_ParseTuple(args,
5524 "i:umask",
5525 &mask))
5526 goto exit;
5527 return_value = os_umask_impl(module, mask);
5528
5529exit:
5530 return return_value;
5531}
5532
5533static PyObject *
5534os_umask_impl(PyModuleDef *module, int mask)
5535/*[clinic end generated code: output=90048b39d2d4a961 input=ab6bfd9b24d8a7e8]*/
5536{
5537 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 if (i < 0)
5539 return posix_error();
5540 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005541}
5542
Brian Curtind40e6f72010-07-08 21:39:08 +00005543#ifdef MS_WINDOWS
5544
5545/* override the default DeleteFileW behavior so that directory
5546symlinks can be removed with this function, the same as with
5547Unix symlinks */
5548BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
5549{
5550 WIN32_FILE_ATTRIBUTE_DATA info;
5551 WIN32_FIND_DATAW find_data;
5552 HANDLE find_data_handle;
5553 int is_directory = 0;
5554 int is_link = 0;
5555
5556 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
5557 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005558
Brian Curtind40e6f72010-07-08 21:39:08 +00005559 /* Get WIN32_FIND_DATA structure for the path to determine if
5560 it is a symlink */
5561 if(is_directory &&
5562 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
5563 find_data_handle = FindFirstFileW(lpFileName, &find_data);
5564
5565 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01005566 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
5567 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
5568 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
5569 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00005570 FindClose(find_data_handle);
5571 }
5572 }
5573 }
5574
5575 if (is_directory && is_link)
5576 return RemoveDirectoryW(lpFileName);
5577
5578 return DeleteFileW(lpFileName);
5579}
5580#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005582
Larry Hastings2f936352014-08-05 14:04:04 +10005583/*[clinic input]
5584os.unlink
5585
5586 path: path_t
5587 *
5588 dir_fd: dir_fd(requires='unlinkat')=None
5589
5590Remove a file (same as remove()).
5591
5592If dir_fd is not None, it should be a file descriptor open to a directory,
5593 and path should be relative; path will then be relative to that directory.
5594dir_fd may not be implemented on your platform.
5595 If it is unavailable, using it will raise a NotImplementedError.
5596
5597[clinic start generated code]*/
5598
5599PyDoc_STRVAR(os_unlink__doc__,
5600"unlink($module, /, path, *, dir_fd=None)\n"
5601"--\n"
5602"\n"
5603"Remove a file (same as remove()).\n"
5604"\n"
5605"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5606" and path should be relative; path will then be relative to that directory.\n"
5607"dir_fd may not be implemented on your platform.\n"
5608" If it is unavailable, using it will raise a NotImplementedError.");
5609
5610#define OS_UNLINK_METHODDEF \
5611 {"unlink", (PyCFunction)os_unlink, METH_VARARGS|METH_KEYWORDS, os_unlink__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005612
Barry Warsaw53699e91996-12-10 23:23:01 +00005613static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005614os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005615
Larry Hastings2f936352014-08-05 14:04:04 +10005616static PyObject *
5617os_unlink(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5618{
5619 PyObject *return_value = NULL;
5620 static char *_keywords[] = {"path", "dir_fd", NULL};
5621 path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0);
5622 int dir_fd = DEFAULT_DIR_FD;
5623
5624 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5625 "O&|$O&:unlink", _keywords,
5626 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5627 goto exit;
5628 return_value = os_unlink_impl(module, &path, dir_fd);
5629
5630exit:
5631 /* Cleanup for path */
5632 path_cleanup(&path);
5633
5634 return return_value;
5635}
5636
5637static PyObject *
5638os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
5639/*[clinic end generated code: output=59a6e66d67ff2e75 input=d7bcde2b1b2a2552]*/
5640{
5641 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005642
5643 Py_BEGIN_ALLOW_THREADS
5644#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10005645 if (path->wide)
5646 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005647 else
Larry Hastings2f936352014-08-05 14:04:04 +10005648 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005649 result = !result; /* Windows, success=1, UNIX, success=0 */
5650#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005651#ifdef HAVE_UNLINKAT
5652 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10005653 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005654 else
5655#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10005656 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005657#endif
5658 Py_END_ALLOW_THREADS
5659
Larry Hastings2f936352014-08-05 14:04:04 +10005660 if (result)
5661 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005662
Larry Hastings2f936352014-08-05 14:04:04 +10005663 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005664}
5665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Larry Hastings2f936352014-08-05 14:04:04 +10005667/*[clinic input]
5668os.remove = os.unlink
5669
5670Remove a file (same as unlink()).
5671
5672If dir_fd is not None, it should be a file descriptor open to a directory,
5673 and path should be relative; path will then be relative to that directory.
5674dir_fd may not be implemented on your platform.
5675 If it is unavailable, using it will raise a NotImplementedError.
5676[clinic start generated code]*/
5677
5678PyDoc_STRVAR(os_remove__doc__,
5679"remove($module, /, path, *, dir_fd=None)\n"
5680"--\n"
5681"\n"
5682"Remove a file (same as unlink()).\n"
5683"\n"
5684"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5685" and path should be relative; path will then be relative to that directory.\n"
5686"dir_fd may not be implemented on your platform.\n"
5687" If it is unavailable, using it will raise a NotImplementedError.");
5688
5689#define OS_REMOVE_METHODDEF \
5690 {"remove", (PyCFunction)os_remove, METH_VARARGS|METH_KEYWORDS, os_remove__doc__},
5691
5692static PyObject *
5693os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd);
5694
5695static PyObject *
5696os_remove(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5697{
5698 PyObject *return_value = NULL;
5699 static char *_keywords[] = {"path", "dir_fd", NULL};
5700 path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0);
5701 int dir_fd = DEFAULT_DIR_FD;
5702
5703 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5704 "O&|$O&:remove", _keywords,
5705 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5706 goto exit;
5707 return_value = os_remove_impl(module, &path, dir_fd);
5708
5709exit:
5710 /* Cleanup for path */
5711 path_cleanup(&path);
5712
5713 return return_value;
5714}
5715
5716static PyObject *
5717os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
5718/*[clinic end generated code: output=cb170cf1e195b8ed input=e05c5ab55cd30983]*/
5719{
5720 return os_unlink_impl(module, path, dir_fd);
5721}
5722
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005723
Larry Hastings605a62d2012-06-24 04:33:36 -07005724static PyStructSequence_Field uname_result_fields[] = {
5725 {"sysname", "operating system name"},
5726 {"nodename", "name of machine on network (implementation-defined)"},
5727 {"release", "operating system release"},
5728 {"version", "operating system version"},
5729 {"machine", "hardware identifier"},
5730 {NULL}
5731};
5732
5733PyDoc_STRVAR(uname_result__doc__,
5734"uname_result: Result from os.uname().\n\n\
5735This object may be accessed either as a tuple of\n\
5736 (sysname, nodename, release, version, machine),\n\
5737or via the attributes sysname, nodename, release, version, and machine.\n\
5738\n\
5739See os.uname for more information.");
5740
5741static PyStructSequence_Desc uname_result_desc = {
5742 "uname_result", /* name */
5743 uname_result__doc__, /* doc */
5744 uname_result_fields,
5745 5
5746};
5747
5748static PyTypeObject UnameResultType;
5749
5750
5751#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10005752/*[clinic input]
5753os.uname
5754
5755Return an object identifying the current operating system.
5756
5757The object behaves like a named tuple with the following fields:
5758 (sysname, nodename, release, version, machine)
5759
5760[clinic start generated code]*/
5761
5762PyDoc_STRVAR(os_uname__doc__,
5763"uname($module, /)\n"
5764"--\n"
5765"\n"
5766"Return an object identifying the current operating system.\n"
5767"\n"
5768"The object behaves like a named tuple with the following fields:\n"
5769" (sysname, nodename, release, version, machine)");
5770
5771#define OS_UNAME_METHODDEF \
5772 {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__},
5773
Barry Warsaw53699e91996-12-10 23:23:01 +00005774static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005775os_uname_impl(PyModuleDef *module);
5776
5777static PyObject *
5778os_uname(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
5779{
5780 return os_uname_impl(module);
5781}
5782
5783static PyObject *
5784os_uname_impl(PyModuleDef *module)
5785/*[clinic end generated code: output=459a86521ff5041c input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005786{
Victor Stinner8c62be82010-05-06 00:08:46 +00005787 struct utsname u;
5788 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07005789 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00005790
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 Py_BEGIN_ALLOW_THREADS
5792 res = uname(&u);
5793 Py_END_ALLOW_THREADS
5794 if (res < 0)
5795 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005796
5797 value = PyStructSequence_New(&UnameResultType);
5798 if (value == NULL)
5799 return NULL;
5800
5801#define SET(i, field) \
5802 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005803 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005804 if (!o) { \
5805 Py_DECREF(value); \
5806 return NULL; \
5807 } \
5808 PyStructSequence_SET_ITEM(value, i, o); \
5809 } \
5810
5811 SET(0, u.sysname);
5812 SET(1, u.nodename);
5813 SET(2, u.release);
5814 SET(3, u.version);
5815 SET(4, u.machine);
5816
5817#undef SET
5818
5819 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005820}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005821#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005822
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005823
Larry Hastings9cf065c2012-06-22 16:30:09 -07005824
5825typedef struct {
5826 int now;
5827 time_t atime_s;
5828 long atime_ns;
5829 time_t mtime_s;
5830 long mtime_ns;
5831} utime_t;
5832
5833/*
Victor Stinner484df002014-10-09 13:52:31 +02005834 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005835 * they also intentionally leak the declaration of a pointer named "time"
5836 */
5837#define UTIME_TO_TIMESPEC \
5838 struct timespec ts[2]; \
5839 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005840 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005841 time = NULL; \
5842 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005843 ts[0].tv_sec = ut->atime_s; \
5844 ts[0].tv_nsec = ut->atime_ns; \
5845 ts[1].tv_sec = ut->mtime_s; \
5846 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005847 time = ts; \
5848 } \
5849
5850#define UTIME_TO_TIMEVAL \
5851 struct timeval tv[2]; \
5852 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005853 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005854 time = NULL; \
5855 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005856 tv[0].tv_sec = ut->atime_s; \
5857 tv[0].tv_usec = ut->atime_ns / 1000; \
5858 tv[1].tv_sec = ut->mtime_s; \
5859 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005860 time = tv; \
5861 } \
5862
5863#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005864 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005865 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005866 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005867 time = NULL; \
5868 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005869 u.actime = ut->atime_s; \
5870 u.modtime = ut->mtime_s; \
5871 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005872 }
5873
5874#define UTIME_TO_TIME_T \
5875 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005876 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005877 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005878 time = NULL; \
5879 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005880 timet[0] = ut->atime_s; \
5881 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005882 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005883 } \
5884
5885
5886#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
5887
5888#if UTIME_HAVE_DIR_FD
5889
5890static int
Victor Stinner484df002014-10-09 13:52:31 +02005891utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005892{
5893#ifdef HAVE_UTIMENSAT
5894 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5895 UTIME_TO_TIMESPEC;
5896 return utimensat(dir_fd, path, time, flags);
5897#elif defined(HAVE_FUTIMESAT)
5898 UTIME_TO_TIMEVAL;
5899 /*
5900 * follow_symlinks will never be false here;
5901 * we only allow !follow_symlinks and dir_fd together
5902 * if we have utimensat()
5903 */
5904 assert(follow_symlinks);
5905 return futimesat(dir_fd, path, time);
5906#endif
5907}
5908
Larry Hastings2f936352014-08-05 14:04:04 +10005909 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5910#else
5911 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005912#endif
5913
5914#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
5915
5916#if UTIME_HAVE_FD
5917
5918static int
Victor Stinner484df002014-10-09 13:52:31 +02005919utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005920{
5921#ifdef HAVE_FUTIMENS
5922 UTIME_TO_TIMESPEC;
5923 return futimens(fd, time);
5924#else
5925 UTIME_TO_TIMEVAL;
5926 return futimes(fd, time);
5927#endif
5928}
5929
Larry Hastings2f936352014-08-05 14:04:04 +10005930 #define PATH_UTIME_HAVE_FD 1
5931#else
5932 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005933#endif
5934
5935
5936#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
5937 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
5938
5939#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5940
5941static int
Victor Stinner484df002014-10-09 13:52:31 +02005942utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005943{
5944#ifdef HAVE_UTIMENSAT
5945 UTIME_TO_TIMESPEC;
5946 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5947#else
5948 UTIME_TO_TIMEVAL;
5949 return lutimes(path, time);
5950#endif
5951}
5952
5953#endif
5954
5955#ifndef MS_WINDOWS
5956
5957static int
Victor Stinner484df002014-10-09 13:52:31 +02005958utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005959{
5960#ifdef HAVE_UTIMENSAT
5961 UTIME_TO_TIMESPEC;
5962 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5963#elif defined(HAVE_UTIMES)
5964 UTIME_TO_TIMEVAL;
5965 return utimes(path, time);
5966#elif defined(HAVE_UTIME_H)
5967 UTIME_TO_UTIMBUF;
5968 return utime(path, time);
5969#else
5970 UTIME_TO_TIME_T;
5971 return utime(path, time);
5972#endif
5973}
5974
5975#endif
5976
Larry Hastings76ad59b2012-05-03 00:30:07 -07005977static int
5978split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
5979{
5980 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005981 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005982 divmod = PyNumber_Divmod(py_long, billion);
5983 if (!divmod)
5984 goto exit;
5985 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5986 if ((*s == -1) && PyErr_Occurred())
5987 goto exit;
5988 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005989 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005990 goto exit;
5991
5992 result = 1;
5993exit:
5994 Py_XDECREF(divmod);
5995 return result;
5996}
5997
Larry Hastings2f936352014-08-05 14:04:04 +10005998
5999/*[clinic input]
6000os.utime
6001
6002 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
6003 times: object = NULL
6004 *
6005 ns: object = NULL
6006 dir_fd: dir_fd(requires='futimensat') = None
6007 follow_symlinks: bool=True
6008
6009# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
6010
6011Set the access and modified time of path.
6012
6013path may always be specified as a string.
6014On some platforms, path may also be specified as an open file descriptor.
6015 If this functionality is unavailable, using it raises an exception.
6016
6017If times is not None, it must be a tuple (atime, mtime);
6018 atime and mtime should be expressed as float seconds since the epoch.
6019If ns is not None, it must be a tuple (atime_ns, mtime_ns);
6020 atime_ns and mtime_ns should be expressed as integer nanoseconds
6021 since the epoch.
6022If both times and ns are None, utime uses the current time.
6023Specifying tuples for both times and ns is an error.
6024
6025If dir_fd is not None, it should be a file descriptor open to a directory,
6026 and path should be relative; path will then be relative to that directory.
6027If follow_symlinks is False, and the last element of the path is a symbolic
6028 link, utime will modify the symbolic link itself instead of the file the
6029 link points to.
6030It is an error to use dir_fd or follow_symlinks when specifying path
6031 as an open file descriptor.
6032dir_fd and follow_symlinks may not be available on your platform.
6033 If they are unavailable, using them will raise a NotImplementedError.
6034
6035[clinic start generated code]*/
6036
6037PyDoc_STRVAR(os_utime__doc__,
6038"utime($module, /, path, times=None, *, ns=None, dir_fd=None,\n"
6039" follow_symlinks=True)\n"
6040"--\n"
6041"\n"
6042"Set the access and modified time of path.\n"
6043"\n"
6044"path may always be specified as a string.\n"
6045"On some platforms, path may also be specified as an open file descriptor.\n"
6046" If this functionality is unavailable, using it raises an exception.\n"
6047"\n"
6048"If times is not None, it must be a tuple (atime, mtime);\n"
6049" atime and mtime should be expressed as float seconds since the epoch.\n"
6050"If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n"
6051" atime_ns and mtime_ns should be expressed as integer nanoseconds\n"
6052" since the epoch.\n"
6053"If both times and ns are None, utime uses the current time.\n"
6054"Specifying tuples for both times and ns is an error.\n"
6055"\n"
6056"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
6057" and path should be relative; path will then be relative to that directory.\n"
6058"If follow_symlinks is False, and the last element of the path is a symbolic\n"
6059" link, utime will modify the symbolic link itself instead of the file the\n"
6060" link points to.\n"
6061"It is an error to use dir_fd or follow_symlinks when specifying path\n"
6062" as an open file descriptor.\n"
6063"dir_fd and follow_symlinks may not be available on your platform.\n"
6064" If they are unavailable, using them will raise a NotImplementedError.");
6065
6066#define OS_UTIME_METHODDEF \
6067 {"utime", (PyCFunction)os_utime, METH_VARARGS|METH_KEYWORDS, os_utime__doc__},
6068
Larry Hastings9cf065c2012-06-22 16:30:09 -07006069static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006070os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks);
6071
6072static PyObject *
6073os_utime(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07006074{
Larry Hastings2f936352014-08-05 14:04:04 +10006075 PyObject *return_value = NULL;
6076 static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL};
6077 path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD);
Larry Hastings76ad59b2012-05-03 00:30:07 -07006078 PyObject *times = NULL;
6079 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006080 int dir_fd = DEFAULT_DIR_FD;
6081 int follow_symlinks = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006082
Larry Hastings2f936352014-08-05 14:04:04 +10006083 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6084 "O&|O$OO&p:utime", _keywords,
6085 path_converter, &path, &times, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
6086 goto exit;
6087 return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks);
Larry Hastings76ad59b2012-05-03 00:30:07 -07006088
Larry Hastings2f936352014-08-05 14:04:04 +10006089exit:
6090 /* Cleanup for path */
6091 path_cleanup(&path);
6092
6093 return return_value;
6094}
6095
6096static PyObject *
6097os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks)
6098/*[clinic end generated code: output=891489c35cc68c5d input=1f18c17d5941aa82]*/
6099{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006100#ifdef MS_WINDOWS
6101 HANDLE hFile;
6102 FILETIME atime, mtime;
6103#else
6104 int result;
6105#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07006106
Larry Hastings9cf065c2012-06-22 16:30:09 -07006107 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006108 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006109
Christian Heimesb3c87242013-08-01 00:08:16 +02006110 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07006111
Larry Hastings9cf065c2012-06-22 16:30:09 -07006112 if (times && (times != Py_None) && ns) {
6113 PyErr_SetString(PyExc_ValueError,
6114 "utime: you may specify either 'times'"
6115 " or 'ns' but not both");
6116 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006117 }
6118
6119 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02006120 time_t a_sec, m_sec;
6121 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006122 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006123 PyErr_SetString(PyExc_TypeError,
6124 "utime: 'times' must be either"
6125 " a tuple of two ints or None");
6126 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006127 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006128 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006129 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01006130 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006131 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01006132 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006133 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006134 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02006135 utime.atime_s = a_sec;
6136 utime.atime_ns = a_nsec;
6137 utime.mtime_s = m_sec;
6138 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006139 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006140 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07006141 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006142 PyErr_SetString(PyExc_TypeError,
6143 "utime: 'ns' must be a tuple of two ints");
6144 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006145 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006146 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006147 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07006148 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006149 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07006150 &utime.mtime_s, &utime.mtime_ns)) {
6151 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006152 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006153 }
6154 else {
6155 /* times and ns are both None/unspecified. use "now". */
6156 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006157 }
6158
Larry Hastings9cf065c2012-06-22 16:30:09 -07006159#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
6160 if (follow_symlinks_specified("utime", follow_symlinks))
6161 goto exit;
6162#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006163
Larry Hastings2f936352014-08-05 14:04:04 +10006164 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
6165 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
6166 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07006167 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006168
Larry Hastings9cf065c2012-06-22 16:30:09 -07006169#if !defined(HAVE_UTIMENSAT)
6170 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02006171 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006172 "utime: cannot use dir_fd and follow_symlinks "
6173 "together on this platform");
6174 goto exit;
6175 }
6176#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07006177
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006178#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006179 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10006180 if (path->wide)
6181 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 NULL, OPEN_EXISTING,
6183 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006184 else
Larry Hastings2f936352014-08-05 14:04:04 +10006185 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 NULL, OPEN_EXISTING,
6187 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006188 Py_END_ALLOW_THREADS
6189 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10006190 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006191 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006192 }
6193
Larry Hastings9cf065c2012-06-22 16:30:09 -07006194 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01006195 GetSystemTimeAsFileTime(&mtime);
6196 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08006199 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
6200 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 }
6202 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
6203 /* Avoid putting the file name into the error here,
6204 as that may confuse the user into believing that
6205 something is wrong with the file, when it also
6206 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01006207 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006208 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006210#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07006211 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00006212
Larry Hastings9cf065c2012-06-22 16:30:09 -07006213#if UTIME_HAVE_NOFOLLOW_SYMLINKS
6214 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10006215 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006216 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07006217#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07006218
6219#if UTIME_HAVE_DIR_FD
6220 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10006221 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006222 else
6223#endif
6224
6225#if UTIME_HAVE_FD
Larry Hastings2f936352014-08-05 14:04:04 +10006226 if (path->fd != -1)
6227 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006228 else
6229#endif
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006232
6233 Py_END_ALLOW_THREADS
6234
6235 if (result < 0) {
6236 /* see previous comment about not putting filename in error here */
6237 return_value = posix_error();
6238 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07006240
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006241#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07006242
6243 Py_INCREF(Py_None);
6244 return_value = Py_None;
6245
6246exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07006247#ifdef MS_WINDOWS
6248 if (hFile != INVALID_HANDLE_VALUE)
6249 CloseHandle(hFile);
6250#endif
6251 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006252}
6253
Guido van Rossum3b066191991-06-04 19:40:25 +00006254/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006255
Larry Hastings2f936352014-08-05 14:04:04 +10006256
6257/*[clinic input]
6258os._exit
6259
6260 status: int
6261
6262Exit to the system with specified status, without normal exit processing.
6263[clinic start generated code]*/
6264
6265PyDoc_STRVAR(os__exit__doc__,
6266"_exit($module, /, status)\n"
6267"--\n"
6268"\n"
6269"Exit to the system with specified status, without normal exit processing.");
6270
6271#define OS__EXIT_METHODDEF \
6272 {"_exit", (PyCFunction)os__exit, METH_VARARGS|METH_KEYWORDS, os__exit__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006273
Barry Warsaw53699e91996-12-10 23:23:01 +00006274static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006275os__exit_impl(PyModuleDef *module, int status);
6276
6277static PyObject *
6278os__exit(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006279{
Larry Hastings2f936352014-08-05 14:04:04 +10006280 PyObject *return_value = NULL;
6281 static char *_keywords[] = {"status", NULL};
6282 int status;
6283
6284 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6285 "i:_exit", _keywords,
6286 &status))
6287 goto exit;
6288 return_value = os__exit_impl(module, status);
6289
6290exit:
6291 return return_value;
6292}
6293
6294static PyObject *
6295os__exit_impl(PyModuleDef *module, int status)
6296/*[clinic end generated code: output=4f9858c4cc2dcb89 input=5e6d57556b0c4a62]*/
6297{
6298 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006300}
6301
Martin v. Löwis114619e2002-10-07 06:44:21 +00006302#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
6303static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00006304free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00006305{
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 Py_ssize_t i;
6307 for (i = 0; i < count; i++)
6308 PyMem_Free(array[i]);
6309 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006310}
Martin v. Löwis011e8422009-05-05 04:43:17 +00006311
Antoine Pitrou69f71142009-05-24 21:25:49 +00006312static
Martin v. Löwis011e8422009-05-05 04:43:17 +00006313int fsconvert_strdup(PyObject *o, char**out)
6314{
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 PyObject *bytes;
6316 Py_ssize_t size;
6317 if (!PyUnicode_FSConverter(o, &bytes))
6318 return 0;
6319 size = PyBytes_GET_SIZE(bytes);
6320 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01006321 if (!*out) {
6322 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01006324 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 memcpy(*out, PyBytes_AsString(bytes), size+1);
6326 Py_DECREF(bytes);
6327 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006328}
Martin v. Löwis114619e2002-10-07 06:44:21 +00006329#endif
6330
Ross Lagerwall7807c352011-03-17 20:20:30 +02006331#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00006332static char**
6333parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
6334{
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 char **envlist;
6336 Py_ssize_t i, pos, envc;
6337 PyObject *keys=NULL, *vals=NULL;
6338 PyObject *key, *val, *key2, *val2;
6339 char *p, *k, *v;
6340 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006341
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 i = PyMapping_Size(env);
6343 if (i < 0)
6344 return NULL;
6345 envlist = PyMem_NEW(char *, i + 1);
6346 if (envlist == NULL) {
6347 PyErr_NoMemory();
6348 return NULL;
6349 }
6350 envc = 0;
6351 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01006352 if (!keys)
6353 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01006355 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 goto error;
6357 if (!PyList_Check(keys) || !PyList_Check(vals)) {
6358 PyErr_Format(PyExc_TypeError,
6359 "env.keys() or env.values() is not a list");
6360 goto error;
6361 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00006362
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 for (pos = 0; pos < i; pos++) {
6364 key = PyList_GetItem(keys, pos);
6365 val = PyList_GetItem(vals, pos);
6366 if (!key || !val)
6367 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006368
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 if (PyUnicode_FSConverter(key, &key2) == 0)
6370 goto error;
6371 if (PyUnicode_FSConverter(val, &val2) == 0) {
6372 Py_DECREF(key2);
6373 goto error;
6374 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00006375
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 k = PyBytes_AsString(key2);
6377 v = PyBytes_AsString(val2);
6378 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006379
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 p = PyMem_NEW(char, len);
6381 if (p == NULL) {
6382 PyErr_NoMemory();
6383 Py_DECREF(key2);
6384 Py_DECREF(val2);
6385 goto error;
6386 }
6387 PyOS_snprintf(p, len, "%s=%s", k, v);
6388 envlist[envc++] = p;
6389 Py_DECREF(key2);
6390 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 }
6392 Py_DECREF(vals);
6393 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00006394
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 envlist[envc] = 0;
6396 *envc_ptr = envc;
6397 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006398
6399error:
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 Py_XDECREF(keys);
6401 Py_XDECREF(vals);
6402 while (--envc >= 0)
6403 PyMem_DEL(envlist[envc]);
6404 PyMem_DEL(envlist);
6405 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006406}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006407
Ross Lagerwall7807c352011-03-17 20:20:30 +02006408static char**
6409parse_arglist(PyObject* argv, Py_ssize_t *argc)
6410{
6411 int i;
6412 char **argvlist = PyMem_NEW(char *, *argc+1);
6413 if (argvlist == NULL) {
6414 PyErr_NoMemory();
6415 return NULL;
6416 }
6417 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006418 PyObject* item = PySequence_ITEM(argv, i);
6419 if (item == NULL)
6420 goto fail;
6421 if (!fsconvert_strdup(item, &argvlist[i])) {
6422 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006423 goto fail;
6424 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006425 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006426 }
6427 argvlist[*argc] = NULL;
6428 return argvlist;
6429fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006430 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006431 free_string_array(argvlist, *argc);
6432 return NULL;
6433}
6434#endif
6435
Larry Hastings2f936352014-08-05 14:04:04 +10006436
Ross Lagerwall7807c352011-03-17 20:20:30 +02006437#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10006438/*[clinic input]
6439os.execv
6440
6441 path: FSConverter
6442 Path of executable file.
6443 argv: object
6444 Tuple or list of strings.
6445 /
6446
6447Execute an executable path with arguments, replacing current process.
6448[clinic start generated code]*/
6449
6450PyDoc_STRVAR(os_execv__doc__,
6451"execv($module, path, argv, /)\n"
6452"--\n"
6453"\n"
6454"Execute an executable path with arguments, replacing current process.\n"
6455"\n"
6456" path\n"
6457" Path of executable file.\n"
6458" argv\n"
6459" Tuple or list of strings.");
6460
6461#define OS_EXECV_METHODDEF \
6462 {"execv", (PyCFunction)os_execv, METH_VARARGS, os_execv__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02006463
6464static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006465os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv);
6466
6467static PyObject *
6468os_execv(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +02006469{
Larry Hastings2f936352014-08-05 14:04:04 +10006470 PyObject *return_value = NULL;
6471 PyObject *path = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006472 PyObject *argv;
Larry Hastings2f936352014-08-05 14:04:04 +10006473
6474 if (!PyArg_ParseTuple(args,
6475 "O&O:execv",
6476 PyUnicode_FSConverter, &path, &argv))
6477 goto exit;
6478 return_value = os_execv_impl(module, path, argv);
6479
6480exit:
6481 /* Cleanup for path */
6482 Py_XDECREF(path);
6483
6484 return return_value;
6485}
6486
6487static PyObject *
6488os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
6489/*[clinic end generated code: output=b0f5f2caa6097edc input=96041559925e5229]*/
6490{
6491 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006492 char **argvlist;
6493 Py_ssize_t argc;
6494
6495 /* execv has two arguments: (path, argv), where
6496 argv is a list or tuple of strings. */
6497
Larry Hastings2f936352014-08-05 14:04:04 +10006498 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006499 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
6500 PyErr_SetString(PyExc_TypeError,
6501 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02006502 return NULL;
6503 }
6504 argc = PySequence_Size(argv);
6505 if (argc < 1) {
6506 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02006507 return NULL;
6508 }
6509
6510 argvlist = parse_arglist(argv, &argc);
6511 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02006512 return NULL;
6513 }
6514
Larry Hastings2f936352014-08-05 14:04:04 +10006515 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006516
6517 /* If we get here it's definitely an error */
6518
6519 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006520 return posix_error();
6521}
6522
Larry Hastings2f936352014-08-05 14:04:04 +10006523
6524/*[clinic input]
6525os.execve
6526
6527 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
6528 Path of executable file.
6529 argv: object
6530 Tuple or list of strings.
6531 env: object
6532 Dictionary of strings mapping to strings.
6533
6534Execute an executable path with arguments, replacing current process.
6535[clinic start generated code]*/
6536
6537PyDoc_STRVAR(os_execve__doc__,
6538"execve($module, /, path, argv, env)\n"
6539"--\n"
6540"\n"
6541"Execute an executable path with arguments, replacing current process.\n"
6542"\n"
6543" path\n"
6544" Path of executable file.\n"
6545" argv\n"
6546" Tuple or list of strings.\n"
6547" env\n"
6548" Dictionary of strings mapping to strings.");
6549
6550#define OS_EXECVE_METHODDEF \
6551 {"execve", (PyCFunction)os_execve, METH_VARARGS|METH_KEYWORDS, os_execve__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006552
Barry Warsaw53699e91996-12-10 23:23:01 +00006553static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006554os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env);
6555
6556static PyObject *
6557os_execve(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006558{
Larry Hastings2f936352014-08-05 14:04:04 +10006559 PyObject *return_value = NULL;
6560 static char *_keywords[] = {"path", "argv", "env", NULL};
6561 path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE);
6562 PyObject *argv;
6563 PyObject *env;
6564
6565 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6566 "O&OO:execve", _keywords,
6567 path_converter, &path, &argv, &env))
6568 goto exit;
6569 return_value = os_execve_impl(module, &path, argv, env);
6570
6571exit:
6572 /* Cleanup for path */
6573 path_cleanup(&path);
6574
6575 return return_value;
6576}
6577
6578static PyObject *
6579os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env)
6580/*[clinic end generated code: output=fb283760f5d15ab7 input=626804fa092606d9]*/
6581{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006582 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006584 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006585
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 /* execve has three arguments: (path, argv, env), where
6587 argv is a list or tuple of strings and env is a dictionary
6588 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006589
Ross Lagerwall7807c352011-03-17 20:20:30 +02006590 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006592 "execve: argv must be a tuple or list");
6593 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02006595 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 if (!PyMapping_Check(env)) {
6597 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006598 "execve: environment must be a mapping object");
6599 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006601
Ross Lagerwall7807c352011-03-17 20:20:30 +02006602 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006604 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006606
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 envlist = parse_envlist(env, &envc);
6608 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02006609 goto fail;
6610
Larry Hastings9cf065c2012-06-22 16:30:09 -07006611#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10006612 if (path->fd > -1)
6613 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006614 else
6615#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006616 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006617
6618 /* If we get here it's definitely an error */
6619
Larry Hastings2f936352014-08-05 14:04:04 +10006620 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006621
6622 while (--envc >= 0)
6623 PyMem_DEL(envlist[envc]);
6624 PyMem_DEL(envlist);
6625 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07006626 if (argvlist)
6627 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006628 return NULL;
6629}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006630#endif /* HAVE_EXECV */
6631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006632
Guido van Rossuma1065681999-01-25 23:20:23 +00006633#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.spawnv
6636
6637 mode: int
6638 Mode of process creation.
6639 path: FSConverter
6640 Path of executable file.
6641 argv: object
6642 Tuple or list of strings.
6643 /
6644
6645Execute the program specified by path in a new process.
6646[clinic start generated code]*/
6647
6648PyDoc_STRVAR(os_spawnv__doc__,
6649"spawnv($module, mode, path, argv, /)\n"
6650"--\n"
6651"\n"
6652"Execute the program specified by path in a new process.\n"
6653"\n"
6654" mode\n"
6655" Mode of process creation.\n"
6656" path\n"
6657" Path of executable file.\n"
6658" argv\n"
6659" Tuple or list of strings.");
6660
6661#define OS_SPAWNV_METHODDEF \
6662 {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006663
6664static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006665os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv);
6666
6667static PyObject *
6668os_spawnv(PyModuleDef *module, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00006669{
Larry Hastings2f936352014-08-05 14:04:04 +10006670 PyObject *return_value = NULL;
6671 int mode;
6672 PyObject *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 PyObject *argv;
Larry Hastings2f936352014-08-05 14:04:04 +10006674
6675 if (!PyArg_ParseTuple(args,
6676 "iO&O:spawnv",
6677 &mode, PyUnicode_FSConverter, &path, &argv))
6678 goto exit;
6679 return_value = os_spawnv_impl(module, mode, path, argv);
6680
6681exit:
6682 /* Cleanup for path */
6683 Py_XDECREF(path);
6684
6685 return return_value;
6686}
6687
6688static PyObject *
6689os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
6690/*[clinic end generated code: output=dfee6be062e780e3 input=042c91dfc1e6debc]*/
6691{
6692 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006694 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 Py_ssize_t argc;
6696 Py_intptr_t spawnval;
6697 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006698
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 /* spawnv has three arguments: (mode, path, argv), where
6700 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006701
Larry Hastings2f936352014-08-05 14:04:04 +10006702 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 if (PyList_Check(argv)) {
6704 argc = PyList_Size(argv);
6705 getitem = PyList_GetItem;
6706 }
6707 else if (PyTuple_Check(argv)) {
6708 argc = PyTuple_Size(argv);
6709 getitem = PyTuple_GetItem;
6710 }
6711 else {
6712 PyErr_SetString(PyExc_TypeError,
6713 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 return NULL;
6715 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006716
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 argvlist = PyMem_NEW(char *, argc+1);
6718 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 return PyErr_NoMemory();
6720 }
6721 for (i = 0; i < argc; i++) {
6722 if (!fsconvert_strdup((*getitem)(argv, i),
6723 &argvlist[i])) {
6724 free_string_array(argvlist, i);
6725 PyErr_SetString(
6726 PyExc_TypeError,
6727 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 return NULL;
6729 }
6730 }
6731 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006732
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 if (mode == _OLD_P_OVERLAY)
6734 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00006735
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10006737 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006739
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006741
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 if (spawnval == -1)
6743 return posix_error();
6744 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006745 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006746}
6747
6748
Larry Hastings2f936352014-08-05 14:04:04 +10006749/*[clinic input]
6750os.spawnve
6751
6752 mode: int
6753 Mode of process creation.
6754 path: FSConverter
6755 Path of executable file.
6756 argv: object
6757 Tuple or list of strings.
6758 env: object
6759 Dictionary of strings mapping to strings.
6760 /
6761
6762Execute the program specified by path in a new process.
6763[clinic start generated code]*/
6764
6765PyDoc_STRVAR(os_spawnve__doc__,
6766"spawnve($module, mode, path, argv, env, /)\n"
6767"--\n"
6768"\n"
6769"Execute the program specified by path in a new process.\n"
6770"\n"
6771" mode\n"
6772" Mode of process creation.\n"
6773" path\n"
6774" Path of executable file.\n"
6775" argv\n"
6776" Tuple or list of strings.\n"
6777" env\n"
6778" Dictionary of strings mapping to strings.");
6779
6780#define OS_SPAWNVE_METHODDEF \
6781 {"spawnve", (PyCFunction)os_spawnve, METH_VARARGS, os_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006782
6783static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006784os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env);
6785
6786static PyObject *
6787os_spawnve(PyModuleDef *module, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00006788{
Larry Hastings2f936352014-08-05 14:04:04 +10006789 PyObject *return_value = NULL;
6790 int mode;
6791 PyObject *path = NULL;
6792 PyObject *argv;
6793 PyObject *env;
6794
6795 if (!PyArg_ParseTuple(args,
6796 "iO&OO:spawnve",
6797 &mode, PyUnicode_FSConverter, &path, &argv, &env))
6798 goto exit;
6799 return_value = os_spawnve_impl(module, mode, path, argv, env);
6800
6801exit:
6802 /* Cleanup for path */
6803 Py_XDECREF(path);
6804
6805 return return_value;
6806}
6807
6808static PyObject *
6809os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env)
6810/*[clinic end generated code: output=6f7df38473f63c7c input=02362fd937963f8f]*/
6811{
6812 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 char **argvlist;
6814 char **envlist;
6815 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006816 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 Py_intptr_t spawnval;
6818 PyObject *(*getitem)(PyObject *, Py_ssize_t);
6819 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 /* spawnve has four arguments: (mode, path, argv, env), where
6822 argv is a list or tuple of strings and env is a dictionary
6823 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006824
Larry Hastings2f936352014-08-05 14:04:04 +10006825 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (PyList_Check(argv)) {
6827 argc = PyList_Size(argv);
6828 getitem = PyList_GetItem;
6829 }
6830 else if (PyTuple_Check(argv)) {
6831 argc = PyTuple_Size(argv);
6832 getitem = PyTuple_GetItem;
6833 }
6834 else {
6835 PyErr_SetString(PyExc_TypeError,
6836 "spawnve() arg 2 must be a tuple or list");
6837 goto fail_0;
6838 }
6839 if (!PyMapping_Check(env)) {
6840 PyErr_SetString(PyExc_TypeError,
6841 "spawnve() arg 3 must be a mapping object");
6842 goto fail_0;
6843 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 argvlist = PyMem_NEW(char *, argc+1);
6846 if (argvlist == NULL) {
6847 PyErr_NoMemory();
6848 goto fail_0;
6849 }
6850 for (i = 0; i < argc; i++) {
6851 if (!fsconvert_strdup((*getitem)(argv, i),
6852 &argvlist[i]))
6853 {
6854 lastarg = i;
6855 goto fail_1;
6856 }
6857 }
6858 lastarg = argc;
6859 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006860
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 envlist = parse_envlist(env, &envc);
6862 if (envlist == NULL)
6863 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006864
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 if (mode == _OLD_P_OVERLAY)
6866 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00006867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10006869 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006871
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 if (spawnval == -1)
6873 (void) posix_error();
6874 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006875 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 while (--envc >= 0)
6878 PyMem_DEL(envlist[envc]);
6879 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006880 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006882 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006884}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006885
Guido van Rossuma1065681999-01-25 23:20:23 +00006886#endif /* HAVE_SPAWNV */
6887
6888
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006889#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006890/*[clinic input]
6891os.fork1
6892
6893Fork a child process with a single multiplexed (i.e., not bound) thread.
6894
6895Return 0 to child process and PID of child to parent process.
6896[clinic start generated code]*/
6897
6898PyDoc_STRVAR(os_fork1__doc__,
6899"fork1($module, /)\n"
6900"--\n"
6901"\n"
6902"Fork a child process with a single multiplexed (i.e., not bound) thread.\n"
6903"\n"
6904"Return 0 to child process and PID of child to parent process.");
6905
6906#define OS_FORK1_METHODDEF \
6907 {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006908
6909static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006910os_fork1_impl(PyModuleDef *module);
6911
6912static PyObject *
6913os_fork1(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
6914{
6915 return os_fork1_impl(module);
6916}
6917
6918static PyObject *
6919os_fork1_impl(PyModuleDef *module)
6920/*[clinic end generated code: output=fa04088d6bc02efa input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006921{
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 pid_t pid;
6923 int result = 0;
6924 _PyImport_AcquireLock();
6925 pid = fork1();
6926 if (pid == 0) {
6927 /* child: this clobbers and resets the import lock. */
6928 PyOS_AfterFork();
6929 } else {
6930 /* parent: release the import lock. */
6931 result = _PyImport_ReleaseLock();
6932 }
6933 if (pid == -1)
6934 return posix_error();
6935 if (result < 0) {
6936 /* Don't clobber the OSError if the fork failed. */
6937 PyErr_SetString(PyExc_RuntimeError,
6938 "not holding the import lock");
6939 return NULL;
6940 }
6941 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006942}
Larry Hastings2f936352014-08-05 14:04:04 +10006943#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006944
6945
Guido van Rossumad0ee831995-03-01 10:34:45 +00006946#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006947/*[clinic input]
6948os.fork
6949
6950Fork a child process.
6951
6952Return 0 to child process and PID of child to parent process.
6953[clinic start generated code]*/
6954
6955PyDoc_STRVAR(os_fork__doc__,
6956"fork($module, /)\n"
6957"--\n"
6958"\n"
6959"Fork a child process.\n"
6960"\n"
6961"Return 0 to child process and PID of child to parent process.");
6962
6963#define OS_FORK_METHODDEF \
6964 {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006965
Barry Warsaw53699e91996-12-10 23:23:01 +00006966static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006967os_fork_impl(PyModuleDef *module);
6968
6969static PyObject *
6970os_fork(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
6971{
6972 return os_fork_impl(module);
6973}
6974
6975static PyObject *
6976os_fork_impl(PyModuleDef *module)
6977/*[clinic end generated code: output=b3c8e6bdc11eedc6 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006978{
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 pid_t pid;
6980 int result = 0;
6981 _PyImport_AcquireLock();
6982 pid = fork();
6983 if (pid == 0) {
6984 /* child: this clobbers and resets the import lock. */
6985 PyOS_AfterFork();
6986 } else {
6987 /* parent: release the import lock. */
6988 result = _PyImport_ReleaseLock();
6989 }
6990 if (pid == -1)
6991 return posix_error();
6992 if (result < 0) {
6993 /* Don't clobber the OSError if the fork failed. */
6994 PyErr_SetString(PyExc_RuntimeError,
6995 "not holding the import lock");
6996 return NULL;
6997 }
6998 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006999}
Larry Hastings2f936352014-08-05 14:04:04 +10007000#endif /* HAVE_FORK */
7001
Guido van Rossum85e3b011991-06-03 12:42:10 +00007002
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007003#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007004#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10007005/*[clinic input]
7006os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007007
Larry Hastings2f936352014-08-05 14:04:04 +10007008 policy: int
7009
7010Get the maximum scheduling priority for policy.
7011[clinic start generated code]*/
7012
7013PyDoc_STRVAR(os_sched_get_priority_max__doc__,
7014"sched_get_priority_max($module, /, policy)\n"
7015"--\n"
7016"\n"
7017"Get the maximum scheduling priority for policy.");
7018
7019#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \
7020 {"sched_get_priority_max", (PyCFunction)os_sched_get_priority_max, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_max__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007021
7022static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007023os_sched_get_priority_max_impl(PyModuleDef *module, int policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007024
Larry Hastings2f936352014-08-05 14:04:04 +10007025static PyObject *
7026os_sched_get_priority_max(PyModuleDef *module, PyObject *args, PyObject *kwargs)
7027{
7028 PyObject *return_value = NULL;
7029 static char *_keywords[] = {"policy", NULL};
7030 int policy;
7031
7032 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7033 "i:sched_get_priority_max", _keywords,
7034 &policy))
7035 goto exit;
7036 return_value = os_sched_get_priority_max_impl(module, policy);
7037
7038exit:
7039 return return_value;
7040}
7041
7042static PyObject *
7043os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
7044/*[clinic end generated code: output=a580a52f25238c1f input=2097b7998eca6874]*/
7045{
7046 int max;
7047
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007048 max = sched_get_priority_max(policy);
7049 if (max < 0)
7050 return posix_error();
7051 return PyLong_FromLong(max);
7052}
7053
Larry Hastings2f936352014-08-05 14:04:04 +10007054
7055/*[clinic input]
7056os.sched_get_priority_min
7057
7058 policy: int
7059
7060Get the minimum scheduling priority for policy.
7061[clinic start generated code]*/
7062
7063PyDoc_STRVAR(os_sched_get_priority_min__doc__,
7064"sched_get_priority_min($module, /, policy)\n"
7065"--\n"
7066"\n"
7067"Get the minimum scheduling priority for policy.");
7068
7069#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \
7070 {"sched_get_priority_min", (PyCFunction)os_sched_get_priority_min, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_min__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007071
7072static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007073os_sched_get_priority_min_impl(PyModuleDef *module, int policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007074
Larry Hastings2f936352014-08-05 14:04:04 +10007075static PyObject *
7076os_sched_get_priority_min(PyModuleDef *module, PyObject *args, PyObject *kwargs)
7077{
7078 PyObject *return_value = NULL;
7079 static char *_keywords[] = {"policy", NULL};
7080 int policy;
7081
7082 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7083 "i:sched_get_priority_min", _keywords,
7084 &policy))
7085 goto exit;
7086 return_value = os_sched_get_priority_min_impl(module, policy);
7087
7088exit:
7089 return return_value;
7090}
7091
7092static PyObject *
7093os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
7094/*[clinic end generated code: output=bad8ba10e7d0e977 input=21bc8fa0d70983bf]*/
7095{
7096 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007097 if (min < 0)
7098 return posix_error();
7099 return PyLong_FromLong(min);
7100}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007101#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
7102
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007103
Larry Hastings2f936352014-08-05 14:04:04 +10007104#ifdef HAVE_SCHED_SETSCHEDULER
7105/*[clinic input]
7106os.sched_getscheduler
7107 pid: pid_t
7108 /
7109
7110Get the scheduling policy for the process identifiedy by pid.
7111
7112Passing 0 for pid returns the scheduling policy for the calling process.
7113[clinic start generated code]*/
7114
7115PyDoc_STRVAR(os_sched_getscheduler__doc__,
7116"sched_getscheduler($module, pid, /)\n"
7117"--\n"
7118"\n"
7119"Get the scheduling policy for the process identifiedy by pid.\n"
7120"\n"
7121"Passing 0 for pid returns the scheduling policy for the calling process.");
7122
7123#define OS_SCHED_GETSCHEDULER_METHODDEF \
7124 {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_VARARGS, os_sched_getscheduler__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007125
7126static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007127os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid);
7128
7129static PyObject *
7130os_sched_getscheduler(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007131{
Larry Hastings2f936352014-08-05 14:04:04 +10007132 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007133 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007134
7135 if (!PyArg_ParseTuple(args,
7136 "" _Py_PARSE_PID ":sched_getscheduler",
7137 &pid))
7138 goto exit;
7139 return_value = os_sched_getscheduler_impl(module, pid);
7140
7141exit:
7142 return return_value;
7143}
7144
7145static PyObject *
7146os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
7147/*[clinic end generated code: output=e0d6244207b1d828 input=5f14cfd1f189e1a0]*/
7148{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007149 int policy;
7150
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007151 policy = sched_getscheduler(pid);
7152 if (policy < 0)
7153 return posix_error();
7154 return PyLong_FromLong(policy);
7155}
Larry Hastings2f936352014-08-05 14:04:04 +10007156#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007157
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007158
7159#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10007160/*[clinic input]
7161class os.sched_param "PyObject *" "&SchedParamType"
7162
7163@classmethod
7164os.sched_param.__new__
7165
7166 sched_priority: object
7167 A scheduling parameter.
7168
7169Current has only one field: sched_priority");
7170[clinic start generated code]*/
7171
7172PyDoc_STRVAR(os_sched_param__doc__,
7173"sched_param(sched_priority)\n"
7174"--\n"
7175"\n"
7176"Current has only one field: sched_priority\");\n"
7177"\n"
7178" sched_priority\n"
7179" A scheduling parameter.");
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007180
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007181static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007182os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007183
Larry Hastings2f936352014-08-05 14:04:04 +10007184static PyObject *
7185os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs)
7186{
7187 PyObject *return_value = NULL;
7188 static char *_keywords[] = {"sched_priority", NULL};
7189 PyObject *sched_priority;
7190
7191 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7192 "O:sched_param", _keywords,
7193 &sched_priority))
7194 goto exit;
7195 return_value = os_sched_param_impl(type, sched_priority);
7196
7197exit:
7198 return return_value;
7199}
7200
7201static PyObject *
7202os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
7203/*[clinic end generated code: output=d3791e345f7fe573 input=73a4c22f7071fc62]*/
7204{
7205 PyObject *res;
7206
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007207 res = PyStructSequence_New(type);
7208 if (!res)
7209 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007210 Py_INCREF(sched_priority);
7211 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007212 return res;
7213}
7214
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007215
7216static PyStructSequence_Field sched_param_fields[] = {
7217 {"sched_priority", "the scheduling priority"},
7218 {0}
7219};
7220
7221static PyStructSequence_Desc sched_param_desc = {
7222 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10007223 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007224 sched_param_fields,
7225 1
7226};
7227
7228static int
7229convert_sched_param(PyObject *param, struct sched_param *res)
7230{
7231 long priority;
7232
7233 if (Py_TYPE(param) != &SchedParamType) {
7234 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
7235 return 0;
7236 }
7237 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
7238 if (priority == -1 && PyErr_Occurred())
7239 return 0;
7240 if (priority > INT_MAX || priority < INT_MIN) {
7241 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
7242 return 0;
7243 }
7244 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
7245 return 1;
7246}
Larry Hastings2f936352014-08-05 14:04:04 +10007247#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007248
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007249
7250#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10007251/*[clinic input]
7252os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007253
Larry Hastings2f936352014-08-05 14:04:04 +10007254 pid: pid_t
7255 policy: int
7256 param: sched_param
7257 /
7258
7259Set the scheduling policy for the process identified by pid.
7260
7261If pid is 0, the calling process is changed.
7262param is an instance of sched_param.
7263[clinic start generated code]*/
7264
7265PyDoc_STRVAR(os_sched_setscheduler__doc__,
7266"sched_setscheduler($module, pid, policy, param, /)\n"
7267"--\n"
7268"\n"
7269"Set the scheduling policy for the process identified by pid.\n"
7270"\n"
7271"If pid is 0, the calling process is changed.\n"
7272"param is an instance of sched_param.");
7273
7274#define OS_SCHED_SETSCHEDULER_METHODDEF \
7275 {"sched_setscheduler", (PyCFunction)os_sched_setscheduler, METH_VARARGS, os_sched_setscheduler__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007276
7277static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007278os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param);
7279
7280static PyObject *
7281os_sched_setscheduler(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007282{
Larry Hastings2f936352014-08-05 14:04:04 +10007283 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007284 pid_t pid;
7285 int policy;
7286 struct sched_param param;
7287
Larry Hastings2f936352014-08-05 14:04:04 +10007288 if (!PyArg_ParseTuple(args,
7289 "" _Py_PARSE_PID "iO&:sched_setscheduler",
7290 &pid, &policy, convert_sched_param, &param))
7291 goto exit;
7292 return_value = os_sched_setscheduler_impl(module, pid, policy, &param);
Jesus Cea9c822272011-09-10 01:40:52 +02007293
Larry Hastings2f936352014-08-05 14:04:04 +10007294exit:
7295 return return_value;
7296}
7297
7298static PyObject *
7299os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param)
7300/*[clinic end generated code: output=36abdb73f81c224f input=c581f9469a5327dd]*/
7301{
Jesus Cea9c822272011-09-10 01:40:52 +02007302 /*
Jesus Cea54b01492011-09-10 01:53:19 +02007303 ** sched_setscheduler() returns 0 in Linux, but the previous
7304 ** scheduling policy under Solaris/Illumos, and others.
7305 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02007306 */
Larry Hastings2f936352014-08-05 14:04:04 +10007307 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007308 return posix_error();
7309 Py_RETURN_NONE;
7310}
Larry Hastings2f936352014-08-05 14:04:04 +10007311#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007312
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007313
7314#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10007315/*[clinic input]
7316os.sched_getparam
7317 pid: pid_t
7318 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007319
Larry Hastings2f936352014-08-05 14:04:04 +10007320Returns scheduling parameters for the process identified by pid.
7321
7322If pid is 0, returns parameters for the calling process.
7323Return value is an instance of sched_param.
7324[clinic start generated code]*/
7325
7326PyDoc_STRVAR(os_sched_getparam__doc__,
7327"sched_getparam($module, pid, /)\n"
7328"--\n"
7329"\n"
7330"Returns scheduling parameters for the process identified by pid.\n"
7331"\n"
7332"If pid is 0, returns parameters for the calling process.\n"
7333"Return value is an instance of sched_param.");
7334
7335#define OS_SCHED_GETPARAM_METHODDEF \
7336 {"sched_getparam", (PyCFunction)os_sched_getparam, METH_VARARGS, os_sched_getparam__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007337
7338static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007339os_sched_getparam_impl(PyModuleDef *module, pid_t pid);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007340
Larry Hastings2f936352014-08-05 14:04:04 +10007341static PyObject *
7342os_sched_getparam(PyModuleDef *module, PyObject *args)
7343{
7344 PyObject *return_value = NULL;
7345 pid_t pid;
7346
7347 if (!PyArg_ParseTuple(args,
7348 "" _Py_PARSE_PID ":sched_getparam",
7349 &pid))
7350 goto exit;
7351 return_value = os_sched_getparam_impl(module, pid);
7352
7353exit:
7354 return return_value;
7355}
7356
7357static PyObject *
7358os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
7359/*[clinic end generated code: output=b33acc8db004a8c9 input=18a1ef9c2efae296]*/
7360{
7361 struct sched_param param;
7362 PyObject *result;
7363 PyObject *priority;
7364
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007365 if (sched_getparam(pid, &param))
7366 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007367 result = PyStructSequence_New(&SchedParamType);
7368 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007369 return NULL;
7370 priority = PyLong_FromLong(param.sched_priority);
7371 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10007372 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007373 return NULL;
7374 }
Larry Hastings2f936352014-08-05 14:04:04 +10007375 PyStructSequence_SET_ITEM(result, 0, priority);
7376 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007377}
7378
Larry Hastings2f936352014-08-05 14:04:04 +10007379
7380/*[clinic input]
7381os.sched_setparam
7382 pid: pid_t
7383 param: sched_param
7384 /
7385
7386Set scheduling parameters for the process identified by pid.
7387
7388If pid is 0, sets parameters for the calling process.
7389param should be an instance of sched_param.
7390[clinic start generated code]*/
7391
7392PyDoc_STRVAR(os_sched_setparam__doc__,
7393"sched_setparam($module, pid, param, /)\n"
7394"--\n"
7395"\n"
7396"Set scheduling parameters for the process identified by pid.\n"
7397"\n"
7398"If pid is 0, sets parameters for the calling process.\n"
7399"param should be an instance of sched_param.");
7400
7401#define OS_SCHED_SETPARAM_METHODDEF \
7402 {"sched_setparam", (PyCFunction)os_sched_setparam, METH_VARARGS, os_sched_setparam__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007403
7404static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007405os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param);
7406
7407static PyObject *
7408os_sched_setparam(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007409{
Larry Hastings2f936352014-08-05 14:04:04 +10007410 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007411 pid_t pid;
7412 struct sched_param param;
7413
Larry Hastings2f936352014-08-05 14:04:04 +10007414 if (!PyArg_ParseTuple(args,
7415 "" _Py_PARSE_PID "O&:sched_setparam",
7416 &pid, convert_sched_param, &param))
7417 goto exit;
7418 return_value = os_sched_setparam_impl(module, pid, &param);
7419
7420exit:
7421 return return_value;
7422}
7423
7424static PyObject *
7425os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param)
7426/*[clinic end generated code: output=488bdf5bcbe0d4e8 input=6b8d6dfcecdc21bd]*/
7427{
7428 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007429 return posix_error();
7430 Py_RETURN_NONE;
7431}
Larry Hastings2f936352014-08-05 14:04:04 +10007432#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007433
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007434
7435#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10007436/*[clinic input]
7437os.sched_rr_get_interval -> double
7438 pid: pid_t
7439 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007440
Larry Hastings2f936352014-08-05 14:04:04 +10007441Return the round-robin quantum for the process identified by pid, in seconds.
7442
7443Value returned is a float.
7444[clinic start generated code]*/
7445
7446PyDoc_STRVAR(os_sched_rr_get_interval__doc__,
7447"sched_rr_get_interval($module, pid, /)\n"
7448"--\n"
7449"\n"
7450"Return the round-robin quantum for the process identified by pid, in seconds.\n"
7451"\n"
7452"Value returned is a float.");
7453
7454#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \
7455 {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_VARARGS, os_sched_rr_get_interval__doc__},
7456
7457static double
7458os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007459
7460static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007461os_sched_rr_get_interval(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007462{
Larry Hastings2f936352014-08-05 14:04:04 +10007463 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007464 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007465 double _return_value;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007466
Larry Hastings2f936352014-08-05 14:04:04 +10007467 if (!PyArg_ParseTuple(args,
7468 "" _Py_PARSE_PID ":sched_rr_get_interval",
7469 &pid))
7470 goto exit;
7471 _return_value = os_sched_rr_get_interval_impl(module, pid);
7472 if ((_return_value == -1.0) && PyErr_Occurred())
7473 goto exit;
7474 return_value = PyFloat_FromDouble(_return_value);
7475
7476exit:
7477 return return_value;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007478}
7479
Larry Hastings2f936352014-08-05 14:04:04 +10007480static double
7481os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
7482/*[clinic end generated code: output=5b3b8d1f27fb2c0a input=2a973da15cca6fae]*/
7483{
7484 struct timespec interval;
7485 if (sched_rr_get_interval(pid, &interval)) {
7486 posix_error();
7487 return -1.0;
7488 }
7489 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
7490}
7491#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007492
Larry Hastings2f936352014-08-05 14:04:04 +10007493
7494/*[clinic input]
7495os.sched_yield
7496
7497Voluntarily relinquish the CPU.
7498[clinic start generated code]*/
7499
7500PyDoc_STRVAR(os_sched_yield__doc__,
7501"sched_yield($module, /)\n"
7502"--\n"
7503"\n"
7504"Voluntarily relinquish the CPU.");
7505
7506#define OS_SCHED_YIELD_METHODDEF \
7507 {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007508
7509static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007510os_sched_yield_impl(PyModuleDef *module);
7511
7512static PyObject *
7513os_sched_yield(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7514{
7515 return os_sched_yield_impl(module);
7516}
7517
7518static PyObject *
7519os_sched_yield_impl(PyModuleDef *module)
7520/*[clinic end generated code: output=9d2e5f29f1370324 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007521{
7522 if (sched_yield())
7523 return posix_error();
7524 Py_RETURN_NONE;
7525}
7526
Benjamin Peterson2740af82011-08-02 17:41:34 -05007527#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02007528/* The minimum number of CPUs allocated in a cpu_set_t */
7529static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007530
Larry Hastings2f936352014-08-05 14:04:04 +10007531/*[clinic input]
7532os.sched_setaffinity
7533 pid: pid_t
7534 mask : object
7535 /
7536
7537Set the CPU affinity of the process identified by pid to mask.
7538
7539mask should be an iterable of integers identifying CPUs.
7540[clinic start generated code]*/
7541
7542PyDoc_STRVAR(os_sched_setaffinity__doc__,
7543"sched_setaffinity($module, pid, mask, /)\n"
7544"--\n"
7545"\n"
7546"Set the CPU affinity of the process identified by pid to mask.\n"
7547"\n"
7548"mask should be an iterable of integers identifying CPUs.");
7549
7550#define OS_SCHED_SETAFFINITY_METHODDEF \
7551 {"sched_setaffinity", (PyCFunction)os_sched_setaffinity, METH_VARARGS, os_sched_setaffinity__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007552
7553static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007554os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask);
7555
7556static PyObject *
7557os_sched_setaffinity(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007558{
Larry Hastings2f936352014-08-05 14:04:04 +10007559 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007560 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007561 PyObject *mask;
7562
7563 if (!PyArg_ParseTuple(args,
7564 "" _Py_PARSE_PID "O:sched_setaffinity",
7565 &pid, &mask))
7566 goto exit;
7567 return_value = os_sched_setaffinity_impl(module, pid, mask);
7568
7569exit:
7570 return return_value;
7571}
7572
7573static PyObject *
7574os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
7575/*[clinic end generated code: output=5199929738130196 input=a0791a597c7085ba]*/
7576{
Antoine Pitrou84869872012-08-04 16:16:35 +02007577 int ncpus;
7578 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007579 cpu_set_t *cpu_set = NULL;
7580 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007581
Larry Hastings2f936352014-08-05 14:04:04 +10007582 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02007583 if (iterator == NULL)
7584 return NULL;
7585
7586 ncpus = NCPUS_START;
7587 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10007588 cpu_set = CPU_ALLOC(ncpus);
7589 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007590 PyErr_NoMemory();
7591 goto error;
7592 }
Larry Hastings2f936352014-08-05 14:04:04 +10007593 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007594
7595 while ((item = PyIter_Next(iterator))) {
7596 long cpu;
7597 if (!PyLong_Check(item)) {
7598 PyErr_Format(PyExc_TypeError,
7599 "expected an iterator of ints, "
7600 "but iterator yielded %R",
7601 Py_TYPE(item));
7602 Py_DECREF(item);
7603 goto error;
7604 }
7605 cpu = PyLong_AsLong(item);
7606 Py_DECREF(item);
7607 if (cpu < 0) {
7608 if (!PyErr_Occurred())
7609 PyErr_SetString(PyExc_ValueError, "negative CPU number");
7610 goto error;
7611 }
7612 if (cpu > INT_MAX - 1) {
7613 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7614 goto error;
7615 }
7616 if (cpu >= ncpus) {
7617 /* Grow CPU mask to fit the CPU number */
7618 int newncpus = ncpus;
7619 cpu_set_t *newmask;
7620 size_t newsetsize;
7621 while (newncpus <= cpu) {
7622 if (newncpus > INT_MAX / 2)
7623 newncpus = cpu + 1;
7624 else
7625 newncpus = newncpus * 2;
7626 }
7627 newmask = CPU_ALLOC(newncpus);
7628 if (newmask == NULL) {
7629 PyErr_NoMemory();
7630 goto error;
7631 }
7632 newsetsize = CPU_ALLOC_SIZE(newncpus);
7633 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007634 memcpy(newmask, cpu_set, setsize);
7635 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007636 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007637 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007638 ncpus = newncpus;
7639 }
Larry Hastings2f936352014-08-05 14:04:04 +10007640 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007641 }
7642 Py_CLEAR(iterator);
7643
Larry Hastings2f936352014-08-05 14:04:04 +10007644 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007645 posix_error();
7646 goto error;
7647 }
Larry Hastings2f936352014-08-05 14:04:04 +10007648 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007649 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007650
7651error:
Larry Hastings2f936352014-08-05 14:04:04 +10007652 if (cpu_set)
7653 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007654 Py_XDECREF(iterator);
7655 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007656}
7657
Larry Hastings2f936352014-08-05 14:04:04 +10007658
7659/*[clinic input]
7660os.sched_getaffinity
7661 pid: pid_t
7662 /
7663
7664Return the affinity of the process identified by pid.
7665
7666The affinity is returned as a set of CPU identifiers.
7667[clinic start generated code]*/
7668
7669PyDoc_STRVAR(os_sched_getaffinity__doc__,
7670"sched_getaffinity($module, pid, /)\n"
7671"--\n"
7672"\n"
7673"Return the affinity of the process identified by pid.\n"
7674"\n"
7675"The affinity is returned as a set of CPU identifiers.");
7676
7677#define OS_SCHED_GETAFFINITY_METHODDEF \
7678 {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_VARARGS, os_sched_getaffinity__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007679
7680static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007681os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid);
7682
7683static PyObject *
7684os_sched_getaffinity(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007685{
Larry Hastings2f936352014-08-05 14:04:04 +10007686 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007687 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007688
7689 if (!PyArg_ParseTuple(args,
7690 "" _Py_PARSE_PID ":sched_getaffinity",
7691 &pid))
7692 goto exit;
7693 return_value = os_sched_getaffinity_impl(module, pid);
7694
7695exit:
7696 return return_value;
7697}
7698
7699static PyObject *
7700os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
7701/*[clinic end generated code: output=7b273b0fca9830f0 input=eaf161936874b8a1]*/
7702{
Antoine Pitrou84869872012-08-04 16:16:35 +02007703 int cpu, ncpus, count;
7704 size_t setsize;
7705 cpu_set_t *mask = NULL;
7706 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007707
Antoine Pitrou84869872012-08-04 16:16:35 +02007708 ncpus = NCPUS_START;
7709 while (1) {
7710 setsize = CPU_ALLOC_SIZE(ncpus);
7711 mask = CPU_ALLOC(ncpus);
7712 if (mask == NULL)
7713 return PyErr_NoMemory();
7714 if (sched_getaffinity(pid, setsize, mask) == 0)
7715 break;
7716 CPU_FREE(mask);
7717 if (errno != EINVAL)
7718 return posix_error();
7719 if (ncpus > INT_MAX / 2) {
7720 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7721 "a large enough CPU set");
7722 return NULL;
7723 }
7724 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007725 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007726
7727 res = PySet_New(NULL);
7728 if (res == NULL)
7729 goto error;
7730 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7731 if (CPU_ISSET_S(cpu, setsize, mask)) {
7732 PyObject *cpu_num = PyLong_FromLong(cpu);
7733 --count;
7734 if (cpu_num == NULL)
7735 goto error;
7736 if (PySet_Add(res, cpu_num)) {
7737 Py_DECREF(cpu_num);
7738 goto error;
7739 }
7740 Py_DECREF(cpu_num);
7741 }
7742 }
7743 CPU_FREE(mask);
7744 return res;
7745
7746error:
7747 if (mask)
7748 CPU_FREE(mask);
7749 Py_XDECREF(res);
7750 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007751}
7752
Benjamin Peterson2740af82011-08-02 17:41:34 -05007753#endif /* HAVE_SCHED_SETAFFINITY */
7754
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007755#endif /* HAVE_SCHED_H */
7756
Larry Hastings2f936352014-08-05 14:04:04 +10007757#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF
7758#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF
7759#endif /* OS_SCHED_GET_PRIORITY_MAX_METHODDEF */
7760
7761#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF
7762#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF
7763#endif /* OS_SCHED_GET_PRIORITY_MIN_METHODDEF */
7764
7765#ifndef OS_SCHED_GETSCHEDULER_METHODDEF
7766#define OS_SCHED_GETSCHEDULER_METHODDEF
7767#endif /* OS_SCHED_GETSCHEDULER_METHODDEF */
7768
7769#ifndef OS_SCHED_SETSCHEDULER_METHODDEF
7770#define OS_SCHED_SETSCHEDULER_METHODDEF
7771#endif /* OS_SCHED_SETSCHEDULER_METHODDEF */
7772
7773#ifndef OS_SCHED_GETPARAM_METHODDEF
7774#define OS_SCHED_GETPARAM_METHODDEF
7775#endif /* OS_SCHED_GETPARAM_METHODDEF */
7776
7777#ifndef OS_SCHED_SETPARAM_METHODDEF
7778#define OS_SCHED_SETPARAM_METHODDEF
7779#endif /* OS_SCHED_SETPARAM_METHODDEF */
7780
7781#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF
7782#define OS_SCHED_RR_GET_INTERVAL_METHODDEF
7783#endif /* OS_SCHED_RR_GET_INTERVAL_METHODDEF */
7784
7785#ifndef OS_SCHED_YIELD_METHODDEF
7786#define OS_SCHED_YIELD_METHODDEF
7787#endif /* OS_SCHED_YIELD_METHODDEF */
7788
7789#ifndef OS_SCHED_SETAFFINITY_METHODDEF
7790#define OS_SCHED_SETAFFINITY_METHODDEF
7791#endif /* OS_SCHED_SETAFFINITY_METHODDEF */
7792
7793#ifndef OS_SCHED_GETAFFINITY_METHODDEF
7794#define OS_SCHED_GETAFFINITY_METHODDEF
7795#endif /* OS_SCHED_GETAFFINITY_METHODDEF */
7796
7797
Neal Norwitzb59798b2003-03-21 01:43:31 +00007798/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007799/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
7800#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00007801#define DEV_PTY_FILE "/dev/ptc"
7802#define HAVE_DEV_PTMX
7803#else
7804#define DEV_PTY_FILE "/dev/ptmx"
7805#endif
7806
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007807#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007808#ifdef HAVE_PTY_H
7809#include <pty.h>
7810#else
7811#ifdef HAVE_LIBUTIL_H
7812#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007813#else
7814#ifdef HAVE_UTIL_H
7815#include <util.h>
7816#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007817#endif /* HAVE_LIBUTIL_H */
7818#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007819#ifdef HAVE_STROPTS_H
7820#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007821#endif
7822#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007823
Larry Hastings2f936352014-08-05 14:04:04 +10007824
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007825#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007826/*[clinic input]
7827os.openpty
7828
7829Open a pseudo-terminal.
7830
7831Return a tuple of (master_fd, slave_fd) containing open file descriptors
7832for both the master and slave ends.
7833[clinic start generated code]*/
7834
7835PyDoc_STRVAR(os_openpty__doc__,
7836"openpty($module, /)\n"
7837"--\n"
7838"\n"
7839"Open a pseudo-terminal.\n"
7840"\n"
7841"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n"
7842"for both the master and slave ends.");
7843
7844#define OS_OPENPTY_METHODDEF \
7845 {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007846
7847static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007848os_openpty_impl(PyModuleDef *module);
7849
7850static PyObject *
7851os_openpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7852{
7853 return os_openpty_impl(module);
7854}
7855
7856static PyObject *
7857os_openpty_impl(PyModuleDef *module)
7858/*[clinic end generated code: output=b12d3c1735468464 input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007859{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007861#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007863#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007864#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007866#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007868#endif
7869#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007870
Thomas Wouters70c21a12000-07-14 14:28:33 +00007871#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007873 goto posix_error;
7874
7875 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7876 goto error;
7877 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7878 goto error;
7879
Neal Norwitzb59798b2003-03-21 01:43:31 +00007880#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7882 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007883 goto posix_error;
7884 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7885 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007886
Victor Stinnerdaf45552013-08-28 00:53:59 +02007887 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007889 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007890
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007891#else
Victor Stinner000de532013-11-25 23:19:58 +01007892 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007894 goto posix_error;
7895
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007897
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 /* change permission of slave */
7899 if (grantpt(master_fd) < 0) {
7900 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007901 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007903
Victor Stinner8c62be82010-05-06 00:08:46 +00007904 /* unlock slave */
7905 if (unlockpt(master_fd) < 0) {
7906 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007907 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007909
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007911
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 slave_name = ptsname(master_fd); /* get name of slave */
7913 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007914 goto posix_error;
7915
7916 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007917 if (slave_fd == -1)
7918 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007919
7920 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7921 goto posix_error;
7922
Neal Norwitzb59798b2003-03-21 01:43:31 +00007923#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7925 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007926#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007928#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007929#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007930#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007931
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007933
Victor Stinnerdaf45552013-08-28 00:53:59 +02007934posix_error:
7935 posix_error();
7936error:
7937 if (master_fd != -1)
7938 close(master_fd);
7939 if (slave_fd != -1)
7940 close(slave_fd);
7941 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007942}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007943#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007944
Larry Hastings2f936352014-08-05 14:04:04 +10007945
Fred Drake8cef4cf2000-06-28 16:40:38 +00007946#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007947/*[clinic input]
7948os.forkpty
7949
7950Fork a new process with a new pseudo-terminal as controlling tty.
7951
7952Returns a tuple of (pid, master_fd).
7953Like fork(), return pid of 0 to the child process,
7954and pid of child to the parent process.
7955To both, return fd of newly opened pseudo-terminal.
7956[clinic start generated code]*/
7957
7958PyDoc_STRVAR(os_forkpty__doc__,
7959"forkpty($module, /)\n"
7960"--\n"
7961"\n"
7962"Fork a new process with a new pseudo-terminal as controlling tty.\n"
7963"\n"
7964"Returns a tuple of (pid, master_fd).\n"
7965"Like fork(), return pid of 0 to the child process,\n"
7966"and pid of child to the parent process.\n"
7967"To both, return fd of newly opened pseudo-terminal.");
7968
7969#define OS_FORKPTY_METHODDEF \
7970 {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007971
7972static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007973os_forkpty_impl(PyModuleDef *module);
7974
7975static PyObject *
7976os_forkpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7977{
7978 return os_forkpty_impl(module);
7979}
7980
7981static PyObject *
7982os_forkpty_impl(PyModuleDef *module)
7983/*[clinic end generated code: output=d4f82958d2ed5cad input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007984{
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 int master_fd = -1, result = 0;
7986 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007987
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 _PyImport_AcquireLock();
7989 pid = forkpty(&master_fd, NULL, NULL, NULL);
7990 if (pid == 0) {
7991 /* child: this clobbers and resets the import lock. */
7992 PyOS_AfterFork();
7993 } else {
7994 /* parent: release the import lock. */
7995 result = _PyImport_ReleaseLock();
7996 }
7997 if (pid == -1)
7998 return posix_error();
7999 if (result < 0) {
8000 /* Don't clobber the OSError if the fork failed. */
8001 PyErr_SetString(PyExc_RuntimeError,
8002 "not holding the import lock");
8003 return NULL;
8004 }
8005 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00008006}
Larry Hastings2f936352014-08-05 14:04:04 +10008007#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008008
Ross Lagerwall7807c352011-03-17 20:20:30 +02008009
Guido van Rossumad0ee831995-03-01 10:34:45 +00008010#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10008011/*[clinic input]
8012os.getegid
8013
8014Return the current process's effective group id.
8015[clinic start generated code]*/
8016
8017PyDoc_STRVAR(os_getegid__doc__,
8018"getegid($module, /)\n"
8019"--\n"
8020"\n"
8021"Return the current process\'s effective group id.");
8022
8023#define OS_GETEGID_METHODDEF \
8024 {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008025
Barry Warsaw53699e91996-12-10 23:23:01 +00008026static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008027os_getegid_impl(PyModuleDef *module);
8028
8029static PyObject *
8030os_getegid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8031{
8032 return os_getegid_impl(module);
8033}
8034
8035static PyObject *
8036os_getegid_impl(PyModuleDef *module)
8037/*[clinic end generated code: output=fd12c346fa41cccb input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008038{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008039 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008040}
Larry Hastings2f936352014-08-05 14:04:04 +10008041#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008043
Guido van Rossumad0ee831995-03-01 10:34:45 +00008044#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008045/*[clinic input]
8046os.geteuid
8047
8048Return the current process's effective user id.
8049[clinic start generated code]*/
8050
8051PyDoc_STRVAR(os_geteuid__doc__,
8052"geteuid($module, /)\n"
8053"--\n"
8054"\n"
8055"Return the current process\'s effective user id.");
8056
8057#define OS_GETEUID_METHODDEF \
8058 {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008059
Barry Warsaw53699e91996-12-10 23:23:01 +00008060static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008061os_geteuid_impl(PyModuleDef *module);
8062
8063static PyObject *
8064os_geteuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8065{
8066 return os_geteuid_impl(module);
8067}
8068
8069static PyObject *
8070os_geteuid_impl(PyModuleDef *module)
8071/*[clinic end generated code: output=03d98e07f4bc03d4 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008072{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008073 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008074}
Larry Hastings2f936352014-08-05 14:04:04 +10008075#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008077
Guido van Rossumad0ee831995-03-01 10:34:45 +00008078#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008079/*[clinic input]
8080os.getgid
8081
8082Return the current process's group id.
8083[clinic start generated code]*/
8084
8085PyDoc_STRVAR(os_getgid__doc__,
8086"getgid($module, /)\n"
8087"--\n"
8088"\n"
8089"Return the current process\'s group id.");
8090
8091#define OS_GETGID_METHODDEF \
8092 {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008093
Barry Warsaw53699e91996-12-10 23:23:01 +00008094static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008095os_getgid_impl(PyModuleDef *module);
8096
8097static PyObject *
8098os_getgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8099{
8100 return os_getgid_impl(module);
8101}
8102
8103static PyObject *
8104os_getgid_impl(PyModuleDef *module)
8105/*[clinic end generated code: output=07b0356121b8098d input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008106{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008107 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008108}
Larry Hastings2f936352014-08-05 14:04:04 +10008109#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008111
Larry Hastings2f936352014-08-05 14:04:04 +10008112/*[clinic input]
8113os.getpid
8114
8115Return the current process id.
8116[clinic start generated code]*/
8117
8118PyDoc_STRVAR(os_getpid__doc__,
8119"getpid($module, /)\n"
8120"--\n"
8121"\n"
8122"Return the current process id.");
8123
8124#define OS_GETPID_METHODDEF \
8125 {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008126
Barry Warsaw53699e91996-12-10 23:23:01 +00008127static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008128os_getpid_impl(PyModuleDef *module);
8129
8130static PyObject *
8131os_getpid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8132{
8133 return os_getpid_impl(module);
8134}
8135
8136static PyObject *
8137os_getpid_impl(PyModuleDef *module)
8138/*[clinic end generated code: output=d63a01a3cebc573d input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00008139{
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00008141}
8142
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008143#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10008144
8145/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008146PyDoc_STRVAR(posix_getgrouplist__doc__,
8147"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
8148Returns a list of groups to which a user belongs.\n\n\
8149 user: username to lookup\n\
8150 group: base group id of the user");
8151
8152static PyObject *
8153posix_getgrouplist(PyObject *self, PyObject *args)
8154{
8155#ifdef NGROUPS_MAX
8156#define MAX_GROUPS NGROUPS_MAX
8157#else
8158 /* defined to be 16 on Solaris7, so this should be a small number */
8159#define MAX_GROUPS 64
8160#endif
8161
8162 const char *user;
8163 int i, ngroups;
8164 PyObject *list;
8165#ifdef __APPLE__
8166 int *groups, basegid;
8167#else
8168 gid_t *groups, basegid;
8169#endif
8170 ngroups = MAX_GROUPS;
8171
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008172#ifdef __APPLE__
8173 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008174 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008175#else
8176 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
8177 _Py_Gid_Converter, &basegid))
8178 return NULL;
8179#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008180
8181#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02008182 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008183#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02008184 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008185#endif
8186 if (groups == NULL)
8187 return PyErr_NoMemory();
8188
8189 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
8190 PyMem_Del(groups);
8191 return posix_error();
8192 }
8193
8194 list = PyList_New(ngroups);
8195 if (list == NULL) {
8196 PyMem_Del(groups);
8197 return NULL;
8198 }
8199
8200 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008201#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008202 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008203#else
8204 PyObject *o = _PyLong_FromGid(groups[i]);
8205#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008206 if (o == NULL) {
8207 Py_DECREF(list);
8208 PyMem_Del(groups);
8209 return NULL;
8210 }
8211 PyList_SET_ITEM(list, i, o);
8212 }
8213
8214 PyMem_Del(groups);
8215
8216 return list;
8217}
Larry Hastings2f936352014-08-05 14:04:04 +10008218#endif /* HAVE_GETGROUPLIST */
8219
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008220
Fred Drakec9680921999-12-13 16:37:25 +00008221#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008222/*[clinic input]
8223os.getgroups
8224
8225Return list of supplemental group IDs for the process.
8226[clinic start generated code]*/
8227
8228PyDoc_STRVAR(os_getgroups__doc__,
8229"getgroups($module, /)\n"
8230"--\n"
8231"\n"
8232"Return list of supplemental group IDs for the process.");
8233
8234#define OS_GETGROUPS_METHODDEF \
8235 {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008236
8237static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008238os_getgroups_impl(PyModuleDef *module);
8239
8240static PyObject *
8241os_getgroups(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8242{
8243 return os_getgroups_impl(module);
8244}
8245
8246static PyObject *
8247os_getgroups_impl(PyModuleDef *module)
8248/*[clinic end generated code: output=d9a3559b2e6f4ab8 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00008249{
8250 PyObject *result = NULL;
8251
Fred Drakec9680921999-12-13 16:37:25 +00008252#ifdef NGROUPS_MAX
8253#define MAX_GROUPS NGROUPS_MAX
8254#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00008256#define MAX_GROUPS 64
8257#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008259
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008260 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008261 * This is a helper variable to store the intermediate result when
8262 * that happens.
8263 *
8264 * To keep the code readable the OSX behaviour is unconditional,
8265 * according to the POSIX spec this should be safe on all unix-y
8266 * systems.
8267 */
8268 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 int n;
Fred Drakec9680921999-12-13 16:37:25 +00008270
Ned Deilyb5dd6d22013-08-01 21:21:15 -07008271#ifdef __APPLE__
8272 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
8273 * there are more groups than can fit in grouplist. Therefore, on OS X
8274 * always first call getgroups with length 0 to get the actual number
8275 * of groups.
8276 */
8277 n = getgroups(0, NULL);
8278 if (n < 0) {
8279 return posix_error();
8280 } else if (n <= MAX_GROUPS) {
8281 /* groups will fit in existing array */
8282 alt_grouplist = grouplist;
8283 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02008284 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07008285 if (alt_grouplist == NULL) {
8286 errno = EINVAL;
8287 return posix_error();
8288 }
8289 }
8290
8291 n = getgroups(n, alt_grouplist);
8292 if (n == -1) {
8293 if (alt_grouplist != grouplist) {
8294 PyMem_Free(alt_grouplist);
8295 }
8296 return posix_error();
8297 }
8298#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008300 if (n < 0) {
8301 if (errno == EINVAL) {
8302 n = getgroups(0, NULL);
8303 if (n == -1) {
8304 return posix_error();
8305 }
8306 if (n == 0) {
8307 /* Avoid malloc(0) */
8308 alt_grouplist = grouplist;
8309 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02008310 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008311 if (alt_grouplist == NULL) {
8312 errno = EINVAL;
8313 return posix_error();
8314 }
8315 n = getgroups(n, alt_grouplist);
8316 if (n == -1) {
8317 PyMem_Free(alt_grouplist);
8318 return posix_error();
8319 }
8320 }
8321 } else {
8322 return posix_error();
8323 }
8324 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07008325#endif
8326
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008327 result = PyList_New(n);
8328 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 int i;
8330 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008331 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008333 Py_DECREF(result);
8334 result = NULL;
8335 break;
Fred Drakec9680921999-12-13 16:37:25 +00008336 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00008338 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008339 }
8340
8341 if (alt_grouplist != grouplist) {
8342 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 }
Neal Norwitze241ce82003-02-17 18:17:05 +00008344
Fred Drakec9680921999-12-13 16:37:25 +00008345 return result;
8346}
Larry Hastings2f936352014-08-05 14:04:04 +10008347#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00008348
Antoine Pitroub7572f02009-12-02 20:46:48 +00008349#ifdef HAVE_INITGROUPS
8350PyDoc_STRVAR(posix_initgroups__doc__,
8351"initgroups(username, gid) -> None\n\n\
8352Call the system initgroups() to initialize the group access list with all of\n\
8353the groups of which the specified username is a member, plus the specified\n\
8354group id.");
8355
Larry Hastings2f936352014-08-05 14:04:04 +10008356/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00008357static PyObject *
8358posix_initgroups(PyObject *self, PyObject *args)
8359{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008360 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008362 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008363#ifdef __APPLE__
8364 int gid;
8365#else
8366 gid_t gid;
8367#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00008368
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008369#ifdef __APPLE__
8370 if (!PyArg_ParseTuple(args, "O&i:initgroups",
8371 PyUnicode_FSConverter, &oname,
8372 &gid))
8373#else
8374 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
8375 PyUnicode_FSConverter, &oname,
8376 _Py_Gid_Converter, &gid))
8377#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008379 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00008380
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008381 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008382 Py_DECREF(oname);
8383 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00008385
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 Py_INCREF(Py_None);
8387 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00008388}
Larry Hastings2f936352014-08-05 14:04:04 +10008389#endif /* HAVE_INITGROUPS */
8390
Antoine Pitroub7572f02009-12-02 20:46:48 +00008391
Martin v. Löwis606edc12002-06-13 21:09:11 +00008392#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008393/*[clinic input]
8394os.getpgid
8395
8396 pid: pid_t
8397
8398Call the system call getpgid(), and return the result.
8399[clinic start generated code]*/
8400
8401PyDoc_STRVAR(os_getpgid__doc__,
8402"getpgid($module, /, pid)\n"
8403"--\n"
8404"\n"
8405"Call the system call getpgid(), and return the result.");
8406
8407#define OS_GETPGID_METHODDEF \
8408 {"getpgid", (PyCFunction)os_getpgid, METH_VARARGS|METH_KEYWORDS, os_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008409
8410static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008411os_getpgid_impl(PyModuleDef *module, pid_t pid);
8412
8413static PyObject *
8414os_getpgid(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis606edc12002-06-13 21:09:11 +00008415{
Larry Hastings2f936352014-08-05 14:04:04 +10008416 PyObject *return_value = NULL;
8417 static char *_keywords[] = {"pid", NULL};
8418 pid_t pid;
8419
8420 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
8421 "" _Py_PARSE_PID ":getpgid", _keywords,
8422 &pid))
8423 goto exit;
8424 return_value = os_getpgid_impl(module, pid);
8425
8426exit:
8427 return return_value;
8428}
8429
8430static PyObject *
8431os_getpgid_impl(PyModuleDef *module, pid_t pid)
8432/*[clinic end generated code: output=3db4ed686179160d input=39d710ae3baaf1c7]*/
8433{
8434 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 if (pgid < 0)
8436 return posix_error();
8437 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00008438}
8439#endif /* HAVE_GETPGID */
8440
8441
Guido van Rossumb6775db1994-08-01 11:34:53 +00008442#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008443/*[clinic input]
8444os.getpgrp
8445
8446Return the current process group id.
8447[clinic start generated code]*/
8448
8449PyDoc_STRVAR(os_getpgrp__doc__,
8450"getpgrp($module, /)\n"
8451"--\n"
8452"\n"
8453"Return the current process group id.");
8454
8455#define OS_GETPGRP_METHODDEF \
8456 {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008457
Barry Warsaw53699e91996-12-10 23:23:01 +00008458static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008459os_getpgrp_impl(PyModuleDef *module);
8460
8461static PyObject *
8462os_getpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8463{
8464 return os_getpgrp_impl(module);
8465}
8466
8467static PyObject *
8468os_getpgrp_impl(PyModuleDef *module)
8469/*[clinic end generated code: output=3b0d3663ea054277 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00008470{
Guido van Rossumb6775db1994-08-01 11:34:53 +00008471#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008473#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008475#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00008476}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008477#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00008478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008479
Guido van Rossumb6775db1994-08-01 11:34:53 +00008480#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008481/*[clinic input]
8482os.setpgrp
8483
8484Make the current process the leader of its process group.
8485[clinic start generated code]*/
8486
8487PyDoc_STRVAR(os_setpgrp__doc__,
8488"setpgrp($module, /)\n"
8489"--\n"
8490"\n"
8491"Make the current process the leader of its process group.");
8492
8493#define OS_SETPGRP_METHODDEF \
8494 {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008495
Barry Warsaw53699e91996-12-10 23:23:01 +00008496static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008497os_setpgrp_impl(PyModuleDef *module);
8498
8499static PyObject *
8500os_setpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8501{
8502 return os_setpgrp_impl(module);
8503}
8504
8505static PyObject *
8506os_setpgrp_impl(PyModuleDef *module)
8507/*[clinic end generated code: output=8fbb0ee29ef6fb2d input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008508{
Guido van Rossum64933891994-10-20 21:56:42 +00008509#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00008510 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00008511#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00008513#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 return posix_error();
8515 Py_INCREF(Py_None);
8516 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008517}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008518#endif /* HAVE_SETPGRP */
8519
Guido van Rossumad0ee831995-03-01 10:34:45 +00008520#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008521
8522#ifdef MS_WINDOWS
8523#include <tlhelp32.h>
8524
8525static PyObject*
8526win32_getppid()
8527{
8528 HANDLE snapshot;
8529 pid_t mypid;
8530 PyObject* result = NULL;
8531 BOOL have_record;
8532 PROCESSENTRY32 pe;
8533
8534 mypid = getpid(); /* This function never fails */
8535
8536 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
8537 if (snapshot == INVALID_HANDLE_VALUE)
8538 return PyErr_SetFromWindowsErr(GetLastError());
8539
8540 pe.dwSize = sizeof(pe);
8541 have_record = Process32First(snapshot, &pe);
8542 while (have_record) {
8543 if (mypid == (pid_t)pe.th32ProcessID) {
8544 /* We could cache the ulong value in a static variable. */
8545 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
8546 break;
8547 }
8548
8549 have_record = Process32Next(snapshot, &pe);
8550 }
8551
8552 /* If our loop exits and our pid was not found (result will be NULL)
8553 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
8554 * error anyway, so let's raise it. */
8555 if (!result)
8556 result = PyErr_SetFromWindowsErr(GetLastError());
8557
8558 CloseHandle(snapshot);
8559
8560 return result;
8561}
8562#endif /*MS_WINDOWS*/
8563
Larry Hastings2f936352014-08-05 14:04:04 +10008564
8565/*[clinic input]
8566os.getppid
8567
8568Return the parent's process id.
8569
8570If the parent process has already exited, Windows machines will still
8571return its id; others systems will return the id of the 'init' process (1).
8572[clinic start generated code]*/
8573
8574PyDoc_STRVAR(os_getppid__doc__,
8575"getppid($module, /)\n"
8576"--\n"
8577"\n"
8578"Return the parent\'s process id.\n"
8579"\n"
8580"If the parent process has already exited, Windows machines will still\n"
8581"return its id; others systems will return the id of the \'init\' process (1).");
8582
8583#define OS_GETPPID_METHODDEF \
8584 {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008585
Barry Warsaw53699e91996-12-10 23:23:01 +00008586static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008587os_getppid_impl(PyModuleDef *module);
8588
8589static PyObject *
8590os_getppid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8591{
8592 return os_getppid_impl(module);
8593}
8594
8595static PyObject *
8596os_getppid_impl(PyModuleDef *module)
8597/*[clinic end generated code: output=9ff3b387781edf3a input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00008598{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008599#ifdef MS_WINDOWS
8600 return win32_getppid();
8601#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00008603#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008604}
8605#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008606
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008607
Fred Drake12c6e2d1999-12-14 21:25:03 +00008608#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10008609/*[clinic input]
8610os.getlogin
8611
8612Return the actual login name.
8613[clinic start generated code]*/
8614
8615PyDoc_STRVAR(os_getlogin__doc__,
8616"getlogin($module, /)\n"
8617"--\n"
8618"\n"
8619"Return the actual login name.");
8620
8621#define OS_GETLOGIN_METHODDEF \
8622 {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008623
8624static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008625os_getlogin_impl(PyModuleDef *module);
8626
8627static PyObject *
8628os_getlogin(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8629{
8630 return os_getlogin_impl(module);
8631}
8632
8633static PyObject *
8634os_getlogin_impl(PyModuleDef *module)
8635/*[clinic end generated code: output=ab6211dab104cbb2 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00008636{
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008638#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008639 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02008640 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008641
8642 if (GetUserNameW(user_name, &num_chars)) {
8643 /* num_chars is the number of unicode chars plus null terminator */
8644 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008645 }
8646 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008647 result = PyErr_SetFromWindowsErr(GetLastError());
8648#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 char *name;
8650 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008651
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 errno = 0;
8653 name = getlogin();
8654 if (name == NULL) {
8655 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00008656 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00008657 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00008658 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00008659 }
8660 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00008661 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008663#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00008664 return result;
8665}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008666#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008667
Larry Hastings2f936352014-08-05 14:04:04 +10008668
Guido van Rossumad0ee831995-03-01 10:34:45 +00008669#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10008670/*[clinic input]
8671os.getuid
8672
8673Return the current process's user id.
8674[clinic start generated code]*/
8675
8676PyDoc_STRVAR(os_getuid__doc__,
8677"getuid($module, /)\n"
8678"--\n"
8679"\n"
8680"Return the current process\'s user id.");
8681
8682#define OS_GETUID_METHODDEF \
8683 {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008684
Barry Warsaw53699e91996-12-10 23:23:01 +00008685static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008686os_getuid_impl(PyModuleDef *module);
8687
8688static PyObject *
8689os_getuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8690{
8691 return os_getuid_impl(module);
8692}
8693
8694static PyObject *
8695os_getuid_impl(PyModuleDef *module)
8696/*[clinic end generated code: output=77e0dcf2e37d1e89 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008697{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008698 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008699}
Larry Hastings2f936352014-08-05 14:04:04 +10008700#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008702
Brian Curtineb24d742010-04-12 17:16:38 +00008703#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008704#define HAVE_KILL
8705#endif /* MS_WINDOWS */
8706
8707#ifdef HAVE_KILL
8708/*[clinic input]
8709os.kill
8710
8711 pid: pid_t
8712 signal: Py_ssize_t
8713 /
8714
8715Kill a process with a signal.
8716[clinic start generated code]*/
8717
8718PyDoc_STRVAR(os_kill__doc__,
8719"kill($module, pid, signal, /)\n"
8720"--\n"
8721"\n"
8722"Kill a process with a signal.");
8723
8724#define OS_KILL_METHODDEF \
8725 {"kill", (PyCFunction)os_kill, METH_VARARGS, os_kill__doc__},
Brian Curtineb24d742010-04-12 17:16:38 +00008726
8727static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008728os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal);
8729
8730static PyObject *
8731os_kill(PyModuleDef *module, PyObject *args)
8732{
8733 PyObject *return_value = NULL;
8734 pid_t pid;
8735 Py_ssize_t signal;
8736
8737 if (!PyArg_ParseTuple(args,
8738 "" _Py_PARSE_PID "n:kill",
8739 &pid, &signal))
8740 goto exit;
8741 return_value = os_kill_impl(module, pid, signal);
8742
8743exit:
8744 return return_value;
8745}
8746
8747static PyObject *
8748os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
8749/*[clinic end generated code: output=2f5c77920ed575e6 input=61a36b86ca275ab9]*/
8750#ifndef MS_WINDOWS
8751{
8752 if (kill(pid, (int)signal) == -1)
8753 return posix_error();
8754 Py_RETURN_NONE;
8755}
8756#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00008757{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00008758 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10008759 DWORD sig = (DWORD)signal;
8760 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00008762
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 /* Console processes which share a common console can be sent CTRL+C or
8764 CTRL+BREAK events, provided they handle said events. */
8765 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01008766 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 err = GetLastError();
8768 PyErr_SetFromWindowsErr(err);
8769 }
8770 else
8771 Py_RETURN_NONE;
8772 }
Brian Curtineb24d742010-04-12 17:16:38 +00008773
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
8775 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01008776 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 if (handle == NULL) {
8778 err = GetLastError();
8779 return PyErr_SetFromWindowsErr(err);
8780 }
Brian Curtineb24d742010-04-12 17:16:38 +00008781
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 if (TerminateProcess(handle, sig) == 0) {
8783 err = GetLastError();
8784 result = PyErr_SetFromWindowsErr(err);
8785 } else {
8786 Py_INCREF(Py_None);
8787 result = Py_None;
8788 }
Brian Curtineb24d742010-04-12 17:16:38 +00008789
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 CloseHandle(handle);
8791 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00008792}
Larry Hastings2f936352014-08-05 14:04:04 +10008793#endif /* !MS_WINDOWS */
8794#endif /* HAVE_KILL */
8795
8796
8797#ifdef HAVE_KILLPG
8798/*[clinic input]
8799os.killpg
8800
8801 pgid: pid_t
8802 signal: int
8803 /
8804
8805Kill a process group with a signal.
8806[clinic start generated code]*/
8807
8808PyDoc_STRVAR(os_killpg__doc__,
8809"killpg($module, pgid, signal, /)\n"
8810"--\n"
8811"\n"
8812"Kill a process group with a signal.");
8813
8814#define OS_KILLPG_METHODDEF \
8815 {"killpg", (PyCFunction)os_killpg, METH_VARARGS, os_killpg__doc__},
8816
8817static PyObject *
8818os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal);
8819
8820static PyObject *
8821os_killpg(PyModuleDef *module, PyObject *args)
8822{
8823 PyObject *return_value = NULL;
8824 pid_t pgid;
8825 int signal;
8826
8827 if (!PyArg_ParseTuple(args,
8828 "" _Py_PARSE_PID "i:killpg",
8829 &pgid, &signal))
8830 goto exit;
8831 return_value = os_killpg_impl(module, pgid, signal);
8832
8833exit:
8834 return return_value;
8835}
8836
8837static PyObject *
8838os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
8839/*[clinic end generated code: output=0e05215d1c007e01 input=38b5449eb8faec19]*/
8840{
8841 /* XXX some man pages make the `pgid` parameter an int, others
8842 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
8843 take the same type. Moreover, pid_t is always at least as wide as
8844 int (else compilation of this module fails), which is safe. */
8845 if (killpg(pgid, signal) == -1)
8846 return posix_error();
8847 Py_RETURN_NONE;
8848}
8849#endif /* HAVE_KILLPG */
8850
Brian Curtineb24d742010-04-12 17:16:38 +00008851
Guido van Rossumc0125471996-06-28 18:55:32 +00008852#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00008853#ifdef HAVE_SYS_LOCK_H
8854#include <sys/lock.h>
8855#endif
8856
Larry Hastings2f936352014-08-05 14:04:04 +10008857/*[clinic input]
8858os.plock
8859 op: int
8860 /
8861
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008862Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10008863[clinic start generated code]*/
8864
8865PyDoc_STRVAR(os_plock__doc__,
8866"plock($module, op, /)\n"
8867"--\n"
8868"\n"
8869"Lock program segments into memory.\");");
8870
8871#define OS_PLOCK_METHODDEF \
8872 {"plock", (PyCFunction)os_plock, METH_VARARGS, os_plock__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008873
Barry Warsaw53699e91996-12-10 23:23:01 +00008874static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008875os_plock_impl(PyModuleDef *module, int op);
8876
8877static PyObject *
8878os_plock(PyModuleDef *module, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00008879{
Larry Hastings2f936352014-08-05 14:04:04 +10008880 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 int op;
Larry Hastings2f936352014-08-05 14:04:04 +10008882
8883 if (!PyArg_ParseTuple(args,
8884 "i:plock",
8885 &op))
8886 goto exit;
8887 return_value = os_plock_impl(module, op);
8888
8889exit:
8890 return return_value;
8891}
8892
8893static PyObject *
8894os_plock_impl(PyModuleDef *module, int op)
8895/*[clinic end generated code: output=2744fe4b6e5f4dbc input=e6e5e348e1525f60]*/
8896{
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 if (plock(op) == -1)
8898 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008899 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00008900}
Larry Hastings2f936352014-08-05 14:04:04 +10008901#endif /* HAVE_PLOCK */
8902
Guido van Rossumc0125471996-06-28 18:55:32 +00008903
Guido van Rossumb6775db1994-08-01 11:34:53 +00008904#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10008905/*[clinic input]
8906os.setuid
8907
8908 uid: uid_t
8909 /
8910
8911Set the current process's user id.
8912[clinic start generated code]*/
8913
8914PyDoc_STRVAR(os_setuid__doc__,
8915"setuid($module, uid, /)\n"
8916"--\n"
8917"\n"
8918"Set the current process\'s user id.");
8919
8920#define OS_SETUID_METHODDEF \
8921 {"setuid", (PyCFunction)os_setuid, METH_VARARGS, os_setuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008922
Barry Warsaw53699e91996-12-10 23:23:01 +00008923static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008924os_setuid_impl(PyModuleDef *module, uid_t uid);
8925
8926static PyObject *
8927os_setuid(PyModuleDef *module, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008928{
Larry Hastings2f936352014-08-05 14:04:04 +10008929 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 uid_t uid;
Larry Hastings2f936352014-08-05 14:04:04 +10008931
8932 if (!PyArg_ParseTuple(args,
8933 "O&:setuid",
8934 _Py_Uid_Converter, &uid))
8935 goto exit;
8936 return_value = os_setuid_impl(module, uid);
8937
8938exit:
8939 return return_value;
8940}
8941
8942static PyObject *
8943os_setuid_impl(PyModuleDef *module, uid_t uid)
8944/*[clinic end generated code: output=aea344bc22ccf400 input=c921a3285aa22256]*/
8945{
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 if (setuid(uid) < 0)
8947 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008948 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008949}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008950#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008952
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008953#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008954/*[clinic input]
8955os.seteuid
8956
8957 euid: uid_t
8958 /
8959
8960Set the current process's effective user id.
8961[clinic start generated code]*/
8962
8963PyDoc_STRVAR(os_seteuid__doc__,
8964"seteuid($module, euid, /)\n"
8965"--\n"
8966"\n"
8967"Set the current process\'s effective user id.");
8968
8969#define OS_SETEUID_METHODDEF \
8970 {"seteuid", (PyCFunction)os_seteuid, METH_VARARGS, os_seteuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008971
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008972static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008973os_seteuid_impl(PyModuleDef *module, uid_t euid);
8974
8975static PyObject *
8976os_seteuid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008977{
Larry Hastings2f936352014-08-05 14:04:04 +10008978 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 uid_t euid;
Larry Hastings2f936352014-08-05 14:04:04 +10008980
8981 if (!PyArg_ParseTuple(args,
8982 "O&:seteuid",
8983 _Py_Uid_Converter, &euid))
8984 goto exit;
8985 return_value = os_seteuid_impl(module, euid);
8986
8987exit:
8988 return return_value;
8989}
8990
8991static PyObject *
8992os_seteuid_impl(PyModuleDef *module, uid_t euid)
8993/*[clinic end generated code: output=6e824cce4f3b8a5d input=ba93d927e4781aa9]*/
8994{
8995 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008997 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008998}
8999#endif /* HAVE_SETEUID */
9000
Larry Hastings2f936352014-08-05 14:04:04 +10009001
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009002#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10009003/*[clinic input]
9004os.setegid
9005
9006 egid: gid_t
9007 /
9008
9009Set the current process's effective group id.
9010[clinic start generated code]*/
9011
9012PyDoc_STRVAR(os_setegid__doc__,
9013"setegid($module, egid, /)\n"
9014"--\n"
9015"\n"
9016"Set the current process\'s effective group id.");
9017
9018#define OS_SETEGID_METHODDEF \
9019 {"setegid", (PyCFunction)os_setegid, METH_VARARGS, os_setegid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009020
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009021static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009022os_setegid_impl(PyModuleDef *module, gid_t egid);
9023
9024static PyObject *
9025os_setegid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009026{
Larry Hastings2f936352014-08-05 14:04:04 +10009027 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 gid_t egid;
Larry Hastings2f936352014-08-05 14:04:04 +10009029
9030 if (!PyArg_ParseTuple(args,
9031 "O&:setegid",
9032 _Py_Gid_Converter, &egid))
9033 goto exit;
9034 return_value = os_setegid_impl(module, egid);
9035
9036exit:
9037 return return_value;
9038}
9039
9040static PyObject *
9041os_setegid_impl(PyModuleDef *module, gid_t egid)
9042/*[clinic end generated code: output=80a32263a4d56a9c input=4080526d0ccd6ce3]*/
9043{
9044 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009046 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009047}
9048#endif /* HAVE_SETEGID */
9049
Larry Hastings2f936352014-08-05 14:04:04 +10009050
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009051#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10009052/*[clinic input]
9053os.setreuid
9054
9055 ruid: uid_t
9056 euid: uid_t
9057 /
9058
9059Set the current process's real and effective user ids.
9060[clinic start generated code]*/
9061
9062PyDoc_STRVAR(os_setreuid__doc__,
9063"setreuid($module, ruid, euid, /)\n"
9064"--\n"
9065"\n"
9066"Set the current process\'s real and effective user ids.");
9067
9068#define OS_SETREUID_METHODDEF \
9069 {"setreuid", (PyCFunction)os_setreuid, METH_VARARGS, os_setreuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009070
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009071static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009072os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid);
9073
9074static PyObject *
9075os_setreuid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009076{
Larry Hastings2f936352014-08-05 14:04:04 +10009077 PyObject *return_value = NULL;
9078 uid_t ruid;
9079 uid_t euid;
9080
9081 if (!PyArg_ParseTuple(args,
9082 "O&O&:setreuid",
9083 _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid))
9084 goto exit;
9085 return_value = os_setreuid_impl(module, ruid, euid);
9086
9087exit:
9088 return return_value;
9089}
9090
9091static PyObject *
9092os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
9093/*[clinic end generated code: output=d7f226f943dad739 input=0ca8978de663880c]*/
9094{
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 if (setreuid(ruid, euid) < 0) {
9096 return posix_error();
9097 } else {
9098 Py_INCREF(Py_None);
9099 return Py_None;
9100 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009101}
9102#endif /* HAVE_SETREUID */
9103
Larry Hastings2f936352014-08-05 14:04:04 +10009104
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009105#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10009106/*[clinic input]
9107os.setregid
9108
9109 rgid: gid_t
9110 egid: gid_t
9111 /
9112
9113Set the current process's real and effective group ids.
9114[clinic start generated code]*/
9115
9116PyDoc_STRVAR(os_setregid__doc__,
9117"setregid($module, rgid, egid, /)\n"
9118"--\n"
9119"\n"
9120"Set the current process\'s real and effective group ids.");
9121
9122#define OS_SETREGID_METHODDEF \
9123 {"setregid", (PyCFunction)os_setregid, METH_VARARGS, os_setregid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009124
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009125static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009126os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid);
9127
9128static PyObject *
9129os_setregid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009130{
Larry Hastings2f936352014-08-05 14:04:04 +10009131 PyObject *return_value = NULL;
9132 gid_t rgid;
9133 gid_t egid;
9134
9135 if (!PyArg_ParseTuple(args,
9136 "O&O&:setregid",
9137 _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid))
9138 goto exit;
9139 return_value = os_setregid_impl(module, rgid, egid);
9140
9141exit:
9142 return return_value;
9143}
9144
9145static PyObject *
9146os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
9147/*[clinic end generated code: output=a82d9ab70f8e6562 input=c59499f72846db78]*/
9148{
9149 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009151 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009152}
9153#endif /* HAVE_SETREGID */
9154
Larry Hastings2f936352014-08-05 14:04:04 +10009155
Guido van Rossumb6775db1994-08-01 11:34:53 +00009156#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10009157/*[clinic input]
9158os.setgid
9159 gid: gid_t
9160 /
9161
9162Set the current process's group id.
9163[clinic start generated code]*/
9164
9165PyDoc_STRVAR(os_setgid__doc__,
9166"setgid($module, gid, /)\n"
9167"--\n"
9168"\n"
9169"Set the current process\'s group id.");
9170
9171#define OS_SETGID_METHODDEF \
9172 {"setgid", (PyCFunction)os_setgid, METH_VARARGS, os_setgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009173
Barry Warsaw53699e91996-12-10 23:23:01 +00009174static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009175os_setgid_impl(PyModuleDef *module, gid_t gid);
9176
9177static PyObject *
9178os_setgid(PyModuleDef *module, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009179{
Larry Hastings2f936352014-08-05 14:04:04 +10009180 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009181 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10009182
9183 if (!PyArg_ParseTuple(args,
9184 "O&:setgid",
9185 _Py_Gid_Converter, &gid))
9186 goto exit;
9187 return_value = os_setgid_impl(module, gid);
9188
9189exit:
9190 return return_value;
9191}
9192
9193static PyObject *
9194os_setgid_impl(PyModuleDef *module, gid_t gid)
9195/*[clinic end generated code: output=08287886db435f23 input=27d30c4059045dc6]*/
9196{
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 if (setgid(gid) < 0)
9198 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009199 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009200}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009201#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009202
Larry Hastings2f936352014-08-05 14:04:04 +10009203
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009204#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10009205/*[clinic input]
9206os.setgroups
9207
9208 groups: object
9209 /
9210
9211Set the groups of the current process to list.
9212[clinic start generated code]*/
9213
9214PyDoc_STRVAR(os_setgroups__doc__,
9215"setgroups($module, groups, /)\n"
9216"--\n"
9217"\n"
9218"Set the groups of the current process to list.");
9219
9220#define OS_SETGROUPS_METHODDEF \
9221 {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009222
9223static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009224os_setgroups(PyModuleDef *module, PyObject *groups)
9225/*[clinic end generated code: output=0b8de65d5b3cda94 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009226{
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 int i, len;
9228 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00009229
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 if (!PySequence_Check(groups)) {
9231 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
9232 return NULL;
9233 }
9234 len = PySequence_Size(groups);
9235 if (len > MAX_GROUPS) {
9236 PyErr_SetString(PyExc_ValueError, "too many groups");
9237 return NULL;
9238 }
9239 for(i = 0; i < len; i++) {
9240 PyObject *elem;
9241 elem = PySequence_GetItem(groups, i);
9242 if (!elem)
9243 return NULL;
9244 if (!PyLong_Check(elem)) {
9245 PyErr_SetString(PyExc_TypeError,
9246 "groups must be integers");
9247 Py_DECREF(elem);
9248 return NULL;
9249 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009250 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 Py_DECREF(elem);
9252 return NULL;
9253 }
9254 }
9255 Py_DECREF(elem);
9256 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009257
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 if (setgroups(len, grouplist) < 0)
9259 return posix_error();
9260 Py_INCREF(Py_None);
9261 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009262}
9263#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009264
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009265#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
9266static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01009267wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009268{
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 PyObject *result;
9270 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02009271 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009272
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 if (pid == -1)
9274 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009275
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 if (struct_rusage == NULL) {
9277 PyObject *m = PyImport_ImportModuleNoBlock("resource");
9278 if (m == NULL)
9279 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02009280 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 Py_DECREF(m);
9282 if (struct_rusage == NULL)
9283 return NULL;
9284 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009285
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
9287 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
9288 if (!result)
9289 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009290
9291#ifndef doubletime
9292#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
9293#endif
9294
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009296 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009298 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009299#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
9301 SET_INT(result, 2, ru->ru_maxrss);
9302 SET_INT(result, 3, ru->ru_ixrss);
9303 SET_INT(result, 4, ru->ru_idrss);
9304 SET_INT(result, 5, ru->ru_isrss);
9305 SET_INT(result, 6, ru->ru_minflt);
9306 SET_INT(result, 7, ru->ru_majflt);
9307 SET_INT(result, 8, ru->ru_nswap);
9308 SET_INT(result, 9, ru->ru_inblock);
9309 SET_INT(result, 10, ru->ru_oublock);
9310 SET_INT(result, 11, ru->ru_msgsnd);
9311 SET_INT(result, 12, ru->ru_msgrcv);
9312 SET_INT(result, 13, ru->ru_nsignals);
9313 SET_INT(result, 14, ru->ru_nvcsw);
9314 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009315#undef SET_INT
9316
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 if (PyErr_Occurred()) {
9318 Py_DECREF(result);
9319 return NULL;
9320 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009321
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009323}
9324#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
9325
Larry Hastings2f936352014-08-05 14:04:04 +10009326
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009327#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10009328/*[clinic input]
9329os.wait3
9330
9331 options: int
9332Wait for completion of a child process.
9333
9334Returns a tuple of information about the child process:
9335 (pid, status, rusage)
9336[clinic start generated code]*/
9337
9338PyDoc_STRVAR(os_wait3__doc__,
9339"wait3($module, /, options)\n"
9340"--\n"
9341"\n"
9342"Wait for completion of a child process.\n"
9343"\n"
9344"Returns a tuple of information about the child process:\n"
9345" (pid, status, rusage)");
9346
9347#define OS_WAIT3_METHODDEF \
9348 {"wait3", (PyCFunction)os_wait3, METH_VARARGS|METH_KEYWORDS, os_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009349
9350static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009351os_wait3_impl(PyModuleDef *module, int options);
9352
9353static PyObject *
9354os_wait3(PyModuleDef *module, PyObject *args, PyObject *kwargs)
9355{
9356 PyObject *return_value = NULL;
9357 static char *_keywords[] = {"options", NULL};
9358 int options;
9359
9360 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
9361 "i:wait3", _keywords,
9362 &options))
9363 goto exit;
9364 return_value = os_wait3_impl(module, options);
9365
9366exit:
9367 return return_value;
9368}
9369
9370static PyObject *
9371os_wait3_impl(PyModuleDef *module, int options)
9372/*[clinic end generated code: output=1f2a63b6a93cbb57 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009373{
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009376 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 WAIT_TYPE status;
9378 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009379
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009380 do {
9381 Py_BEGIN_ALLOW_THREADS
9382 pid = wait3(&status, options, &ru);
9383 Py_END_ALLOW_THREADS
9384 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9385 if (pid < 0)
9386 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009387
Victor Stinner4195b5c2012-02-08 23:03:19 +01009388 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009389}
9390#endif /* HAVE_WAIT3 */
9391
Larry Hastings2f936352014-08-05 14:04:04 +10009392
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009393#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10009394/*[clinic input]
9395
9396os.wait4
9397
9398 pid: pid_t
9399 options: int
9400
9401Wait for completion of a specific child process.
9402
9403Returns a tuple of information about the child process:
9404 (pid, status, rusage)
9405[clinic start generated code]*/
9406
9407PyDoc_STRVAR(os_wait4__doc__,
9408"wait4($module, /, pid, options)\n"
9409"--\n"
9410"\n"
9411"Wait for completion of a specific child process.\n"
9412"\n"
9413"Returns a tuple of information about the child process:\n"
9414" (pid, status, rusage)");
9415
9416#define OS_WAIT4_METHODDEF \
9417 {"wait4", (PyCFunction)os_wait4, METH_VARARGS|METH_KEYWORDS, os_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009418
9419static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009420os_wait4_impl(PyModuleDef *module, pid_t pid, int options);
9421
9422static PyObject *
9423os_wait4(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009424{
Larry Hastings2f936352014-08-05 14:04:04 +10009425 PyObject *return_value = NULL;
9426 static char *_keywords[] = {"pid", "options", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 pid_t pid;
9428 int options;
Larry Hastings2f936352014-08-05 14:04:04 +10009429
9430 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
9431 "" _Py_PARSE_PID "i:wait4", _keywords,
9432 &pid, &options))
9433 goto exit;
9434 return_value = os_wait4_impl(module, pid, options);
9435
9436exit:
9437 return return_value;
9438}
9439
9440static PyObject *
9441os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
9442/*[clinic end generated code: output=20dfb05289d37dc6 input=d11deed0750600ba]*/
9443{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009444 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009446 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 WAIT_TYPE status;
9448 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009449
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009450 do {
9451 Py_BEGIN_ALLOW_THREADS
9452 res = wait4(pid, &status, options, &ru);
9453 Py_END_ALLOW_THREADS
9454 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9455 if (res < 0)
9456 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009457
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009458 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009459}
9460#endif /* HAVE_WAIT4 */
9461
Larry Hastings2f936352014-08-05 14:04:04 +10009462
Ross Lagerwall7807c352011-03-17 20:20:30 +02009463#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10009464/*[clinic input]
9465os.waitid
9466
9467 idtype: idtype_t
9468 Must be one of be P_PID, P_PGID or P_ALL.
9469 id: id_t
9470 The id to wait on.
9471 options: int
9472 Constructed from the ORing of one or more of WEXITED, WSTOPPED
9473 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
9474 /
9475
9476Returns the result of waiting for a process or processes.
9477
9478Returns either waitid_result or None if WNOHANG is specified and there are
9479no children in a waitable state.
9480[clinic start generated code]*/
9481
9482PyDoc_STRVAR(os_waitid__doc__,
9483"waitid($module, idtype, id, options, /)\n"
9484"--\n"
9485"\n"
9486"Returns the result of waiting for a process or processes.\n"
9487"\n"
9488" idtype\n"
9489" Must be one of be P_PID, P_PGID or P_ALL.\n"
9490" id\n"
9491" The id to wait on.\n"
9492" options\n"
9493" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n"
9494" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n"
9495"\n"
9496"Returns either waitid_result or None if WNOHANG is specified and there are\n"
9497"no children in a waitable state.");
9498
9499#define OS_WAITID_METHODDEF \
9500 {"waitid", (PyCFunction)os_waitid, METH_VARARGS, os_waitid__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02009501
9502static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009503os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options);
9504
9505static PyObject *
9506os_waitid(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009507{
Larry Hastings2f936352014-08-05 14:04:04 +10009508 PyObject *return_value = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009509 idtype_t idtype;
9510 id_t id;
Larry Hastings2f936352014-08-05 14:04:04 +10009511 int options;
9512
9513 if (!PyArg_ParseTuple(args,
9514 "i" _Py_PARSE_PID "i:waitid",
9515 &idtype, &id, &options))
9516 goto exit;
9517 return_value = os_waitid_impl(module, idtype, id, options);
9518
9519exit:
9520 return return_value;
9521}
9522
9523static PyObject *
9524os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
9525/*[clinic end generated code: output=fb44bf97f01021b2 input=d8e7f76e052b7920]*/
9526{
9527 PyObject *result;
9528 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009529 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009530 siginfo_t si;
9531 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009532
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009533 do {
9534 Py_BEGIN_ALLOW_THREADS
9535 res = waitid(idtype, id, &si, options);
9536 Py_END_ALLOW_THREADS
9537 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9538 if (res < 0)
9539 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009540
9541 if (si.si_pid == 0)
9542 Py_RETURN_NONE;
9543
9544 result = PyStructSequence_New(&WaitidResultType);
9545 if (!result)
9546 return NULL;
9547
9548 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009549 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009550 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
9551 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
9552 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
9553 if (PyErr_Occurred()) {
9554 Py_DECREF(result);
9555 return NULL;
9556 }
9557
9558 return result;
9559}
Larry Hastings2f936352014-08-05 14:04:04 +10009560#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009561
Larry Hastings2f936352014-08-05 14:04:04 +10009562
9563#if defined(HAVE_WAITPID)
9564/*[clinic input]
9565os.waitpid
9566 pid: pid_t
9567 options: int
9568 /
9569
9570Wait for completion of a given child process.
9571
9572Returns a tuple of information regarding the child process:
9573 (pid, status)
9574
9575The options argument is ignored on Windows.
9576[clinic start generated code]*/
9577
9578PyDoc_STRVAR(os_waitpid__doc__,
9579"waitpid($module, pid, options, /)\n"
9580"--\n"
9581"\n"
9582"Wait for completion of a given child process.\n"
9583"\n"
9584"Returns a tuple of information regarding the child process:\n"
9585" (pid, status)\n"
9586"\n"
9587"The options argument is ignored on Windows.");
9588
9589#define OS_WAITPID_METHODDEF \
9590 {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009591
Barry Warsaw53699e91996-12-10 23:23:01 +00009592static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009593os_waitpid_impl(PyModuleDef *module, pid_t pid, int options);
9594
9595static PyObject *
9596os_waitpid(PyModuleDef *module, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00009597{
Larry Hastings2f936352014-08-05 14:04:04 +10009598 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 pid_t pid;
9600 int options;
Larry Hastings2f936352014-08-05 14:04:04 +10009601
9602 if (!PyArg_ParseTuple(args,
9603 "" _Py_PARSE_PID "i:waitpid",
9604 &pid, &options))
9605 goto exit;
9606 return_value = os_waitpid_impl(module, pid, options);
9607
9608exit:
9609 return return_value;
9610}
9611
9612static PyObject *
9613os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
9614/*[clinic end generated code: output=095a6b00af70b7ac input=0bf1666b8758fda3]*/
9615{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009616 pid_t res;
9617 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 WAIT_TYPE status;
9619 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009620
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009621 do {
9622 Py_BEGIN_ALLOW_THREADS
9623 res = waitpid(pid, &status, options);
9624 Py_END_ALLOW_THREADS
9625 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9626 if (res < 0)
9627 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009628
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009629 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00009630}
Tim Petersab034fa2002-02-01 11:27:43 +00009631#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00009632/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10009633/*[clinic input]
9634os.waitpid
9635 pid: Py_intptr_t
9636 options: int
9637 /
9638
9639Wait for completion of a given process.
9640
9641Returns a tuple of information regarding the process:
9642 (pid, status << 8)
9643
9644The options argument is ignored on Windows.
9645[clinic start generated code]*/
9646
9647PyDoc_STRVAR(os_waitpid__doc__,
9648"waitpid($module, pid, options, /)\n"
9649"--\n"
9650"\n"
9651"Wait for completion of a given process.\n"
9652"\n"
9653"Returns a tuple of information regarding the process:\n"
9654" (pid, status << 8)\n"
9655"\n"
9656"The options argument is ignored on Windows.");
9657
9658#define OS_WAITPID_METHODDEF \
9659 {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__},
Tim Petersab034fa2002-02-01 11:27:43 +00009660
9661static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009662os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options);
Tim Petersab034fa2002-02-01 11:27:43 +00009663
Larry Hastings2f936352014-08-05 14:04:04 +10009664static PyObject *
9665os_waitpid(PyModuleDef *module, PyObject *args)
9666{
9667 PyObject *return_value = NULL;
9668 Py_intptr_t pid;
9669 int options;
9670
9671 if (!PyArg_ParseTuple(args,
9672 "" _Py_PARSE_INTPTR "i:waitpid",
9673 &pid, &options))
9674 goto exit;
9675 return_value = os_waitpid_impl(module, pid, options);
9676
9677exit:
9678 return return_value;
9679}
9680
9681static PyObject *
9682os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
9683/*[clinic end generated code: output=c20b95b15ad44a3a input=444c8f51cca5b862]*/
9684{
9685 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009686 Py_intptr_t res;
9687 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009688
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009689 do {
9690 Py_BEGIN_ALLOW_THREADS
9691 res = _cwait(&status, pid, options);
9692 Py_END_ALLOW_THREADS
9693 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9694 if (res != 0)
9695 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009696
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009698 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00009699}
Larry Hastings2f936352014-08-05 14:04:04 +10009700#endif
9701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009702
Guido van Rossumad0ee831995-03-01 10:34:45 +00009703#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10009704/*[clinic input]
9705os.wait
9706
9707Wait for completion of a child process.
9708
9709Returns a tuple of information about the child process:
9710 (pid, status)
9711[clinic start generated code]*/
9712
9713PyDoc_STRVAR(os_wait__doc__,
9714"wait($module, /)\n"
9715"--\n"
9716"\n"
9717"Wait for completion of a child process.\n"
9718"\n"
9719"Returns a tuple of information about the child process:\n"
9720" (pid, status)");
9721
9722#define OS_WAIT_METHODDEF \
9723 {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009724
Barry Warsaw53699e91996-12-10 23:23:01 +00009725static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009726os_wait_impl(PyModuleDef *module);
9727
9728static PyObject *
9729os_wait(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
9730{
9731 return os_wait_impl(module);
9732}
9733
9734static PyObject *
9735os_wait_impl(PyModuleDef *module)
9736/*[clinic end generated code: output=2a83a9d164e7e6a8 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00009737{
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009739 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 WAIT_TYPE status;
9741 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00009742
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009743 do {
9744 Py_BEGIN_ALLOW_THREADS
9745 pid = wait(&status);
9746 Py_END_ALLOW_THREADS
9747 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9748 if (pid < 0)
9749 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009750
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00009752}
Larry Hastings2f936352014-08-05 14:04:04 +10009753#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00009754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009755
Larry Hastings9cf065c2012-06-22 16:30:09 -07009756#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
9757PyDoc_STRVAR(readlink__doc__,
9758"readlink(path, *, dir_fd=None) -> path\n\n\
9759Return a string representing the path to which the symbolic link points.\n\
9760\n\
9761If dir_fd is not None, it should be a file descriptor open to a directory,\n\
9762 and path should be relative; path will then be relative to that directory.\n\
9763dir_fd may not be implemented on your platform.\n\
9764 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009765#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009766
Guido van Rossumb6775db1994-08-01 11:34:53 +00009767#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009768
Larry Hastings2f936352014-08-05 14:04:04 +10009769/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00009770static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009771posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009772{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009773 path_t path;
9774 int dir_fd = DEFAULT_DIR_FD;
9775 char buffer[MAXPATHLEN];
9776 ssize_t length;
9777 PyObject *return_value = NULL;
9778 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00009779
Larry Hastings9cf065c2012-06-22 16:30:09 -07009780 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009781 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009782 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
9783 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10009784 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00009786
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009788#ifdef HAVE_READLINKAT
9789 if (dir_fd != DEFAULT_DIR_FD)
9790 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00009791 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009792#endif
9793 length = readlink(path.narrow, buffer, sizeof(buffer));
9794 Py_END_ALLOW_THREADS
9795
9796 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01009797 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009798 goto exit;
9799 }
9800
9801 if (PyUnicode_Check(path.object))
9802 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
9803 else
9804 return_value = PyBytes_FromStringAndSize(buffer, length);
9805exit:
9806 path_cleanup(&path);
9807 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009808}
Larry Hastings9cf065c2012-06-22 16:30:09 -07009809
Guido van Rossumb6775db1994-08-01 11:34:53 +00009810#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009811
Larry Hastings2f936352014-08-05 14:04:04 +10009812#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
9813
9814static PyObject *
9815win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
9816{
9817 wchar_t *path;
9818 DWORD n_bytes_returned;
9819 DWORD io_result;
9820 PyObject *po, *result;
9821 int dir_fd;
9822 HANDLE reparse_point_handle;
9823
9824 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
9825 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
9826 wchar_t *print_name;
9827
9828 static char *keywords[] = {"path", "dir_fd", NULL};
9829
9830 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
9831 &po,
9832 dir_fd_unavailable, &dir_fd
9833 ))
9834 return NULL;
9835
9836 path = PyUnicode_AsUnicode(po);
9837 if (path == NULL)
9838 return NULL;
9839
9840 /* First get a handle to the reparse point */
9841 Py_BEGIN_ALLOW_THREADS
9842 reparse_point_handle = CreateFileW(
9843 path,
9844 0,
9845 0,
9846 0,
9847 OPEN_EXISTING,
9848 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
9849 0);
9850 Py_END_ALLOW_THREADS
9851
9852 if (reparse_point_handle==INVALID_HANDLE_VALUE)
9853 return win32_error_object("readlink", po);
9854
9855 Py_BEGIN_ALLOW_THREADS
9856 /* New call DeviceIoControl to read the reparse point */
9857 io_result = DeviceIoControl(
9858 reparse_point_handle,
9859 FSCTL_GET_REPARSE_POINT,
9860 0, 0, /* in buffer */
9861 target_buffer, sizeof(target_buffer),
9862 &n_bytes_returned,
9863 0 /* we're not using OVERLAPPED_IO */
9864 );
9865 CloseHandle(reparse_point_handle);
9866 Py_END_ALLOW_THREADS
9867
9868 if (io_result==0)
9869 return win32_error_object("readlink", po);
9870
9871 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
9872 {
9873 PyErr_SetString(PyExc_ValueError,
9874 "not a symbolic link");
9875 return NULL;
9876 }
9877 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
9878 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
9879
9880 result = PyUnicode_FromWideChar(print_name,
9881 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
9882 return result;
9883}
9884
9885#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
9886
9887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009888
Larry Hastings9cf065c2012-06-22 16:30:09 -07009889#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07009890
9891#if defined(MS_WINDOWS)
9892
9893/* Grab CreateSymbolicLinkW dynamically from kernel32 */
9894static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
9895static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02009896
Larry Hastings9cf065c2012-06-22 16:30:09 -07009897static int
Victor Stinner31b3b922013-06-05 01:49:17 +02009898check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07009899{
9900 HINSTANCE hKernel32;
9901 /* only recheck */
9902 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
9903 return 1;
9904 hKernel32 = GetModuleHandleW(L"KERNEL32");
9905 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
9906 "CreateSymbolicLinkW");
9907 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
9908 "CreateSymbolicLinkA");
9909 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
9910}
9911
Victor Stinner31b3b922013-06-05 01:49:17 +02009912/* Remove the last portion of the path */
9913static void
9914_dirnameW(WCHAR *path)
9915{
Jason R. Coombs3a092862013-05-27 23:21:28 -04009916 WCHAR *ptr;
9917
9918 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02009919 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02009920 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04009921 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009922 }
9923 *ptr = 0;
9924}
9925
Victor Stinner31b3b922013-06-05 01:49:17 +02009926/* Remove the last portion of the path */
9927static void
9928_dirnameA(char *path)
9929{
Jason R. Coombs3a092862013-05-27 23:21:28 -04009930 char *ptr;
9931
9932 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02009933 for(ptr = path + strlen(path); ptr != path; ptr--) {
9934 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04009935 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009936 }
9937 *ptr = 0;
9938}
9939
Victor Stinner31b3b922013-06-05 01:49:17 +02009940/* Is this path absolute? */
9941static int
9942_is_absW(const WCHAR *path)
9943{
Jason R. Coombs3a092862013-05-27 23:21:28 -04009944 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
9945
9946}
9947
Victor Stinner31b3b922013-06-05 01:49:17 +02009948/* Is this path absolute? */
9949static int
9950_is_absA(const char *path)
9951{
Jason R. Coombs3a092862013-05-27 23:21:28 -04009952 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
9953
9954}
9955
Victor Stinner31b3b922013-06-05 01:49:17 +02009956/* join root and rest with a backslash */
9957static void
9958_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
9959{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02009960 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009961
Victor Stinner31b3b922013-06-05 01:49:17 +02009962 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04009963 wcscpy(dest_path, rest);
9964 return;
9965 }
9966
9967 root_len = wcslen(root);
9968
9969 wcscpy(dest_path, root);
9970 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02009971 dest_path[root_len] = L'\\';
9972 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009973 }
9974 wcscpy(dest_path+root_len, rest);
9975}
9976
Victor Stinner31b3b922013-06-05 01:49:17 +02009977/* join root and rest with a backslash */
9978static void
9979_joinA(char *dest_path, const char *root, const char *rest)
9980{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02009981 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009982
Victor Stinner31b3b922013-06-05 01:49:17 +02009983 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04009984 strcpy(dest_path, rest);
9985 return;
9986 }
9987
9988 root_len = strlen(root);
9989
9990 strcpy(dest_path, root);
9991 if(root_len) {
9992 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02009993 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04009994 }
9995 strcpy(dest_path+root_len, rest);
9996}
9997
Victor Stinner31b3b922013-06-05 01:49:17 +02009998/* Return True if the path at src relative to dest is a directory */
9999static int
10000_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -040010001{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010002 WIN32_FILE_ATTRIBUTE_DATA src_info;
10003 WCHAR dest_parent[MAX_PATH];
10004 WCHAR src_resolved[MAX_PATH] = L"";
10005
10006 /* dest_parent = os.path.dirname(dest) */
10007 wcscpy(dest_parent, dest);
10008 _dirnameW(dest_parent);
10009 /* src_resolved = os.path.join(dest_parent, src) */
10010 _joinW(src_resolved, dest_parent, src);
10011 return (
10012 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
10013 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
10014 );
10015}
10016
Victor Stinner31b3b922013-06-05 01:49:17 +020010017/* Return True if the path at src relative to dest is a directory */
10018static int
10019_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -040010020{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010021 WIN32_FILE_ATTRIBUTE_DATA src_info;
10022 char dest_parent[MAX_PATH];
10023 char src_resolved[MAX_PATH] = "";
10024
10025 /* dest_parent = os.path.dirname(dest) */
10026 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +020010027 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010028 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +020010029 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010030 return (
10031 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
10032 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
10033 );
10034}
Larry Hastings9cf065c2012-06-22 16:30:09 -070010035#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010036
Larry Hastings2f936352014-08-05 14:04:04 +100010037
10038/*[clinic input]
10039os.symlink
10040 src: path_t
10041 dst: path_t
10042 target_is_directory: bool = False
10043 *
10044 dir_fd: dir_fd(requires='symlinkat')=None
10045
10046# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
10047
10048Create a symbolic link pointing to src named dst.
10049
10050target_is_directory is required on Windows if the target is to be
10051 interpreted as a directory. (On Windows, symlink requires
10052 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
10053 target_is_directory is ignored on non-Windows platforms.
10054
10055If dir_fd is not None, it should be a file descriptor open to a directory,
10056 and path should be relative; path will then be relative to that directory.
10057dir_fd may not be implemented on your platform.
10058 If it is unavailable, using it will raise a NotImplementedError.
10059
10060[clinic start generated code]*/
10061
10062PyDoc_STRVAR(os_symlink__doc__,
10063"symlink($module, /, src, dst, target_is_directory=False, *, dir_fd=None)\n"
10064"--\n"
10065"\n"
10066"Create a symbolic link pointing to src named dst.\n"
10067"\n"
10068"target_is_directory is required on Windows if the target is to be\n"
10069" interpreted as a directory. (On Windows, symlink requires\n"
10070" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n"
10071" target_is_directory is ignored on non-Windows platforms.\n"
10072"\n"
10073"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
10074" and path should be relative; path will then be relative to that directory.\n"
10075"dir_fd may not be implemented on your platform.\n"
10076" If it is unavailable, using it will raise a NotImplementedError.");
10077
10078#define OS_SYMLINK_METHODDEF \
10079 {"symlink", (PyCFunction)os_symlink, METH_VARARGS|METH_KEYWORDS, os_symlink__doc__},
10080
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010081static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010082os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd);
10083
10084static PyObject *
10085os_symlink(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010086{
Larry Hastings2f936352014-08-05 14:04:04 +100010087 PyObject *return_value = NULL;
10088 static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL};
10089 path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0);
10090 path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010091 int target_is_directory = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010092 int dir_fd = DEFAULT_DIR_FD;
10093
10094 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10095 "O&O&|p$O&:symlink", _keywords,
10096 path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd))
10097 goto exit;
10098 return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd);
10099
10100exit:
10101 /* Cleanup for src */
10102 path_cleanup(&src);
10103 /* Cleanup for dst */
10104 path_cleanup(&dst);
10105
10106 return return_value;
10107}
10108
10109static PyObject *
10110os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd)
10111/*[clinic end generated code: output=1a31e6d88aafe9b6 input=e820ec4472547bc3]*/
10112{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010113#ifdef MS_WINDOWS
10114 DWORD result;
10115#else
10116 int result;
10117#endif
10118
Larry Hastings9cf065c2012-06-22 16:30:09 -070010119#ifdef MS_WINDOWS
10120 if (!check_CreateSymbolicLink()) {
10121 PyErr_SetString(PyExc_NotImplementedError,
10122 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +100010123 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +030010124 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010125 if (!win32_can_symlink) {
10126 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +100010127 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +030010128 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010129#endif
10130
Larry Hastings2f936352014-08-05 14:04:04 +100010131 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010132 PyErr_SetString(PyExc_ValueError,
10133 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +100010134 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010135 }
10136
10137#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -040010138
Larry Hastings9cf065c2012-06-22 16:30:09 -070010139 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010140 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -040010141 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +100010142 target_is_directory |= _check_dirW(src->wide, dst->wide);
10143 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010144 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010145 }
10146 else {
10147 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +100010148 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
10149 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010150 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010151 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010152 Py_END_ALLOW_THREADS
10153
Larry Hastings2f936352014-08-05 14:04:04 +100010154 if (!result)
10155 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010156
10157#else
10158
10159 Py_BEGIN_ALLOW_THREADS
10160#if HAVE_SYMLINKAT
10161 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +100010162 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010163 else
10164#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010165 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010166 Py_END_ALLOW_THREADS
10167
Larry Hastings2f936352014-08-05 14:04:04 +100010168 if (result)
10169 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010170#endif
10171
Larry Hastings2f936352014-08-05 14:04:04 +100010172 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010173}
10174#endif /* HAVE_SYMLINK */
10175
Larry Hastings9cf065c2012-06-22 16:30:09 -070010176
Brian Curtind40e6f72010-07-08 21:39:08 +000010177
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010178
Larry Hastings605a62d2012-06-24 04:33:36 -070010179static PyStructSequence_Field times_result_fields[] = {
10180 {"user", "user time"},
10181 {"system", "system time"},
10182 {"children_user", "user time of children"},
10183 {"children_system", "system time of children"},
10184 {"elapsed", "elapsed time since an arbitrary point in the past"},
10185 {NULL}
10186};
10187
10188PyDoc_STRVAR(times_result__doc__,
10189"times_result: Result from os.times().\n\n\
10190This object may be accessed either as a tuple of\n\
10191 (user, system, children_user, children_system, elapsed),\n\
10192or via the attributes user, system, children_user, children_system,\n\
10193and elapsed.\n\
10194\n\
10195See os.times for more information.");
10196
10197static PyStructSequence_Desc times_result_desc = {
10198 "times_result", /* name */
10199 times_result__doc__, /* doc */
10200 times_result_fields,
10201 5
10202};
10203
10204static PyTypeObject TimesResultType;
10205
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010206#ifdef MS_WINDOWS
10207#define HAVE_TIMES /* mandatory, for the method table */
10208#endif
Larry Hastings605a62d2012-06-24 04:33:36 -070010209
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010210#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -070010211
10212static PyObject *
10213build_times_result(double user, double system,
10214 double children_user, double children_system,
10215 double elapsed)
10216{
10217 PyObject *value = PyStructSequence_New(&TimesResultType);
10218 if (value == NULL)
10219 return NULL;
10220
10221#define SET(i, field) \
10222 { \
10223 PyObject *o = PyFloat_FromDouble(field); \
10224 if (!o) { \
10225 Py_DECREF(value); \
10226 return NULL; \
10227 } \
10228 PyStructSequence_SET_ITEM(value, i, o); \
10229 } \
10230
10231 SET(0, user);
10232 SET(1, system);
10233 SET(2, children_user);
10234 SET(3, children_system);
10235 SET(4, elapsed);
10236
10237#undef SET
10238
10239 return value;
10240}
10241
Larry Hastings605a62d2012-06-24 04:33:36 -070010242
Larry Hastings2f936352014-08-05 14:04:04 +100010243#ifndef MS_WINDOWS
10244#define NEED_TICKS_PER_SECOND
10245static long ticks_per_second = -1;
10246#endif /* MS_WINDOWS */
10247
10248/*[clinic input]
10249os.times
10250
10251Return a collection containing process timing information.
10252
10253The object returned behaves like a named tuple with these fields:
10254 (utime, stime, cutime, cstime, elapsed_time)
10255All fields are floating point numbers.
10256[clinic start generated code]*/
10257
10258PyDoc_STRVAR(os_times__doc__,
10259"times($module, /)\n"
10260"--\n"
10261"\n"
10262"Return a collection containing process timing information.\n"
10263"\n"
10264"The object returned behaves like a named tuple with these fields:\n"
10265" (utime, stime, cutime, cstime, elapsed_time)\n"
10266"All fields are floating point numbers.");
10267
10268#define OS_TIMES_METHODDEF \
10269 {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__},
10270
Barry Warsaw53699e91996-12-10 23:23:01 +000010271static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010272os_times_impl(PyModuleDef *module);
10273
10274static PyObject *
10275os_times(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
10276{
10277 return os_times_impl(module);
10278}
10279
10280static PyObject *
10281os_times_impl(PyModuleDef *module)
10282/*[clinic end generated code: output=b86896d031a9b768 input=2bf9df3d6ab2e48b]*/
10283#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +000010284{
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 FILETIME create, exit, kernel, user;
10286 HANDLE hProc;
10287 hProc = GetCurrentProcess();
10288 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
10289 /* The fields of a FILETIME structure are the hi and lo part
10290 of a 64-bit value expressed in 100 nanosecond units.
10291 1e7 is one second in such units; 1e-7 the inverse.
10292 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
10293 */
Larry Hastings605a62d2012-06-24 04:33:36 -070010294 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 (double)(user.dwHighDateTime*429.4967296 +
10296 user.dwLowDateTime*1e-7),
10297 (double)(kernel.dwHighDateTime*429.4967296 +
10298 kernel.dwLowDateTime*1e-7),
10299 (double)0,
10300 (double)0,
10301 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000010302}
Larry Hastings2f936352014-08-05 14:04:04 +100010303#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010304{
Larry Hastings2f936352014-08-05 14:04:04 +100010305
10306
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010307 struct tms t;
10308 clock_t c;
10309 errno = 0;
10310 c = times(&t);
10311 if (c == (clock_t) -1)
10312 return posix_error();
10313 return build_times_result(
10314 (double)t.tms_utime / ticks_per_second,
10315 (double)t.tms_stime / ticks_per_second,
10316 (double)t.tms_cutime / ticks_per_second,
10317 (double)t.tms_cstime / ticks_per_second,
10318 (double)c / ticks_per_second);
10319}
Larry Hastings2f936352014-08-05 14:04:04 +100010320#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010321#endif /* HAVE_TIMES */
10322
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010323
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010324#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +100010325/*[clinic input]
10326os.getsid
10327
10328 pid: pid_t
10329 /
10330
10331Call the system call getsid(pid) and return the result.
10332[clinic start generated code]*/
10333
10334PyDoc_STRVAR(os_getsid__doc__,
10335"getsid($module, pid, /)\n"
10336"--\n"
10337"\n"
10338"Call the system call getsid(pid) and return the result.");
10339
10340#define OS_GETSID_METHODDEF \
10341 {"getsid", (PyCFunction)os_getsid, METH_VARARGS, os_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010342
10343static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010344os_getsid_impl(PyModuleDef *module, pid_t pid);
10345
10346static PyObject *
10347os_getsid(PyModuleDef *module, PyObject *args)
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010348{
Larry Hastings2f936352014-08-05 14:04:04 +100010349 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +100010351
10352 if (!PyArg_ParseTuple(args,
10353 "" _Py_PARSE_PID ":getsid",
10354 &pid))
10355 goto exit;
10356 return_value = os_getsid_impl(module, pid);
10357
10358exit:
10359 return return_value;
10360}
10361
10362static PyObject *
10363os_getsid_impl(PyModuleDef *module, pid_t pid)
10364/*[clinic end generated code: output=ea8390f395f4e0e1 input=eeb2b923a30ce04e]*/
10365{
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 sid = getsid(pid);
10368 if (sid < 0)
10369 return posix_error();
10370 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010371}
10372#endif /* HAVE_GETSID */
10373
10374
Guido van Rossumb6775db1994-08-01 11:34:53 +000010375#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +100010376/*[clinic input]
10377os.setsid
10378
10379Call the system call setsid().
10380[clinic start generated code]*/
10381
10382PyDoc_STRVAR(os_setsid__doc__,
10383"setsid($module, /)\n"
10384"--\n"
10385"\n"
10386"Call the system call setsid().");
10387
10388#define OS_SETSID_METHODDEF \
10389 {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010390
Barry Warsaw53699e91996-12-10 23:23:01 +000010391static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010392os_setsid_impl(PyModuleDef *module);
10393
10394static PyObject *
10395os_setsid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
10396{
10397 return os_setsid_impl(module);
10398}
10399
10400static PyObject *
10401os_setsid_impl(PyModuleDef *module)
10402/*[clinic end generated code: output=2a9a1435d8d764d5 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +000010403{
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 if (setsid() < 0)
10405 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010406 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +000010407}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010408#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +000010409
Larry Hastings2f936352014-08-05 14:04:04 +100010410
Guido van Rossumb6775db1994-08-01 11:34:53 +000010411#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +100010412/*[clinic input]
10413os.setpgid
10414
10415 pid: pid_t
10416 pgrp: pid_t
10417 /
10418
10419Call the system call setpgid(pid, pgrp).
10420[clinic start generated code]*/
10421
10422PyDoc_STRVAR(os_setpgid__doc__,
10423"setpgid($module, pid, pgrp, /)\n"
10424"--\n"
10425"\n"
10426"Call the system call setpgid(pid, pgrp).");
10427
10428#define OS_SETPGID_METHODDEF \
10429 {"setpgid", (PyCFunction)os_setpgid, METH_VARARGS, os_setpgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010430
Barry Warsaw53699e91996-12-10 23:23:01 +000010431static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010432os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp);
10433
10434static PyObject *
10435os_setpgid(PyModuleDef *module, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +000010436{
Larry Hastings2f936352014-08-05 14:04:04 +100010437 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +100010439 pid_t pgrp;
10440
10441 if (!PyArg_ParseTuple(args,
10442 "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid",
10443 &pid, &pgrp))
10444 goto exit;
10445 return_value = os_setpgid_impl(module, pid, pgrp);
10446
10447exit:
10448 return return_value;
10449}
10450
10451static PyObject *
10452os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
10453/*[clinic end generated code: output=7ad79b725f890e1f input=fceb395eca572e1a]*/
10454{
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 if (setpgid(pid, pgrp) < 0)
10456 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010457 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +000010458}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010459#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +000010460
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010461
Guido van Rossumb6775db1994-08-01 11:34:53 +000010462#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +100010463/*[clinic input]
10464os.tcgetpgrp
10465
10466 fd: int
10467 /
10468
10469Return the process group associated with the terminal specified by fd.
10470[clinic start generated code]*/
10471
10472PyDoc_STRVAR(os_tcgetpgrp__doc__,
10473"tcgetpgrp($module, fd, /)\n"
10474"--\n"
10475"\n"
10476"Return the process group associated with the terminal specified by fd.");
10477
10478#define OS_TCGETPGRP_METHODDEF \
10479 {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_VARARGS, os_tcgetpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010480
Barry Warsaw53699e91996-12-10 23:23:01 +000010481static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010482os_tcgetpgrp_impl(PyModuleDef *module, int fd);
10483
10484static PyObject *
10485os_tcgetpgrp(PyModuleDef *module, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +000010486{
Larry Hastings2f936352014-08-05 14:04:04 +100010487 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100010489
10490 if (!PyArg_ParseTuple(args,
10491 "i:tcgetpgrp",
10492 &fd))
10493 goto exit;
10494 return_value = os_tcgetpgrp_impl(module, fd);
10495
10496exit:
10497 return return_value;
10498}
10499
10500static PyObject *
10501os_tcgetpgrp_impl(PyModuleDef *module, int fd)
10502/*[clinic end generated code: output=abcf52ed4c8d22cb input=7f6c18eac10ada86]*/
10503{
10504 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 if (pgid < 0)
10506 return posix_error();
10507 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +000010508}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010509#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +000010510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010511
Guido van Rossumb6775db1994-08-01 11:34:53 +000010512#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +100010513/*[clinic input]
10514os.tcsetpgrp
10515
10516 fd: int
10517 pgid: pid_t
10518 /
10519
10520Set the process group associated with the terminal specified by fd.
10521[clinic start generated code]*/
10522
10523PyDoc_STRVAR(os_tcsetpgrp__doc__,
10524"tcsetpgrp($module, fd, pgid, /)\n"
10525"--\n"
10526"\n"
10527"Set the process group associated with the terminal specified by fd.");
10528
10529#define OS_TCSETPGRP_METHODDEF \
10530 {"tcsetpgrp", (PyCFunction)os_tcsetpgrp, METH_VARARGS, os_tcsetpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010531
Barry Warsaw53699e91996-12-10 23:23:01 +000010532static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010533os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid);
10534
10535static PyObject *
10536os_tcsetpgrp(PyModuleDef *module, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +000010537{
Larry Hastings2f936352014-08-05 14:04:04 +100010538 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 int fd;
10540 pid_t pgid;
Larry Hastings2f936352014-08-05 14:04:04 +100010541
10542 if (!PyArg_ParseTuple(args,
10543 "i" _Py_PARSE_PID ":tcsetpgrp",
10544 &fd, &pgid))
10545 goto exit;
10546 return_value = os_tcsetpgrp_impl(module, fd, pgid);
10547
10548exit:
10549 return return_value;
10550}
10551
10552static PyObject *
10553os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
10554/*[clinic end generated code: output=76f9bb8fd00f20f5 input=5bdc997c6a619020]*/
10555{
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 if (tcsetpgrp(fd, pgid) < 0)
10557 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010558 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +000010559}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010560#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +000010561
Guido van Rossum687dd131993-05-17 08:34:16 +000010562/* Functions acting on file descriptors */
10563
Victor Stinnerdaf45552013-08-28 00:53:59 +020010564#ifdef O_CLOEXEC
10565extern int _Py_open_cloexec_works;
10566#endif
10567
Larry Hastings2f936352014-08-05 14:04:04 +100010568
10569/*[clinic input]
10570os.open -> int
10571 path: path_t
10572 flags: int
10573 mode: int = 0o777
10574 *
10575 dir_fd: dir_fd(requires='openat') = None
10576
10577# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
10578
10579Open a file for low level IO. Returns a file descriptor (integer).
10580
10581If dir_fd is not None, it should be a file descriptor open to a directory,
10582 and path should be relative; path will then be relative to that directory.
10583dir_fd may not be implemented on your platform.
10584 If it is unavailable, using it will raise a NotImplementedError.
10585[clinic start generated code]*/
10586
10587PyDoc_STRVAR(os_open__doc__,
10588"open($module, /, path, flags, mode=511, *, dir_fd=None)\n"
10589"--\n"
10590"\n"
10591"Open a file for low level IO. Returns a file descriptor (integer).\n"
10592"\n"
10593"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
10594" and path should be relative; path will then be relative to that directory.\n"
10595"dir_fd may not be implemented on your platform.\n"
10596" If it is unavailable, using it will raise a NotImplementedError.");
10597
10598#define OS_OPEN_METHODDEF \
10599 {"open", (PyCFunction)os_open, METH_VARARGS|METH_KEYWORDS, os_open__doc__},
10600
10601static int
10602os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010603
Barry Warsaw53699e91996-12-10 23:23:01 +000010604static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010605os_open(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000010606{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010607 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010608 static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
10609 path_t path = PATH_T_INITIALIZE("open", "path", 0, 0);
10610 int flags;
10611 int mode = 511;
10612 int dir_fd = DEFAULT_DIR_FD;
10613 int _return_value;
10614
10615 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10616 "O&i|i$O&:open", _keywords,
10617 path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd))
10618 goto exit;
10619 _return_value = os_open_impl(module, &path, flags, mode, dir_fd);
10620 if ((_return_value == -1) && PyErr_Occurred())
10621 goto exit;
10622 return_value = PyLong_FromLong((long)_return_value);
10623
10624exit:
10625 /* Cleanup for path */
10626 path_cleanup(&path);
10627
10628 return return_value;
10629}
10630
10631static int
10632os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd)
10633/*[clinic end generated code: output=05b68fc4ed5e29c9 input=ad8623b29acd2934]*/
10634{
10635 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010636 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010637
Victor Stinnerdaf45552013-08-28 00:53:59 +020010638#ifdef O_CLOEXEC
10639 int *atomic_flag_works = &_Py_open_cloexec_works;
10640#elif !defined(MS_WINDOWS)
10641 int *atomic_flag_works = NULL;
10642#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +000010643
Victor Stinnerdaf45552013-08-28 00:53:59 +020010644#ifdef MS_WINDOWS
10645 flags |= O_NOINHERIT;
10646#elif defined(O_CLOEXEC)
10647 flags |= O_CLOEXEC;
10648#endif
10649
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010650 do {
10651 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010652#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010653 if (path->wide)
10654 fd = _wopen(path->wide, flags, mode);
10655 else
Larry Hastings9cf065c2012-06-22 16:30:09 -070010656#endif
10657#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010658 if (dir_fd != DEFAULT_DIR_FD)
10659 fd = openat(dir_fd, path->narrow, flags, mode);
10660 else
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010662 fd = open(path->narrow, flags, mode);
10663 Py_END_ALLOW_THREADS
10664 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Guido van Rossum687dd131993-05-17 08:34:16 +000010665
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 if (fd == -1) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010667 if (!async_err)
10668 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +100010669 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 }
10671
Victor Stinnerdaf45552013-08-28 00:53:59 +020010672#ifndef MS_WINDOWS
10673 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
10674 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +100010675 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010676 }
10677#endif
10678
Larry Hastings2f936352014-08-05 14:04:04 +100010679 return fd;
10680}
10681
10682
10683/*[clinic input]
10684os.close
10685
10686 fd: int
10687
10688Close a file descriptor.
10689[clinic start generated code]*/
10690
10691PyDoc_STRVAR(os_close__doc__,
10692"close($module, /, fd)\n"
10693"--\n"
10694"\n"
10695"Close a file descriptor.");
10696
10697#define OS_CLOSE_METHODDEF \
10698 {"close", (PyCFunction)os_close, METH_VARARGS|METH_KEYWORDS, os_close__doc__},
10699
10700static PyObject *
10701os_close_impl(PyModuleDef *module, int fd);
10702
10703static PyObject *
10704os_close(PyModuleDef *module, PyObject *args, PyObject *kwargs)
10705{
10706 PyObject *return_value = NULL;
10707 static char *_keywords[] = {"fd", NULL};
10708 int fd;
10709
10710 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10711 "i:close", _keywords,
10712 &fd))
10713 goto exit;
10714 return_value = os_close_impl(module, fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715
10716exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 return return_value;
10718}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010719
Barry Warsaw53699e91996-12-10 23:23:01 +000010720static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010721os_close_impl(PyModuleDef *module, int fd)
10722/*[clinic end generated code: output=927004e29ad55808 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010723{
Larry Hastings2f936352014-08-05 14:04:04 +100010724 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 if (!_PyVerify_fd(fd))
10726 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010727 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
10728 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
10729 * for more details.
10730 */
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 Py_BEGIN_ALLOW_THREADS
10732 res = close(fd);
10733 Py_END_ALLOW_THREADS
10734 if (res < 0)
10735 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010736 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +000010737}
10738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010739
Larry Hastings2f936352014-08-05 14:04:04 +100010740/*[clinic input]
10741os.closerange
10742
10743 fd_low: int
10744 fd_high: int
10745 /
10746
10747Closes all file descriptors in [fd_low, fd_high), ignoring errors.
10748[clinic start generated code]*/
10749
10750PyDoc_STRVAR(os_closerange__doc__,
10751"closerange($module, fd_low, fd_high, /)\n"
10752"--\n"
10753"\n"
10754"Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
10755
10756#define OS_CLOSERANGE_METHODDEF \
10757 {"closerange", (PyCFunction)os_closerange, METH_VARARGS, os_closerange__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +000010758
10759static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010760os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high);
10761
10762static PyObject *
10763os_closerange(PyModuleDef *module, PyObject *args)
Christian Heimesfdab48e2008-01-20 09:06:41 +000010764{
Larry Hastings2f936352014-08-05 14:04:04 +100010765 PyObject *return_value = NULL;
10766 int fd_low;
10767 int fd_high;
10768
10769 if (!PyArg_ParseTuple(args,
10770 "ii:closerange",
10771 &fd_low, &fd_high))
10772 goto exit;
10773 return_value = os_closerange_impl(module, fd_low, fd_high);
10774
10775exit:
10776 return return_value;
10777}
10778
10779static PyObject *
10780os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
10781/*[clinic end generated code: output=0a929ece386811c3 input=5855a3d053ebd4ec]*/
10782{
10783 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010785 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 if (_PyVerify_fd(i))
10787 close(i);
10788 Py_END_ALLOW_THREADS
10789 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +000010790}
10791
10792
Larry Hastings2f936352014-08-05 14:04:04 +100010793/*[clinic input]
10794os.dup -> int
10795
10796 fd: int
10797 /
10798
10799Return a duplicate of a file descriptor.
10800[clinic start generated code]*/
10801
10802PyDoc_STRVAR(os_dup__doc__,
10803"dup($module, fd, /)\n"
10804"--\n"
10805"\n"
10806"Return a duplicate of a file descriptor.");
10807
10808#define OS_DUP_METHODDEF \
10809 {"dup", (PyCFunction)os_dup, METH_VARARGS, os_dup__doc__},
10810
10811static int
10812os_dup_impl(PyModuleDef *module, int fd);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010813
Barry Warsaw53699e91996-12-10 23:23:01 +000010814static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010815os_dup(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000010816{
Larry Hastings2f936352014-08-05 14:04:04 +100010817 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100010819 int _return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010820
Larry Hastings2f936352014-08-05 14:04:04 +100010821 if (!PyArg_ParseTuple(args,
10822 "i:dup",
10823 &fd))
10824 goto exit;
10825 _return_value = os_dup_impl(module, fd);
10826 if ((_return_value == -1) && PyErr_Occurred())
10827 goto exit;
10828 return_value = PyLong_FromLong((long)_return_value);
Tim Golden23005082013-10-25 11:22:37 +010010829
Larry Hastings2f936352014-08-05 14:04:04 +100010830exit:
10831 return return_value;
10832}
Victor Stinnerdaf45552013-08-28 00:53:59 +020010833
Larry Hastings2f936352014-08-05 14:04:04 +100010834static int
10835os_dup_impl(PyModuleDef *module, int fd)
10836/*[clinic end generated code: output=75943e057b25e1bd input=6f10f7ea97f7852a]*/
10837{
10838 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +000010839}
10840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010841
Larry Hastings2f936352014-08-05 14:04:04 +100010842/*[clinic input]
10843os.dup2
10844 fd: int
10845 fd2: int
10846 inheritable: bool=True
10847
10848Duplicate file descriptor.
10849[clinic start generated code]*/
10850
10851PyDoc_STRVAR(os_dup2__doc__,
10852"dup2($module, /, fd, fd2, inheritable=True)\n"
10853"--\n"
10854"\n"
10855"Duplicate file descriptor.");
10856
10857#define OS_DUP2_METHODDEF \
10858 {"dup2", (PyCFunction)os_dup2, METH_VARARGS|METH_KEYWORDS, os_dup2__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010859
Barry Warsaw53699e91996-12-10 23:23:01 +000010860static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010861os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable);
10862
10863static PyObject *
10864os_dup2(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000010865{
Larry Hastings2f936352014-08-05 14:04:04 +100010866 PyObject *return_value = NULL;
10867 static char *_keywords[] = {"fd", "fd2", "inheritable", NULL};
10868 int fd;
10869 int fd2;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010870 int inheritable = 1;
Larry Hastings2f936352014-08-05 14:04:04 +100010871
10872 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10873 "ii|p:dup2", _keywords,
10874 &fd, &fd2, &inheritable))
10875 goto exit;
10876 return_value = os_dup2_impl(module, fd, fd2, inheritable);
10877
10878exit:
10879 return return_value;
10880}
10881
10882static PyObject *
10883os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
10884/*[clinic end generated code: output=531e482dd11a99a0 input=76e96f511be0352f]*/
10885{
Victor Stinnerdaf45552013-08-28 00:53:59 +020010886 int res;
10887#if defined(HAVE_DUP3) && \
10888 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
10889 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
10890 int dup3_works = -1;
10891#endif
10892
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 if (!_PyVerify_fd_dup2(fd, fd2))
10894 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +020010895
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010896 /* dup2() can fail with EINTR if the target FD is already open, because it
10897 * then has to be closed. See os_close_impl() for why we don't handle EINTR
10898 * upon close(), and therefore below.
10899 */
Victor Stinnerdaf45552013-08-28 00:53:59 +020010900#ifdef MS_WINDOWS
10901 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010903 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 if (res < 0)
10905 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +020010906
10907 /* Character files like console cannot be make non-inheritable */
10908 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
10909 close(fd2);
10910 return NULL;
10911 }
10912
10913#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
10914 Py_BEGIN_ALLOW_THREADS
10915 if (!inheritable)
10916 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
10917 else
10918 res = dup2(fd, fd2);
10919 Py_END_ALLOW_THREADS
10920 if (res < 0)
10921 return posix_error();
10922
10923#else
10924
10925#ifdef HAVE_DUP3
10926 if (!inheritable && dup3_works != 0) {
10927 Py_BEGIN_ALLOW_THREADS
10928 res = dup3(fd, fd2, O_CLOEXEC);
10929 Py_END_ALLOW_THREADS
10930 if (res < 0) {
10931 if (dup3_works == -1)
10932 dup3_works = (errno != ENOSYS);
10933 if (dup3_works)
10934 return posix_error();
10935 }
10936 }
10937
10938 if (inheritable || dup3_works == 0)
10939 {
10940#endif
10941 Py_BEGIN_ALLOW_THREADS
10942 res = dup2(fd, fd2);
10943 Py_END_ALLOW_THREADS
10944 if (res < 0)
10945 return posix_error();
10946
10947 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
10948 close(fd2);
10949 return NULL;
10950 }
10951#ifdef HAVE_DUP3
10952 }
10953#endif
10954
10955#endif
10956
Larry Hastings2f936352014-08-05 14:04:04 +100010957 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +000010958}
10959
Larry Hastings2f936352014-08-05 14:04:04 +100010960
Ross Lagerwall7807c352011-03-17 20:20:30 +020010961#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +100010962/*[clinic input]
10963os.lockf
10964
10965 fd: int
10966 An open file descriptor.
10967 command: int
10968 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
10969 length: Py_off_t
10970 The number of bytes to lock, starting at the current position.
10971 /
10972
10973Apply, test or remove a POSIX lock on an open file descriptor.
10974
10975[clinic start generated code]*/
10976
10977PyDoc_STRVAR(os_lockf__doc__,
10978"lockf($module, fd, command, length, /)\n"
10979"--\n"
10980"\n"
10981"Apply, test or remove a POSIX lock on an open file descriptor.\n"
10982"\n"
10983" fd\n"
10984" An open file descriptor.\n"
10985" command\n"
10986" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n"
10987" length\n"
10988" The number of bytes to lock, starting at the current position.");
10989
10990#define OS_LOCKF_METHODDEF \
10991 {"lockf", (PyCFunction)os_lockf, METH_VARARGS, os_lockf__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010992
10993static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010994os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length);
10995
10996static PyObject *
10997os_lockf(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020010998{
Larry Hastings2f936352014-08-05 14:04:04 +100010999 PyObject *return_value = NULL;
11000 int fd;
11001 int command;
11002 Py_off_t length;
11003
11004 if (!PyArg_ParseTuple(args,
11005 "iiO&:lockf",
11006 &fd, &command, Py_off_t_converter, &length))
11007 goto exit;
11008 return_value = os_lockf_impl(module, fd, command, length);
11009
11010exit:
11011 return return_value;
11012}
11013
11014static PyObject *
11015os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
11016/*[clinic end generated code: output=1b28346ac7335c0f input=65da41d2106e9b79]*/
11017{
11018 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011019
11020 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011021 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011022 Py_END_ALLOW_THREADS
11023
11024 if (res < 0)
11025 return posix_error();
11026
11027 Py_RETURN_NONE;
11028}
Larry Hastings2f936352014-08-05 14:04:04 +100011029#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011031
Larry Hastings2f936352014-08-05 14:04:04 +100011032/*[clinic input]
11033os.lseek -> Py_off_t
11034
11035 fd: int
11036 position: Py_off_t
11037 how: int
11038 /
11039
11040Set the position of a file descriptor. Return the new position.
11041
11042Return the new cursor position in number of bytes
11043relative to the beginning of the file.
11044[clinic start generated code]*/
11045
11046PyDoc_STRVAR(os_lseek__doc__,
11047"lseek($module, fd, position, how, /)\n"
11048"--\n"
11049"\n"
11050"Set the position of a file descriptor. Return the new position.\n"
11051"\n"
11052"Return the new cursor position in number of bytes\n"
11053"relative to the beginning of the file.");
11054
11055#define OS_LSEEK_METHODDEF \
11056 {"lseek", (PyCFunction)os_lseek, METH_VARARGS, os_lseek__doc__},
11057
11058static Py_off_t
11059os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011060
Barry Warsaw53699e91996-12-10 23:23:01 +000011061static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011062os_lseek(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000011063{
Larry Hastings2f936352014-08-05 14:04:04 +100011064 PyObject *return_value = NULL;
11065 int fd;
11066 Py_off_t position;
11067 int how;
11068 Py_off_t _return_value;
11069
11070 if (!PyArg_ParseTuple(args,
11071 "iO&i:lseek",
11072 &fd, Py_off_t_converter, &position, &how))
11073 goto exit;
11074 _return_value = os_lseek_impl(module, fd, position, how);
11075 if ((_return_value == -1) && PyErr_Occurred())
11076 goto exit;
11077 return_value = PyLong_FromPy_off_t(_return_value);
11078
11079exit:
11080 return return_value;
11081}
11082
11083static Py_off_t
11084os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
11085/*[clinic end generated code: output=88cfc146f55667af input=902654ad3f96a6d3]*/
11086{
11087 Py_off_t result;
11088
11089 if (!_PyVerify_fd(fd)) {
11090 posix_error();
11091 return -1;
11092 }
Guido van Rossum687dd131993-05-17 08:34:16 +000011093#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
11095 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +100011096 case 0: how = SEEK_SET; break;
11097 case 1: how = SEEK_CUR; break;
11098 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011100#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011101
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100011103 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +000011104
Larry Hastings2f936352014-08-05 14:04:04 +100011105 if (!_PyVerify_fd(fd)) {
11106 posix_error();
11107 return -1;
11108 }
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +020011110#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011111 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +000011112#else
Larry Hastings2f936352014-08-05 14:04:04 +100011113 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +000011114#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011116 if (result < 0)
11117 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +000011118
Larry Hastings2f936352014-08-05 14:04:04 +100011119 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +000011120}
11121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011122
Larry Hastings2f936352014-08-05 14:04:04 +100011123/*[clinic input]
11124os.read
11125 fd: int
11126 length: Py_ssize_t
11127 /
11128
11129Read from a file descriptor. Returns a bytes object.
11130[clinic start generated code]*/
11131
11132PyDoc_STRVAR(os_read__doc__,
11133"read($module, fd, length, /)\n"
11134"--\n"
11135"\n"
11136"Read from a file descriptor. Returns a bytes object.");
11137
11138#define OS_READ_METHODDEF \
11139 {"read", (PyCFunction)os_read, METH_VARARGS, os_read__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011140
Barry Warsaw53699e91996-12-10 23:23:01 +000011141static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011142os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length);
11143
11144static PyObject *
11145os_read(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000011146{
Larry Hastings2f936352014-08-05 14:04:04 +100011147 PyObject *return_value = NULL;
Victor Stinnerb28ed922014-07-11 17:04:41 +020011148 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011149 Py_ssize_t length;
11150
11151 if (!PyArg_ParseTuple(args,
11152 "in:read",
11153 &fd, &length))
11154 goto exit;
11155 return_value = os_read_impl(module, fd, length);
11156
11157exit:
11158 return return_value;
11159}
11160
11161static PyObject *
11162os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
11163/*[clinic end generated code: output=1f3bc27260a24968 input=1df2eaa27c0bf1d3]*/
11164{
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 Py_ssize_t n;
11166 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +100011167
11168 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 errno = EINVAL;
11170 return posix_error();
11171 }
Larry Hastings2f936352014-08-05 14:04:04 +100011172
11173#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +010011174 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +100011175 if (length > INT_MAX)
11176 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +100011177#endif
11178
11179 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 if (buffer == NULL)
11181 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011182
Victor Stinner66aab0c2015-03-19 22:53:20 +010011183 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
11184 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +010011186 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 }
Larry Hastings2f936352014-08-05 14:04:04 +100011188
11189 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +100011191
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +000011193}
11194
Ross Lagerwall7807c352011-03-17 20:20:30 +020011195#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
11196 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011197static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011198iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
11199{
11200 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011201 Py_ssize_t blen, total = 0;
11202
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011203 *iov = PyMem_New(struct iovec, cnt);
11204 if (*iov == NULL) {
11205 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +010011206 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011207 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011208
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011209 *buf = PyMem_New(Py_buffer, cnt);
11210 if (*buf == NULL) {
11211 PyMem_Del(*iov);
11212 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +010011213 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011214 }
11215
11216 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011217 PyObject *item = PySequence_GetItem(seq, i);
11218 if (item == NULL)
11219 goto fail;
11220 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
11221 Py_DECREF(item);
11222 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011223 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011224 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011225 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011226 blen = (*buf)[i].len;
11227 (*iov)[i].iov_len = blen;
11228 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011229 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011230 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011231
11232fail:
11233 PyMem_Del(*iov);
11234 for (j = 0; j < i; j++) {
11235 PyBuffer_Release(&(*buf)[j]);
11236 }
11237 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +010011238 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011239}
11240
11241static void
11242iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
11243{
11244 int i;
11245 PyMem_Del(iov);
11246 for (i = 0; i < cnt; i++) {
11247 PyBuffer_Release(&buf[i]);
11248 }
11249 PyMem_Del(buf);
11250}
11251#endif
11252
Larry Hastings2f936352014-08-05 14:04:04 +100011253
Ross Lagerwall7807c352011-03-17 20:20:30 +020011254#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +100011255/*[clinic input]
11256os.readv -> Py_ssize_t
11257
11258 fd: int
11259 buffers: object
11260 /
11261
11262Read from a file descriptor fd into an iterable of buffers.
11263
11264The buffers should be mutable buffers accepting bytes.
11265readv will transfer data into each buffer until it is full
11266and then move on to the next buffer in the sequence to hold
11267the rest of the data.
11268
11269readv returns the total number of bytes read,
11270which may be less than the total capacity of all the buffers.
11271[clinic start generated code]*/
11272
11273PyDoc_STRVAR(os_readv__doc__,
11274"readv($module, fd, buffers, /)\n"
11275"--\n"
11276"\n"
11277"Read from a file descriptor fd into an iterable of buffers.\n"
11278"\n"
11279"The buffers should be mutable buffers accepting bytes.\n"
11280"readv will transfer data into each buffer until it is full\n"
11281"and then move on to the next buffer in the sequence to hold\n"
11282"the rest of the data.\n"
11283"\n"
11284"readv returns the total number of bytes read,\n"
11285"which may be less than the total capacity of all the buffers.");
11286
11287#define OS_READV_METHODDEF \
11288 {"readv", (PyCFunction)os_readv, METH_VARARGS, os_readv__doc__},
11289
11290static Py_ssize_t
11291os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011292
11293static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011294os_readv(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011295{
Larry Hastings2f936352014-08-05 14:04:04 +100011296 PyObject *return_value = NULL;
11297 int fd;
11298 PyObject *buffers;
11299 Py_ssize_t _return_value;
11300
11301 if (!PyArg_ParseTuple(args,
11302 "iO:readv",
11303 &fd, &buffers))
11304 goto exit;
11305 _return_value = os_readv_impl(module, fd, buffers);
11306 if ((_return_value == -1) && PyErr_Occurred())
11307 goto exit;
11308 return_value = PyLong_FromSsize_t(_return_value);
11309
11310exit:
11311 return return_value;
11312}
11313
11314static Py_ssize_t
11315os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
11316/*[clinic end generated code: output=72748b1c32a6e2a1 input=e679eb5dbfa0357d]*/
11317{
11318 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011319 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011320 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011321 struct iovec *iov;
11322 Py_buffer *buf;
11323
Larry Hastings2f936352014-08-05 14:04:04 +100011324 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011325 PyErr_SetString(PyExc_TypeError,
11326 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100011327 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011328 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011329
Larry Hastings2f936352014-08-05 14:04:04 +100011330 cnt = PySequence_Size(buffers);
11331
11332 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
11333 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011334
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011335 do {
11336 Py_BEGIN_ALLOW_THREADS
11337 n = readv(fd, iov, cnt);
11338 Py_END_ALLOW_THREADS
11339 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020011340
11341 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +100011342 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011343 if (!async_err)
11344 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100011345 return -1;
11346 }
Victor Stinner57ddf782014-01-08 15:21:28 +010011347
Larry Hastings2f936352014-08-05 14:04:04 +100011348 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011349}
Larry Hastings2f936352014-08-05 14:04:04 +100011350#endif /* HAVE_READV */
11351
Ross Lagerwall7807c352011-03-17 20:20:30 +020011352
11353#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +100011354/*[clinic input]
11355# TODO length should be size_t! but Python doesn't support parsing size_t yet.
11356os.pread
11357
11358 fd: int
11359 length: int
11360 offset: Py_off_t
11361 /
11362
11363Read a number of bytes from a file descriptor starting at a particular offset.
11364
11365Read length bytes from file descriptor fd, starting at offset bytes from
11366the beginning of the file. The file offset remains unchanged.
11367[clinic start generated code]*/
11368
11369PyDoc_STRVAR(os_pread__doc__,
11370"pread($module, fd, length, offset, /)\n"
11371"--\n"
11372"\n"
11373"Read a number of bytes from a file descriptor starting at a particular offset.\n"
11374"\n"
11375"Read length bytes from file descriptor fd, starting at offset bytes from\n"
11376"the beginning of the file. The file offset remains unchanged.");
11377
11378#define OS_PREAD_METHODDEF \
11379 {"pread", (PyCFunction)os_pread, METH_VARARGS, os_pread__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011380
11381static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011382os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset);
11383
11384static PyObject *
11385os_pread(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011386{
Larry Hastings2f936352014-08-05 14:04:04 +100011387 PyObject *return_value = NULL;
11388 int fd;
11389 int length;
11390 Py_off_t offset;
11391
11392 if (!PyArg_ParseTuple(args,
11393 "iiO&:pread",
11394 &fd, &length, Py_off_t_converter, &offset))
11395 goto exit;
11396 return_value = os_pread_impl(module, fd, length, offset);
11397
11398exit:
11399 return return_value;
11400}
11401
11402static PyObject *
11403os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
11404/*[clinic end generated code: output=7b62bf6c06e20ae8 input=084948dcbaa35d4c]*/
11405{
Ross Lagerwall7807c352011-03-17 20:20:30 +020011406 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011407 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011408 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011409
Larry Hastings2f936352014-08-05 14:04:04 +100011410 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011411 errno = EINVAL;
11412 return posix_error();
11413 }
Larry Hastings2f936352014-08-05 14:04:04 +100011414 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011415 if (buffer == NULL)
11416 return NULL;
11417 if (!_PyVerify_fd(fd)) {
11418 Py_DECREF(buffer);
11419 return posix_error();
11420 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011421
11422 do {
11423 Py_BEGIN_ALLOW_THREADS
11424 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
11425 Py_END_ALLOW_THREADS
11426 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
11427
Ross Lagerwall7807c352011-03-17 20:20:30 +020011428 if (n < 0) {
11429 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011430 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011431 }
Larry Hastings2f936352014-08-05 14:04:04 +100011432 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011433 _PyBytes_Resize(&buffer, n);
11434 return buffer;
11435}
Larry Hastings2f936352014-08-05 14:04:04 +100011436#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011437
Larry Hastings2f936352014-08-05 14:04:04 +100011438
11439/*[clinic input]
11440os.write -> Py_ssize_t
11441
11442 fd: int
11443 data: Py_buffer
11444 /
11445
11446Write a bytes object to a file descriptor.
11447[clinic start generated code]*/
11448
11449PyDoc_STRVAR(os_write__doc__,
11450"write($module, fd, data, /)\n"
11451"--\n"
11452"\n"
11453"Write a bytes object to a file descriptor.");
11454
11455#define OS_WRITE_METHODDEF \
11456 {"write", (PyCFunction)os_write, METH_VARARGS, os_write__doc__},
11457
11458static Py_ssize_t
11459os_write_impl(PyModuleDef *module, int fd, Py_buffer *data);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011460
11461static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011462os_write(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011463{
Larry Hastings2f936352014-08-05 14:04:04 +100011464 PyObject *return_value = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011465 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011466 Py_buffer data = {NULL, NULL};
11467 Py_ssize_t _return_value;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011468
Larry Hastings2f936352014-08-05 14:04:04 +100011469 if (!PyArg_ParseTuple(args,
11470 "iy*:write",
11471 &fd, &data))
11472 goto exit;
11473 _return_value = os_write_impl(module, fd, &data);
11474 if ((_return_value == -1) && PyErr_Occurred())
11475 goto exit;
11476 return_value = PyLong_FromSsize_t(_return_value);
11477
11478exit:
11479 /* Cleanup for data */
11480 if (data.obj)
11481 PyBuffer_Release(&data);
11482
11483 return return_value;
11484}
11485
11486static Py_ssize_t
11487os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
11488/*[clinic end generated code: output=aeb96acfdd4d5112 input=3207e28963234f3c]*/
11489{
Victor Stinner66aab0c2015-03-19 22:53:20 +010011490 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011491}
11492
11493#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011494PyDoc_STRVAR(posix_sendfile__doc__,
11495"sendfile(out, in, offset, nbytes) -> byteswritten\n\
11496sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
11497 -> byteswritten\n\
11498Copy nbytes bytes from file descriptor in to file descriptor out.");
11499
Larry Hastings2f936352014-08-05 14:04:04 +100011500/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011501static PyObject *
11502posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
11503{
11504 int in, out;
11505 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011506 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011507 off_t offset;
11508
11509#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
11510#ifndef __APPLE__
11511 Py_ssize_t len;
11512#endif
11513 PyObject *headers = NULL, *trailers = NULL;
11514 Py_buffer *hbuf, *tbuf;
11515 off_t sbytes;
11516 struct sf_hdtr sf;
11517 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +000011518 static char *keywords[] = {"out", "in",
11519 "offset", "count",
11520 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011521
Victor Stinner6ce0dbf2013-07-07 16:32:36 +020011522 sf.headers = NULL;
11523 sf.trailers = NULL;
11524
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011525#ifdef __APPLE__
11526 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +100011527 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011528#else
11529 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +100011530 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011531#endif
11532 &headers, &trailers, &flags))
11533 return NULL;
11534 if (headers != NULL) {
11535 if (!PySequence_Check(headers)) {
11536 PyErr_SetString(PyExc_TypeError,
11537 "sendfile() headers must be a sequence or None");
11538 return NULL;
11539 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011540 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011541 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011542 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +010011543 (i = iov_setup(&(sf.headers), &hbuf,
11544 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011545 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011546#ifdef __APPLE__
11547 sbytes += i;
11548#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011549 }
11550 }
11551 if (trailers != NULL) {
11552 if (!PySequence_Check(trailers)) {
11553 PyErr_SetString(PyExc_TypeError,
11554 "sendfile() trailers must be a sequence or None");
11555 return NULL;
11556 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011557 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011558 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011559 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +010011560 (i = iov_setup(&(sf.trailers), &tbuf,
11561 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011562 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011563#ifdef __APPLE__
11564 sbytes += i;
11565#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011566 }
11567 }
11568
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011569 do {
11570 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011571#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011572 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011573#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011574 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011575#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011576 Py_END_ALLOW_THREADS
11577 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011578
11579 if (sf.headers != NULL)
11580 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
11581 if (sf.trailers != NULL)
11582 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
11583
11584 if (ret < 0) {
11585 if ((errno == EAGAIN) || (errno == EBUSY)) {
11586 if (sbytes != 0) {
11587 // some data has been sent
11588 goto done;
11589 }
11590 else {
11591 // no data has been sent; upper application is supposed
11592 // to retry on EAGAIN or EBUSY
11593 return posix_error();
11594 }
11595 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011596 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011597 }
11598 goto done;
11599
11600done:
11601 #if !defined(HAVE_LARGEFILE_SUPPORT)
11602 return Py_BuildValue("l", sbytes);
11603 #else
11604 return Py_BuildValue("L", sbytes);
11605 #endif
11606
11607#else
11608 Py_ssize_t count;
11609 PyObject *offobj;
11610 static char *keywords[] = {"out", "in",
11611 "offset", "count", NULL};
11612 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
11613 keywords, &out, &in, &offobj, &count))
11614 return NULL;
11615#ifdef linux
11616 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011617 do {
11618 Py_BEGIN_ALLOW_THREADS
11619 ret = sendfile(out, in, NULL, count);
11620 Py_END_ALLOW_THREADS
11621 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011622 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011623 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +020011624 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011625 }
11626#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011627 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +000011628 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011629
11630 do {
11631 Py_BEGIN_ALLOW_THREADS
11632 ret = sendfile(out, in, &offset, count);
11633 Py_END_ALLOW_THREADS
11634 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011635 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011636 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011637 return Py_BuildValue("n", ret);
11638#endif
11639}
Larry Hastings2f936352014-08-05 14:04:04 +100011640#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011641
Larry Hastings2f936352014-08-05 14:04:04 +100011642
11643/*[clinic input]
11644os.fstat
11645
11646 fd : int
11647
11648Perform a stat system call on the given file descriptor.
11649
11650Like stat(), but for an open file descriptor.
11651Equivalent to os.stat(fd).
11652[clinic start generated code]*/
11653
11654PyDoc_STRVAR(os_fstat__doc__,
11655"fstat($module, /, fd)\n"
11656"--\n"
11657"\n"
11658"Perform a stat system call on the given file descriptor.\n"
11659"\n"
11660"Like stat(), but for an open file descriptor.\n"
11661"Equivalent to os.stat(fd).");
11662
11663#define OS_FSTAT_METHODDEF \
11664 {"fstat", (PyCFunction)os_fstat, METH_VARARGS|METH_KEYWORDS, os_fstat__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011665
Barry Warsaw53699e91996-12-10 23:23:01 +000011666static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011667os_fstat_impl(PyModuleDef *module, int fd);
11668
11669static PyObject *
11670os_fstat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000011671{
Larry Hastings2f936352014-08-05 14:04:04 +100011672 PyObject *return_value = NULL;
11673 static char *_keywords[] = {"fd", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011675
11676 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
11677 "i:fstat", _keywords,
11678 &fd))
11679 goto exit;
11680 return_value = os_fstat_impl(module, fd);
11681
11682exit:
11683 return return_value;
11684}
11685
11686static PyObject *
11687os_fstat_impl(PyModuleDef *module, int fd)
11688/*[clinic end generated code: output=dae4a9678c7bd881 input=27e0e0ebbe5600c9]*/
11689{
Victor Stinner8c62be82010-05-06 00:08:46 +000011690 STRUCT_STAT st;
11691 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011692 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100011693
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011694 do {
11695 Py_BEGIN_ALLOW_THREADS
11696 res = FSTAT(fd, &st);
11697 Py_END_ALLOW_THREADS
11698 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +000011699 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +000011700#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +010011701 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +000011702#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011703 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +000011704#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011705 }
Tim Peters5aa91602002-01-30 05:46:57 +000011706
Victor Stinner4195b5c2012-02-08 23:03:19 +010011707 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +000011708}
11709
Larry Hastings2f936352014-08-05 14:04:04 +100011710
11711/*[clinic input]
11712os.isatty -> bool
11713 fd: int
11714 /
11715
11716Return True if the fd is connected to a terminal.
11717
11718Return True if the file descriptor is an open file descriptor
11719connected to the slave end of a terminal.
11720[clinic start generated code]*/
11721
11722PyDoc_STRVAR(os_isatty__doc__,
11723"isatty($module, fd, /)\n"
11724"--\n"
11725"\n"
11726"Return True if the fd is connected to a terminal.\n"
11727"\n"
11728"Return True if the file descriptor is an open file descriptor\n"
11729"connected to the slave end of a terminal.");
11730
11731#define OS_ISATTY_METHODDEF \
11732 {"isatty", (PyCFunction)os_isatty, METH_VARARGS, os_isatty__doc__},
11733
11734static int
11735os_isatty_impl(PyModuleDef *module, int fd);
Skip Montanaro1517d842000-07-19 14:34:14 +000011736
11737static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011738os_isatty(PyModuleDef *module, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +000011739{
Larry Hastings2f936352014-08-05 14:04:04 +100011740 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011741 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011742 int _return_value;
11743
11744 if (!PyArg_ParseTuple(args,
11745 "i:isatty",
11746 &fd))
11747 goto exit;
11748 _return_value = os_isatty_impl(module, fd);
11749 if ((_return_value == -1) && PyErr_Occurred())
11750 goto exit;
11751 return_value = PyBool_FromLong((long)_return_value);
11752
11753exit:
11754 return return_value;
Skip Montanaro1517d842000-07-19 14:34:14 +000011755}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011756
Larry Hastings2f936352014-08-05 14:04:04 +100011757static int
11758os_isatty_impl(PyModuleDef *module, int fd)
11759/*[clinic end generated code: output=4bfadbfe22715097 input=08ce94aa1eaf7b5e]*/
11760{
11761 if (!_PyVerify_fd(fd))
11762 return 0;
11763 return isatty(fd);
11764}
11765
11766
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011767#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100011768/*[clinic input]
11769os.pipe
11770
11771Create a pipe.
11772
11773Returns a tuple of two file descriptors:
11774 (read_fd, write_fd)
11775[clinic start generated code]*/
11776
11777PyDoc_STRVAR(os_pipe__doc__,
11778"pipe($module, /)\n"
11779"--\n"
11780"\n"
11781"Create a pipe.\n"
11782"\n"
11783"Returns a tuple of two file descriptors:\n"
11784" (read_fd, write_fd)");
11785
11786#define OS_PIPE_METHODDEF \
11787 {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011788
Barry Warsaw53699e91996-12-10 23:23:01 +000011789static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011790os_pipe_impl(PyModuleDef *module);
11791
11792static PyObject *
11793os_pipe(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
11794{
11795 return os_pipe_impl(module);
11796}
11797
11798static PyObject *
11799os_pipe_impl(PyModuleDef *module)
11800/*[clinic end generated code: output=0da2479f2266e774 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000011801{
Victor Stinner8c62be82010-05-06 00:08:46 +000011802 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020011803#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011804 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011805 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000011806 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011807#else
11808 int res;
11809#endif
11810
11811#ifdef MS_WINDOWS
11812 attr.nLength = sizeof(attr);
11813 attr.lpSecurityDescriptor = NULL;
11814 attr.bInheritHandle = FALSE;
11815
11816 Py_BEGIN_ALLOW_THREADS
11817 ok = CreatePipe(&read, &write, &attr, 0);
11818 if (ok) {
11819 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
11820 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
11821 if (fds[0] == -1 || fds[1] == -1) {
11822 CloseHandle(read);
11823 CloseHandle(write);
11824 ok = 0;
11825 }
11826 }
11827 Py_END_ALLOW_THREADS
11828
Victor Stinner8c62be82010-05-06 00:08:46 +000011829 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010011830 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020011831#else
11832
11833#ifdef HAVE_PIPE2
11834 Py_BEGIN_ALLOW_THREADS
11835 res = pipe2(fds, O_CLOEXEC);
11836 Py_END_ALLOW_THREADS
11837
11838 if (res != 0 && errno == ENOSYS)
11839 {
11840#endif
11841 Py_BEGIN_ALLOW_THREADS
11842 res = pipe(fds);
11843 Py_END_ALLOW_THREADS
11844
11845 if (res == 0) {
11846 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
11847 close(fds[0]);
11848 close(fds[1]);
11849 return NULL;
11850 }
11851 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
11852 close(fds[0]);
11853 close(fds[1]);
11854 return NULL;
11855 }
11856 }
11857#ifdef HAVE_PIPE2
11858 }
11859#endif
11860
11861 if (res != 0)
11862 return PyErr_SetFromErrno(PyExc_OSError);
11863#endif /* !MS_WINDOWS */
11864 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000011865}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011866#endif /* HAVE_PIPE */
11867
Larry Hastings2f936352014-08-05 14:04:04 +100011868
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011869#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100011870/*[clinic input]
11871os.pipe2
11872
11873 flags: int
11874 /
11875
11876Create a pipe with flags set atomically.
11877
11878Returns a tuple of two file descriptors:
11879 (read_fd, write_fd)
11880
11881flags can be constructed by ORing together one or more of these values:
11882O_NONBLOCK, O_CLOEXEC.
11883[clinic start generated code]*/
11884
11885PyDoc_STRVAR(os_pipe2__doc__,
11886"pipe2($module, flags, /)\n"
11887"--\n"
11888"\n"
11889"Create a pipe with flags set atomically.\n"
11890"\n"
11891"Returns a tuple of two file descriptors:\n"
11892" (read_fd, write_fd)\n"
11893"\n"
11894"flags can be constructed by ORing together one or more of these values:\n"
11895"O_NONBLOCK, O_CLOEXEC.");
11896
11897#define OS_PIPE2_METHODDEF \
11898 {"pipe2", (PyCFunction)os_pipe2, METH_VARARGS, os_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011899
11900static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011901os_pipe2_impl(PyModuleDef *module, int flags);
11902
11903static PyObject *
11904os_pipe2(PyModuleDef *module, PyObject *args)
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011905{
Larry Hastings2f936352014-08-05 14:04:04 +100011906 PyObject *return_value = NULL;
Charles-François Natali368f34b2011-06-06 19:49:47 +020011907 int flags;
Larry Hastings2f936352014-08-05 14:04:04 +100011908
11909 if (!PyArg_ParseTuple(args,
11910 "i:pipe2",
11911 &flags))
11912 goto exit;
11913 return_value = os_pipe2_impl(module, flags);
11914
11915exit:
11916 return return_value;
11917}
11918
11919static PyObject *
11920os_pipe2_impl(PyModuleDef *module, int flags)
11921/*[clinic end generated code: output=9e27c799ce19220b input=f261b6e7e63c6817]*/
11922{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011923 int fds[2];
11924 int res;
11925
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011926 res = pipe2(fds, flags);
11927 if (res != 0)
11928 return posix_error();
11929 return Py_BuildValue("(ii)", fds[0], fds[1]);
11930}
11931#endif /* HAVE_PIPE2 */
11932
Larry Hastings2f936352014-08-05 14:04:04 +100011933
Ross Lagerwall7807c352011-03-17 20:20:30 +020011934#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100011935/*[clinic input]
11936os.writev -> Py_ssize_t
11937 fd: int
11938 buffers: object
11939 /
11940
11941Iterate over buffers, and write the contents of each to a file descriptor.
11942
11943Returns the total number of bytes written.
11944buffers must be a sequence of bytes-like objects.
11945[clinic start generated code]*/
11946
11947PyDoc_STRVAR(os_writev__doc__,
11948"writev($module, fd, buffers, /)\n"
11949"--\n"
11950"\n"
11951"Iterate over buffers, and write the contents of each to a file descriptor.\n"
11952"\n"
11953"Returns the total number of bytes written.\n"
11954"buffers must be a sequence of bytes-like objects.");
11955
11956#define OS_WRITEV_METHODDEF \
11957 {"writev", (PyCFunction)os_writev, METH_VARARGS, os_writev__doc__},
11958
11959static Py_ssize_t
11960os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011961
11962static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011963os_writev(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011964{
Larry Hastings2f936352014-08-05 14:04:04 +100011965 PyObject *return_value = NULL;
11966 int fd;
11967 PyObject *buffers;
11968 Py_ssize_t _return_value;
11969
11970 if (!PyArg_ParseTuple(args,
11971 "iO:writev",
11972 &fd, &buffers))
11973 goto exit;
11974 _return_value = os_writev_impl(module, fd, buffers);
11975 if ((_return_value == -1) && PyErr_Occurred())
11976 goto exit;
11977 return_value = PyLong_FromSsize_t(_return_value);
11978
11979exit:
11980 return return_value;
11981}
11982
11983static Py_ssize_t
11984os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
11985/*[clinic end generated code: output=591c662dccbe4951 input=5b8d17fe4189d2fe]*/
11986{
11987 int cnt;
11988 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011989 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011990 struct iovec *iov;
11991 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100011992
11993 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011994 PyErr_SetString(PyExc_TypeError,
11995 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100011996 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011997 }
Larry Hastings2f936352014-08-05 14:04:04 +100011998 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011999
Larry Hastings2f936352014-08-05 14:04:04 +100012000 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
12001 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012002 }
12003
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012004 do {
12005 Py_BEGIN_ALLOW_THREADS
12006 result = writev(fd, iov, cnt);
12007 Py_END_ALLOW_THREADS
12008 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020012009
12010 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012011 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100012012 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010012013
Georg Brandl306336b2012-06-24 12:55:33 +020012014 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012015}
Larry Hastings2f936352014-08-05 14:04:04 +100012016#endif /* HAVE_WRITEV */
12017
12018
12019#ifdef HAVE_PWRITE
12020/*[clinic input]
12021os.pwrite -> Py_ssize_t
12022
12023 fd: int
12024 buffer: Py_buffer
12025 offset: Py_off_t
12026 /
12027
12028Write bytes to a file descriptor starting at a particular offset.
12029
12030Write buffer to fd, starting at offset bytes from the beginning of
12031the file. Returns the number of bytes writte. Does not change the
12032current file offset.
12033[clinic start generated code]*/
12034
12035PyDoc_STRVAR(os_pwrite__doc__,
12036"pwrite($module, fd, buffer, offset, /)\n"
12037"--\n"
12038"\n"
12039"Write bytes to a file descriptor starting at a particular offset.\n"
12040"\n"
12041"Write buffer to fd, starting at offset bytes from the beginning of\n"
12042"the file. Returns the number of bytes writte. Does not change the\n"
12043"current file offset.");
12044
12045#define OS_PWRITE_METHODDEF \
12046 {"pwrite", (PyCFunction)os_pwrite, METH_VARARGS, os_pwrite__doc__},
12047
12048static Py_ssize_t
12049os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset);
12050
12051static PyObject *
12052os_pwrite(PyModuleDef *module, PyObject *args)
12053{
12054 PyObject *return_value = NULL;
12055 int fd;
12056 Py_buffer buffer = {NULL, NULL};
12057 Py_off_t offset;
12058 Py_ssize_t _return_value;
12059
12060 if (!PyArg_ParseTuple(args,
12061 "iy*O&:pwrite",
12062 &fd, &buffer, Py_off_t_converter, &offset))
12063 goto exit;
12064 _return_value = os_pwrite_impl(module, fd, &buffer, offset);
12065 if ((_return_value == -1) && PyErr_Occurred())
12066 goto exit;
12067 return_value = PyLong_FromSsize_t(_return_value);
12068
12069exit:
12070 /* Cleanup for buffer */
12071 if (buffer.obj)
12072 PyBuffer_Release(&buffer);
12073
12074 return return_value;
12075}
12076
12077static Py_ssize_t
12078os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset)
12079/*[clinic end generated code: output=ec9cc5b2238e96a7 input=19903f1b3dd26377]*/
12080{
12081 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012082 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100012083
12084 if (!_PyVerify_fd(fd)) {
12085 posix_error();
12086 return -1;
12087 }
12088
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012089 do {
12090 Py_BEGIN_ALLOW_THREADS
12091 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
12092 Py_END_ALLOW_THREADS
12093 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100012094
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012095 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100012096 posix_error();
12097 return size;
12098}
12099#endif /* HAVE_PWRITE */
12100
12101
12102#ifdef HAVE_MKFIFO
12103/*[clinic input]
12104os.mkfifo
12105
12106 path: path_t
12107 mode: int=0o666
12108 *
12109 dir_fd: dir_fd(requires='mkfifoat')=None
12110
12111Create a "fifo" (a POSIX named pipe).
12112
12113If dir_fd is not None, it should be a file descriptor open to a directory,
12114 and path should be relative; path will then be relative to that directory.
12115dir_fd may not be implemented on your platform.
12116 If it is unavailable, using it will raise a NotImplementedError.
12117[clinic start generated code]*/
12118
12119PyDoc_STRVAR(os_mkfifo__doc__,
12120"mkfifo($module, /, path, mode=438, *, dir_fd=None)\n"
12121"--\n"
12122"\n"
12123"Create a \"fifo\" (a POSIX named pipe).\n"
12124"\n"
12125"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
12126" and path should be relative; path will then be relative to that directory.\n"
12127"dir_fd may not be implemented on your platform.\n"
12128" If it is unavailable, using it will raise a NotImplementedError.");
12129
12130#define OS_MKFIFO_METHODDEF \
12131 {"mkfifo", (PyCFunction)os_mkfifo, METH_VARARGS|METH_KEYWORDS, os_mkfifo__doc__},
12132
12133static PyObject *
12134os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd);
12135
12136static PyObject *
12137os_mkfifo(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12138{
12139 PyObject *return_value = NULL;
12140 static char *_keywords[] = {"path", "mode", "dir_fd", NULL};
12141 path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0);
12142 int mode = 438;
12143 int dir_fd = DEFAULT_DIR_FD;
12144
12145 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
12146 "O&|i$O&:mkfifo", _keywords,
12147 path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd))
12148 goto exit;
12149 return_value = os_mkfifo_impl(module, &path, mode, dir_fd);
12150
12151exit:
12152 /* Cleanup for path */
12153 path_cleanup(&path);
12154
12155 return return_value;
12156}
12157
12158static PyObject *
12159os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
12160/*[clinic end generated code: output=b3321927546893d0 input=73032e98a36e0e19]*/
12161{
12162 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012163 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100012164
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012165 do {
12166 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012167#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012168 if (dir_fd != DEFAULT_DIR_FD)
12169 result = mkfifoat(dir_fd, path->narrow, mode);
12170 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020012171#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012172 result = mkfifo(path->narrow, mode);
12173 Py_END_ALLOW_THREADS
12174 } while (result != 0 && errno == EINTR &&
12175 !(async_err = PyErr_CheckSignals()));
12176 if (result != 0)
12177 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012178
12179 Py_RETURN_NONE;
12180}
12181#endif /* HAVE_MKFIFO */
12182
12183
12184#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
12185/*[clinic input]
12186os.mknod
12187
12188 path: path_t
12189 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012190 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100012191 *
12192 dir_fd: dir_fd(requires='mknodat')=None
12193
12194Create a node in the file system.
12195
12196Create a node in the file system (file, device special file or named pipe)
12197at path. mode specifies both the permissions to use and the
12198type of node to be created, being combined (bitwise OR) with one of
12199S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
12200device defines the newly created device special file (probably using
12201os.makedev()). Otherwise device is ignored.
12202
12203If dir_fd is not None, it should be a file descriptor open to a directory,
12204 and path should be relative; path will then be relative to that directory.
12205dir_fd may not be implemented on your platform.
12206 If it is unavailable, using it will raise a NotImplementedError.
12207[clinic start generated code]*/
12208
12209PyDoc_STRVAR(os_mknod__doc__,
12210"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n"
12211"--\n"
12212"\n"
12213"Create a node in the file system.\n"
12214"\n"
12215"Create a node in the file system (file, device special file or named pipe)\n"
12216"at path. mode specifies both the permissions to use and the\n"
12217"type of node to be created, being combined (bitwise OR) with one of\n"
12218"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n"
12219"device defines the newly created device special file (probably using\n"
12220"os.makedev()). Otherwise device is ignored.\n"
12221"\n"
12222"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
12223" and path should be relative; path will then be relative to that directory.\n"
12224"dir_fd may not be implemented on your platform.\n"
12225" If it is unavailable, using it will raise a NotImplementedError.");
12226
12227#define OS_MKNOD_METHODDEF \
12228 {"mknod", (PyCFunction)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__},
12229
12230static PyObject *
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012231os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd);
Larry Hastings2f936352014-08-05 14:04:04 +100012232
12233static PyObject *
12234os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12235{
12236 PyObject *return_value = NULL;
12237 static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL};
12238 path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0);
12239 int mode = 384;
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012240 dev_t device = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100012241 int dir_fd = DEFAULT_DIR_FD;
12242
12243 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012244 "O&|iO&$O&:mknod", _keywords,
12245 path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd))
Larry Hastings2f936352014-08-05 14:04:04 +100012246 goto exit;
12247 return_value = os_mknod_impl(module, &path, mode, device, dir_fd);
12248
12249exit:
12250 /* Cleanup for path */
12251 path_cleanup(&path);
12252
12253 return return_value;
12254}
12255
12256static PyObject *
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012257os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd)
12258/*[clinic end generated code: output=f71d54eaf9bb6f1a input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012259{
12260 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012261 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100012262
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012263 do {
12264 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012265#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012266 if (dir_fd != DEFAULT_DIR_FD)
12267 result = mknodat(dir_fd, path->narrow, mode, device);
12268 else
Larry Hastings2f936352014-08-05 14:04:04 +100012269#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012270 result = mknod(path->narrow, mode, device);
12271 Py_END_ALLOW_THREADS
12272 } while (result != 0 && errno == EINTR &&
12273 !(async_err = PyErr_CheckSignals()));
12274 if (result != 0)
12275 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012276
12277 Py_RETURN_NONE;
12278}
12279#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
12280
12281
12282#ifdef HAVE_DEVICE_MACROS
12283/*[clinic input]
12284os.major -> unsigned_int
12285
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012286 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100012287 /
12288
12289Extracts a device major number from a raw device number.
12290[clinic start generated code]*/
12291
12292PyDoc_STRVAR(os_major__doc__,
12293"major($module, device, /)\n"
12294"--\n"
12295"\n"
12296"Extracts a device major number from a raw device number.");
12297
12298#define OS_MAJOR_METHODDEF \
12299 {"major", (PyCFunction)os_major, METH_VARARGS, os_major__doc__},
12300
12301static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012302os_major_impl(PyModuleDef *module, dev_t device);
Larry Hastings2f936352014-08-05 14:04:04 +100012303
12304static PyObject *
12305os_major(PyModuleDef *module, PyObject *args)
12306{
12307 PyObject *return_value = NULL;
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012308 dev_t device;
Larry Hastings2f936352014-08-05 14:04:04 +100012309 unsigned int _return_value;
12310
12311 if (!PyArg_ParseTuple(args,
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012312 "O&:major",
12313 _Py_Dev_Converter, &device))
Larry Hastings2f936352014-08-05 14:04:04 +100012314 goto exit;
12315 _return_value = os_major_impl(module, device);
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012316 if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012317 goto exit;
12318 return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
12319
12320exit:
12321 return return_value;
12322}
12323
12324static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012325os_major_impl(PyModuleDef *module, dev_t device)
12326/*[clinic end generated code: output=a2d06e908ebf95b5 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012327{
12328 return major(device);
12329}
12330
12331
12332/*[clinic input]
12333os.minor -> unsigned_int
12334
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012335 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100012336 /
12337
12338Extracts a device minor number from a raw device number.
12339[clinic start generated code]*/
12340
12341PyDoc_STRVAR(os_minor__doc__,
12342"minor($module, device, /)\n"
12343"--\n"
12344"\n"
12345"Extracts a device minor number from a raw device number.");
12346
12347#define OS_MINOR_METHODDEF \
12348 {"minor", (PyCFunction)os_minor, METH_VARARGS, os_minor__doc__},
12349
12350static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012351os_minor_impl(PyModuleDef *module, dev_t device);
Larry Hastings2f936352014-08-05 14:04:04 +100012352
12353static PyObject *
12354os_minor(PyModuleDef *module, PyObject *args)
12355{
12356 PyObject *return_value = NULL;
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012357 dev_t device;
Larry Hastings2f936352014-08-05 14:04:04 +100012358 unsigned int _return_value;
12359
12360 if (!PyArg_ParseTuple(args,
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012361 "O&:minor",
12362 _Py_Dev_Converter, &device))
Larry Hastings2f936352014-08-05 14:04:04 +100012363 goto exit;
12364 _return_value = os_minor_impl(module, device);
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012365 if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012366 goto exit;
12367 return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
12368
12369exit:
12370 return return_value;
12371}
12372
12373static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012374os_minor_impl(PyModuleDef *module, dev_t device)
12375/*[clinic end generated code: output=6332287ee3f006e2 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012376{
12377 return minor(device);
12378}
12379
12380
12381/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012382os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100012383
12384 major: int
12385 minor: int
12386 /
12387
12388Composes a raw device number from the major and minor device numbers.
12389[clinic start generated code]*/
12390
12391PyDoc_STRVAR(os_makedev__doc__,
12392"makedev($module, major, minor, /)\n"
12393"--\n"
12394"\n"
12395"Composes a raw device number from the major and minor device numbers.");
12396
12397#define OS_MAKEDEV_METHODDEF \
12398 {"makedev", (PyCFunction)os_makedev, METH_VARARGS, os_makedev__doc__},
12399
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012400static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100012401os_makedev_impl(PyModuleDef *module, int major, int minor);
12402
12403static PyObject *
12404os_makedev(PyModuleDef *module, PyObject *args)
12405{
12406 PyObject *return_value = NULL;
12407 int major;
12408 int minor;
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012409 dev_t _return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012410
12411 if (!PyArg_ParseTuple(args,
12412 "ii:makedev",
12413 &major, &minor))
12414 goto exit;
12415 _return_value = os_makedev_impl(module, major, minor);
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012416 if ((_return_value == (dev_t)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012417 goto exit;
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012418 return_value = _PyLong_FromDev(_return_value);
Larry Hastings2f936352014-08-05 14:04:04 +100012419
12420exit:
12421 return return_value;
12422}
12423
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012424static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100012425os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020012426/*[clinic end generated code: output=38e9a9774c96511a input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012427{
12428 return makedev(major, minor);
12429}
12430#endif /* HAVE_DEVICE_MACROS */
12431
12432
12433#ifdef HAVE_FTRUNCATE
12434/*[clinic input]
12435os.ftruncate
12436
12437 fd: int
12438 length: Py_off_t
12439 /
12440
12441Truncate a file, specified by file descriptor, to a specific length.
12442[clinic start generated code]*/
12443
12444PyDoc_STRVAR(os_ftruncate__doc__,
12445"ftruncate($module, fd, length, /)\n"
12446"--\n"
12447"\n"
12448"Truncate a file, specified by file descriptor, to a specific length.");
12449
12450#define OS_FTRUNCATE_METHODDEF \
12451 {"ftruncate", (PyCFunction)os_ftruncate, METH_VARARGS, os_ftruncate__doc__},
12452
12453static PyObject *
12454os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length);
12455
12456static PyObject *
12457os_ftruncate(PyModuleDef *module, PyObject *args)
12458{
12459 PyObject *return_value = NULL;
12460 int fd;
12461 Py_off_t length;
12462
12463 if (!PyArg_ParseTuple(args,
12464 "iO&:ftruncate",
12465 &fd, Py_off_t_converter, &length))
12466 goto exit;
12467 return_value = os_ftruncate_impl(module, fd, length);
12468
12469exit:
12470 return return_value;
12471}
12472
12473static PyObject *
12474os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
12475/*[clinic end generated code: output=62326766cb9b76bf input=63b43641e52818f2]*/
12476{
12477 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012478 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100012479
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012480 do {
12481 Py_BEGIN_ALLOW_THREADS
12482 result = ftruncate(fd, length);
12483 Py_END_ALLOW_THREADS
12484 } while (result != 0 && errno == EINTR &&
12485 !(async_err = PyErr_CheckSignals()));
12486 if (result != 0)
12487 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012488 Py_RETURN_NONE;
12489}
12490#endif /* HAVE_FTRUNCATE */
12491
12492
12493#ifdef HAVE_TRUNCATE
12494/*[clinic input]
12495os.truncate
12496 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
12497 length: Py_off_t
12498
12499Truncate a file, specified by path, to a specific length.
12500
12501On some platforms, path may also be specified as an open file descriptor.
12502 If this functionality is unavailable, using it raises an exception.
12503[clinic start generated code]*/
12504
12505PyDoc_STRVAR(os_truncate__doc__,
12506"truncate($module, /, path, length)\n"
12507"--\n"
12508"\n"
12509"Truncate a file, specified by path, to a specific length.\n"
12510"\n"
12511"On some platforms, path may also be specified as an open file descriptor.\n"
12512" If this functionality is unavailable, using it raises an exception.");
12513
12514#define OS_TRUNCATE_METHODDEF \
12515 {"truncate", (PyCFunction)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__},
12516
12517static PyObject *
12518os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length);
12519
12520static PyObject *
12521os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12522{
12523 PyObject *return_value = NULL;
12524 static char *_keywords[] = {"path", "length", NULL};
12525 path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE);
12526 Py_off_t length;
12527
12528 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
12529 "O&O&:truncate", _keywords,
12530 path_converter, &path, Py_off_t_converter, &length))
12531 goto exit;
12532 return_value = os_truncate_impl(module, &path, length);
12533
12534exit:
12535 /* Cleanup for path */
12536 path_cleanup(&path);
12537
12538 return return_value;
12539}
12540
12541static PyObject *
12542os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
12543/*[clinic end generated code: output=6bd76262d2e027c6 input=77229cf0b50a9b77]*/
12544{
12545 int result;
12546
12547 Py_BEGIN_ALLOW_THREADS
12548#ifdef HAVE_FTRUNCATE
12549 if (path->fd != -1)
12550 result = ftruncate(path->fd, length);
12551 else
12552#endif
12553 result = truncate(path->narrow, length);
12554 Py_END_ALLOW_THREADS
12555 if (result < 0)
12556 return path_error(path);
12557
12558 Py_RETURN_NONE;
12559}
12560#endif /* HAVE_TRUNCATE */
12561
Ross Lagerwall7807c352011-03-17 20:20:30 +020012562
Victor Stinnerd6b17692014-09-30 12:20:05 +020012563/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
12564 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
12565 defined, which is the case in Python on AIX. AIX bug report:
12566 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
12567#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
12568# define POSIX_FADVISE_AIX_BUG
12569#endif
12570
Victor Stinnerec39e262014-09-30 12:35:58 +020012571
Victor Stinnerd6b17692014-09-30 12:20:05 +020012572#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100012573/*[clinic input]
12574os.posix_fallocate
12575
12576 fd: int
12577 offset: Py_off_t
12578 length: Py_off_t
12579 /
12580
12581Ensure a file has allocated at least a particular number of bytes on disk.
12582
12583Ensure that the file specified by fd encompasses a range of bytes
12584starting at offset bytes from the beginning and continuing for length bytes.
12585[clinic start generated code]*/
12586
12587PyDoc_STRVAR(os_posix_fallocate__doc__,
12588"posix_fallocate($module, fd, offset, length, /)\n"
12589"--\n"
12590"\n"
12591"Ensure a file has allocated at least a particular number of bytes on disk.\n"
12592"\n"
12593"Ensure that the file specified by fd encompasses a range of bytes\n"
12594"starting at offset bytes from the beginning and continuing for length bytes.");
12595
12596#define OS_POSIX_FALLOCATE_METHODDEF \
12597 {"posix_fallocate", (PyCFunction)os_posix_fallocate, METH_VARARGS, os_posix_fallocate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020012598
12599static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012600os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012601
Larry Hastings2f936352014-08-05 14:04:04 +100012602static PyObject *
12603os_posix_fallocate(PyModuleDef *module, PyObject *args)
12604{
12605 PyObject *return_value = NULL;
12606 int fd;
12607 Py_off_t offset;
12608 Py_off_t length;
12609
12610 if (!PyArg_ParseTuple(args,
12611 "iO&O&:posix_fallocate",
12612 &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length))
12613 goto exit;
12614 return_value = os_posix_fallocate_impl(module, fd, offset, length);
12615
12616exit:
12617 return return_value;
12618}
12619
12620static PyObject *
12621os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length)
12622/*[clinic end generated code: output=0cd702d2065c79db input=d7a2ef0ab2ca52fb]*/
12623{
12624 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012625 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012626
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012627 do {
12628 Py_BEGIN_ALLOW_THREADS
12629 result = posix_fallocate(fd, offset, length);
12630 Py_END_ALLOW_THREADS
12631 } while (result != 0 && errno == EINTR &&
12632 !(async_err = PyErr_CheckSignals()));
12633 if (result != 0)
12634 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012635 Py_RETURN_NONE;
12636}
Victor Stinnerec39e262014-09-30 12:35:58 +020012637#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100012638
Ross Lagerwall7807c352011-03-17 20:20:30 +020012639
Victor Stinnerd6b17692014-09-30 12:20:05 +020012640#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100012641/*[clinic input]
12642os.posix_fadvise
12643
12644 fd: int
12645 offset: Py_off_t
12646 length: Py_off_t
12647 advice: int
12648 /
12649
12650Announce an intention to access data in a specific pattern.
12651
12652Announce an intention to access data in a specific pattern, thus allowing
12653the kernel to make optimizations.
12654The advice applies to the region of the file specified by fd starting at
12655offset and continuing for length bytes.
12656advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
12657POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
12658POSIX_FADV_DONTNEED.
12659[clinic start generated code]*/
12660
12661PyDoc_STRVAR(os_posix_fadvise__doc__,
12662"posix_fadvise($module, fd, offset, length, advice, /)\n"
12663"--\n"
12664"\n"
12665"Announce an intention to access data in a specific pattern.\n"
12666"\n"
12667"Announce an intention to access data in a specific pattern, thus allowing\n"
12668"the kernel to make optimizations.\n"
12669"The advice applies to the region of the file specified by fd starting at\n"
12670"offset and continuing for length bytes.\n"
12671"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n"
12672"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n"
12673"POSIX_FADV_DONTNEED.");
12674
12675#define OS_POSIX_FADVISE_METHODDEF \
12676 {"posix_fadvise", (PyCFunction)os_posix_fadvise, METH_VARARGS, os_posix_fadvise__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020012677
12678static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012679os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012680
Larry Hastings2f936352014-08-05 14:04:04 +100012681static PyObject *
12682os_posix_fadvise(PyModuleDef *module, PyObject *args)
12683{
12684 PyObject *return_value = NULL;
12685 int fd;
12686 Py_off_t offset;
12687 Py_off_t length;
12688 int advice;
12689
12690 if (!PyArg_ParseTuple(args,
12691 "iO&O&i:posix_fadvise",
12692 &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice))
12693 goto exit;
12694 return_value = os_posix_fadvise_impl(module, fd, offset, length, advice);
12695
12696exit:
12697 return return_value;
12698}
12699
12700static PyObject *
12701os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice)
12702/*[clinic end generated code: output=dad93f32c04dd4f7 input=0fbe554edc2f04b5]*/
12703{
12704 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012705 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012706
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000012707 do {
12708 Py_BEGIN_ALLOW_THREADS
12709 result = posix_fadvise(fd, offset, length, advice);
12710 Py_END_ALLOW_THREADS
12711 } while (result != 0 && errno == EINTR &&
12712 !(async_err = PyErr_CheckSignals()));
12713 if (result != 0)
12714 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012715 Py_RETURN_NONE;
12716}
Victor Stinnerec39e262014-09-30 12:35:58 +020012717#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020012718
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012719#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000012720
Fred Drake762e2061999-08-26 17:23:54 +000012721/* Save putenv() parameters as values here, so we can collect them when they
12722 * get re-set with another call for the same key. */
12723static PyObject *posix_putenv_garbage;
12724
Larry Hastings2f936352014-08-05 14:04:04 +100012725static void
12726posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012727{
Larry Hastings2f936352014-08-05 14:04:04 +100012728 /* Install the first arg and newstr in posix_putenv_garbage;
12729 * this will cause previous value to be collected. This has to
12730 * happen after the real putenv() call because the old value
12731 * was still accessible until then. */
12732 if (PyDict_SetItem(posix_putenv_garbage, name, value))
12733 /* really not much we can do; just leak */
12734 PyErr_Clear();
12735 else
12736 Py_DECREF(value);
12737}
12738
12739
Thomas Hellerf78f12a2007-11-08 19:33:05 +000012740#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012741/*[clinic input]
12742os.putenv
12743
12744 name: unicode
12745 value: unicode
12746 /
12747
12748Change or add an environment variable.
12749[clinic start generated code]*/
12750
12751PyDoc_STRVAR(os_putenv__doc__,
12752"putenv($module, name, value, /)\n"
12753"--\n"
12754"\n"
12755"Change or add an environment variable.");
12756
12757#define OS_PUTENV_METHODDEF \
12758 {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__},
12759
12760static PyObject *
12761os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value);
12762
12763static PyObject *
12764os_putenv(PyModuleDef *module, PyObject *args)
12765{
12766 PyObject *return_value = NULL;
12767 PyObject *name;
12768 PyObject *value;
Victor Stinner65170952011-11-22 22:16:17 +010012769
Victor Stinner8c62be82010-05-06 00:08:46 +000012770 if (!PyArg_ParseTuple(args,
Larry Hastings2f936352014-08-05 14:04:04 +100012771 "UU:putenv",
12772 &name, &value))
12773 goto exit;
12774 return_value = os_putenv_impl(module, name, value);
Guido van Rossumd48f2521997-12-05 22:19:34 +000012775
Larry Hastings2f936352014-08-05 14:04:04 +100012776exit:
12777 return return_value;
12778}
12779
12780static PyObject *
12781os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
12782/*[clinic end generated code: output=5ce9ef9b15606e7e input=ba586581c2e6105f]*/
12783{
12784 wchar_t *env;
12785
12786 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
12787 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +000012788 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +100012789 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +000012790 }
Larry Hastings2f936352014-08-05 14:04:04 +100012791 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +010012792 PyErr_Format(PyExc_ValueError,
12793 "the environment variable is longer than %u characters",
12794 _MAX_ENV);
12795 goto error;
12796 }
12797
Larry Hastings2f936352014-08-05 14:04:04 +100012798 env = PyUnicode_AsUnicode(unicode);
12799 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +020012800 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +100012801 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012802 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +000012803 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +000012804 }
Guido van Rossuma4916fa1996-05-23 22:58:55 +000012805
Larry Hastings2f936352014-08-05 14:04:04 +100012806 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +000012807 Py_RETURN_NONE;
12808
12809error:
Larry Hastings2f936352014-08-05 14:04:04 +100012810 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +000012811 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012812}
Larry Hastings2f936352014-08-05 14:04:04 +100012813#else /* MS_WINDOWS */
12814/*[clinic input]
12815os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000012816
Larry Hastings2f936352014-08-05 14:04:04 +100012817 name: FSConverter
12818 value: FSConverter
12819 /
12820
12821Change or add an environment variable.
12822[clinic start generated code]*/
12823
12824PyDoc_STRVAR(os_putenv__doc__,
12825"putenv($module, name, value, /)\n"
12826"--\n"
12827"\n"
12828"Change or add an environment variable.");
12829
12830#define OS_PUTENV_METHODDEF \
12831 {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000012832
12833static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012834os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value);
12835
12836static PyObject *
12837os_putenv(PyModuleDef *module, PyObject *args)
Guido van Rossumc524d952001-10-19 01:31:59 +000012838{
Larry Hastings2f936352014-08-05 14:04:04 +100012839 PyObject *return_value = NULL;
12840 PyObject *name = NULL;
12841 PyObject *value = NULL;
12842
12843 if (!PyArg_ParseTuple(args,
12844 "O&O&:putenv",
12845 PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value))
12846 goto exit;
12847 return_value = os_putenv_impl(module, name, value);
12848
12849exit:
12850 /* Cleanup for name */
12851 Py_XDECREF(name);
12852 /* Cleanup for value */
12853 Py_XDECREF(value);
12854
12855 return return_value;
12856}
12857
12858static PyObject *
12859os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
12860/*[clinic end generated code: output=85ab223393dc7afd input=a97bc6152f688d31]*/
12861{
12862 PyObject *bytes = NULL;
12863 char *env;
12864 char *name_string = PyBytes_AsString(name);
12865 char *value_string = PyBytes_AsString(value);
12866
12867 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
12868 if (bytes == NULL) {
12869 PyErr_NoMemory();
12870 return NULL;
12871 }
12872
12873 env = PyBytes_AS_STRING(bytes);
12874 if (putenv(env)) {
12875 Py_DECREF(bytes);
12876 return posix_error();
12877 }
12878
12879 posix_putenv_garbage_setitem(name, bytes);
12880 Py_RETURN_NONE;
12881}
12882#endif /* MS_WINDOWS */
12883#endif /* HAVE_PUTENV */
12884
12885
12886#ifdef HAVE_UNSETENV
12887/*[clinic input]
12888os.unsetenv
12889 name: FSConverter
12890 /
12891
12892Delete an environment variable.
12893[clinic start generated code]*/
12894
12895PyDoc_STRVAR(os_unsetenv__doc__,
12896"unsetenv($module, name, /)\n"
12897"--\n"
12898"\n"
12899"Delete an environment variable.");
12900
12901#define OS_UNSETENV_METHODDEF \
12902 {"unsetenv", (PyCFunction)os_unsetenv, METH_VARARGS, os_unsetenv__doc__},
12903
12904static PyObject *
12905os_unsetenv_impl(PyModuleDef *module, PyObject *name);
12906
12907static PyObject *
12908os_unsetenv(PyModuleDef *module, PyObject *args)
12909{
12910 PyObject *return_value = NULL;
12911 PyObject *name = NULL;
12912
12913 if (!PyArg_ParseTuple(args,
12914 "O&:unsetenv",
12915 PyUnicode_FSConverter, &name))
12916 goto exit;
12917 return_value = os_unsetenv_impl(module, name);
12918
12919exit:
12920 /* Cleanup for name */
12921 Py_XDECREF(name);
12922
12923 return return_value;
12924}
12925
12926static PyObject *
12927os_unsetenv_impl(PyModuleDef *module, PyObject *name)
12928/*[clinic end generated code: output=91318c995f9a0767 input=2bb5288a599c7107]*/
12929{
Victor Stinner984890f2011-11-24 13:53:38 +010012930#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010012931 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010012932#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000012933
Victor Stinner984890f2011-11-24 13:53:38 +010012934#ifdef HAVE_BROKEN_UNSETENV
12935 unsetenv(PyBytes_AS_STRING(name));
12936#else
Victor Stinner65170952011-11-22 22:16:17 +010012937 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100012938 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010012939 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010012940#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000012941
Victor Stinner8c62be82010-05-06 00:08:46 +000012942 /* Remove the key from posix_putenv_garbage;
12943 * this will cause it to be collected. This has to
12944 * happen after the real unsetenv() call because the
12945 * old value was still accessible until then.
12946 */
Victor Stinner65170952011-11-22 22:16:17 +010012947 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012948 /* really not much we can do; just leak */
12949 PyErr_Clear();
12950 }
Victor Stinner84ae1182010-05-06 22:05:07 +000012951 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000012952}
Larry Hastings2f936352014-08-05 14:04:04 +100012953#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000012954
Larry Hastings2f936352014-08-05 14:04:04 +100012955
12956/*[clinic input]
12957os.strerror
12958
12959 code: int
12960 /
12961
12962Translate an error code to a message string.
12963[clinic start generated code]*/
12964
12965PyDoc_STRVAR(os_strerror__doc__,
12966"strerror($module, code, /)\n"
12967"--\n"
12968"\n"
12969"Translate an error code to a message string.");
12970
12971#define OS_STRERROR_METHODDEF \
12972 {"strerror", (PyCFunction)os_strerror, METH_VARARGS, os_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +000012973
Guido van Rossumf68d8e52001-04-14 17:55:09 +000012974static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012975os_strerror_impl(PyModuleDef *module, int code);
12976
12977static PyObject *
12978os_strerror(PyModuleDef *module, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +000012979{
Larry Hastings2f936352014-08-05 14:04:04 +100012980 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012981 int code;
Larry Hastings2f936352014-08-05 14:04:04 +100012982
12983 if (!PyArg_ParseTuple(args,
12984 "i:strerror",
12985 &code))
12986 goto exit;
12987 return_value = os_strerror_impl(module, code);
12988
12989exit:
12990 return return_value;
12991}
12992
12993static PyObject *
12994os_strerror_impl(PyModuleDef *module, int code)
12995/*[clinic end generated code: output=8665c70bb2ca4720 input=75a8673d97915a91]*/
12996{
12997 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 if (message == NULL) {
12999 PyErr_SetString(PyExc_ValueError,
13000 "strerror() argument out of range");
13001 return NULL;
13002 }
Victor Stinner1b579672011-12-17 05:47:23 +010013003 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000013004}
Guido van Rossumb6a47161997-09-15 22:54:34 +000013005
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000013006
Guido van Rossumc9641791998-08-04 15:26:23 +000013007#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000013008#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100013009/*[clinic input]
13010os.WCOREDUMP -> bool
13011
13012 status: int
13013 /
13014
13015Return True if the process returning status was dumped to a core file.
13016[clinic start generated code]*/
13017
13018PyDoc_STRVAR(os_WCOREDUMP__doc__,
13019"WCOREDUMP($module, status, /)\n"
13020"--\n"
13021"\n"
13022"Return True if the process returning status was dumped to a core file.");
13023
13024#define OS_WCOREDUMP_METHODDEF \
13025 {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_VARARGS, os_WCOREDUMP__doc__},
13026
13027static int
13028os_WCOREDUMP_impl(PyModuleDef *module, int status);
Fred Drake106c1a02002-04-23 15:58:02 +000013029
13030static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013031os_WCOREDUMP(PyModuleDef *module, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +000013032{
Larry Hastings2f936352014-08-05 14:04:04 +100013033 PyObject *return_value = NULL;
13034 int status;
13035 int _return_value;
Fred Drake106c1a02002-04-23 15:58:02 +000013036
Larry Hastings2f936352014-08-05 14:04:04 +100013037 if (!PyArg_ParseTuple(args,
13038 "i:WCOREDUMP",
13039 &status))
13040 goto exit;
13041 _return_value = os_WCOREDUMP_impl(module, status);
13042 if ((_return_value == -1) && PyErr_Occurred())
13043 goto exit;
13044 return_value = PyBool_FromLong((long)_return_value);
Fred Drake106c1a02002-04-23 15:58:02 +000013045
Larry Hastings2f936352014-08-05 14:04:04 +100013046exit:
13047 return return_value;
13048}
13049
13050static int
13051os_WCOREDUMP_impl(PyModuleDef *module, int status)
13052/*[clinic end generated code: output=e04d55c09c299828 input=8b05e7ab38528d04]*/
13053{
13054 WAIT_TYPE wait_status;
13055 WAIT_STATUS_INT(wait_status) = status;
13056 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000013057}
13058#endif /* WCOREDUMP */
13059
Larry Hastings2f936352014-08-05 14:04:04 +100013060
Fred Drake106c1a02002-04-23 15:58:02 +000013061#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100013062/*[clinic input]
13063os.WIFCONTINUED -> bool
13064
13065 status: int
13066
13067Return True if a particular process was continued from a job control stop.
13068
13069Return True if the process returning status was continued from a
13070job control stop.
13071[clinic start generated code]*/
13072
13073PyDoc_STRVAR(os_WIFCONTINUED__doc__,
13074"WIFCONTINUED($module, /, status)\n"
13075"--\n"
13076"\n"
13077"Return True if a particular process was continued from a job control stop.\n"
13078"\n"
13079"Return True if the process returning status was continued from a\n"
13080"job control stop.");
13081
13082#define OS_WIFCONTINUED_METHODDEF \
13083 {"WIFCONTINUED", (PyCFunction)os_WIFCONTINUED, METH_VARARGS|METH_KEYWORDS, os_WIFCONTINUED__doc__},
13084
13085static int
13086os_WIFCONTINUED_impl(PyModuleDef *module, int status);
Fred Drake106c1a02002-04-23 15:58:02 +000013087
13088static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013089os_WIFCONTINUED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Fred Drake106c1a02002-04-23 15:58:02 +000013090{
Larry Hastings2f936352014-08-05 14:04:04 +100013091 PyObject *return_value = NULL;
13092 static char *_keywords[] = {"status", NULL};
13093 int status;
13094 int _return_value;
Fred Drake106c1a02002-04-23 15:58:02 +000013095
Larry Hastings2f936352014-08-05 14:04:04 +100013096 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13097 "i:WIFCONTINUED", _keywords,
13098 &status))
13099 goto exit;
13100 _return_value = os_WIFCONTINUED_impl(module, status);
13101 if ((_return_value == -1) && PyErr_Occurred())
13102 goto exit;
13103 return_value = PyBool_FromLong((long)_return_value);
Fred Drake106c1a02002-04-23 15:58:02 +000013104
Larry Hastings2f936352014-08-05 14:04:04 +100013105exit:
13106 return return_value;
13107}
13108
13109static int
13110os_WIFCONTINUED_impl(PyModuleDef *module, int status)
13111/*[clinic end generated code: output=9c4e6105a4520ab5 input=e777e7d38eb25bd9]*/
13112{
13113 WAIT_TYPE wait_status;
13114 WAIT_STATUS_INT(wait_status) = status;
13115 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000013116}
13117#endif /* WIFCONTINUED */
13118
Larry Hastings2f936352014-08-05 14:04:04 +100013119
Guido van Rossumc9641791998-08-04 15:26:23 +000013120#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100013121/*[clinic input]
13122os.WIFSTOPPED -> bool
13123
13124 status: int
13125
13126Return True if the process returning status was stopped.
13127[clinic start generated code]*/
13128
13129PyDoc_STRVAR(os_WIFSTOPPED__doc__,
13130"WIFSTOPPED($module, /, status)\n"
13131"--\n"
13132"\n"
13133"Return True if the process returning status was stopped.");
13134
13135#define OS_WIFSTOPPED_METHODDEF \
13136 {"WIFSTOPPED", (PyCFunction)os_WIFSTOPPED, METH_VARARGS|METH_KEYWORDS, os_WIFSTOPPED__doc__},
13137
13138static int
13139os_WIFSTOPPED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013140
13141static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013142os_WIFSTOPPED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013143{
Larry Hastings2f936352014-08-05 14:04:04 +100013144 PyObject *return_value = NULL;
13145 static char *_keywords[] = {"status", NULL};
13146 int status;
13147 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013148
Larry Hastings2f936352014-08-05 14:04:04 +100013149 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13150 "i:WIFSTOPPED", _keywords,
13151 &status))
13152 goto exit;
13153 _return_value = os_WIFSTOPPED_impl(module, status);
13154 if ((_return_value == -1) && PyErr_Occurred())
13155 goto exit;
13156 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013157
Larry Hastings2f936352014-08-05 14:04:04 +100013158exit:
13159 return return_value;
13160}
13161
13162static int
13163os_WIFSTOPPED_impl(PyModuleDef *module, int status)
13164/*[clinic end generated code: output=e0de2da8ec9593ff input=043cb7f1289ef904]*/
13165{
13166 WAIT_TYPE wait_status;
13167 WAIT_STATUS_INT(wait_status) = status;
13168 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013169}
13170#endif /* WIFSTOPPED */
13171
Larry Hastings2f936352014-08-05 14:04:04 +100013172
Guido van Rossumc9641791998-08-04 15:26:23 +000013173#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100013174/*[clinic input]
13175os.WIFSIGNALED -> bool
13176
13177 status: int
13178
13179Return True if the process returning status was terminated by a signal.
13180[clinic start generated code]*/
13181
13182PyDoc_STRVAR(os_WIFSIGNALED__doc__,
13183"WIFSIGNALED($module, /, status)\n"
13184"--\n"
13185"\n"
13186"Return True if the process returning status was terminated by a signal.");
13187
13188#define OS_WIFSIGNALED_METHODDEF \
13189 {"WIFSIGNALED", (PyCFunction)os_WIFSIGNALED, METH_VARARGS|METH_KEYWORDS, os_WIFSIGNALED__doc__},
13190
13191static int
13192os_WIFSIGNALED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013193
13194static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013195os_WIFSIGNALED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013196{
Larry Hastings2f936352014-08-05 14:04:04 +100013197 PyObject *return_value = NULL;
13198 static char *_keywords[] = {"status", NULL};
13199 int status;
13200 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013201
Larry Hastings2f936352014-08-05 14:04:04 +100013202 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13203 "i:WIFSIGNALED", _keywords,
13204 &status))
13205 goto exit;
13206 _return_value = os_WIFSIGNALED_impl(module, status);
13207 if ((_return_value == -1) && PyErr_Occurred())
13208 goto exit;
13209 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013210
Larry Hastings2f936352014-08-05 14:04:04 +100013211exit:
13212 return return_value;
13213}
13214
13215static int
13216os_WIFSIGNALED_impl(PyModuleDef *module, int status)
13217/*[clinic end generated code: output=f14d106558f406be input=d55ba7cc9ce5dc43]*/
13218{
13219 WAIT_TYPE wait_status;
13220 WAIT_STATUS_INT(wait_status) = status;
13221 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013222}
13223#endif /* WIFSIGNALED */
13224
Larry Hastings2f936352014-08-05 14:04:04 +100013225
Guido van Rossumc9641791998-08-04 15:26:23 +000013226#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100013227/*[clinic input]
13228os.WIFEXITED -> bool
13229
13230 status: int
13231
13232Return True if the process returning status exited via the exit() system call.
13233[clinic start generated code]*/
13234
13235PyDoc_STRVAR(os_WIFEXITED__doc__,
13236"WIFEXITED($module, /, status)\n"
13237"--\n"
13238"\n"
13239"Return True if the process returning status exited via the exit() system call.");
13240
13241#define OS_WIFEXITED_METHODDEF \
13242 {"WIFEXITED", (PyCFunction)os_WIFEXITED, METH_VARARGS|METH_KEYWORDS, os_WIFEXITED__doc__},
13243
13244static int
13245os_WIFEXITED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013246
13247static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013248os_WIFEXITED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013249{
Larry Hastings2f936352014-08-05 14:04:04 +100013250 PyObject *return_value = NULL;
13251 static char *_keywords[] = {"status", NULL};
13252 int status;
13253 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013254
Larry Hastings2f936352014-08-05 14:04:04 +100013255 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13256 "i:WIFEXITED", _keywords,
13257 &status))
13258 goto exit;
13259 _return_value = os_WIFEXITED_impl(module, status);
13260 if ((_return_value == -1) && PyErr_Occurred())
13261 goto exit;
13262 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013263
Larry Hastings2f936352014-08-05 14:04:04 +100013264exit:
13265 return return_value;
13266}
13267
13268static int
13269os_WIFEXITED_impl(PyModuleDef *module, int status)
13270/*[clinic end generated code: output=2f76087d53721255 input=d63775a6791586c0]*/
13271{
13272 WAIT_TYPE wait_status;
13273 WAIT_STATUS_INT(wait_status) = status;
13274 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013275}
13276#endif /* WIFEXITED */
13277
Larry Hastings2f936352014-08-05 14:04:04 +100013278
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000013279#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100013280/*[clinic input]
13281os.WEXITSTATUS -> int
13282
13283 status: int
13284
13285Return the process return code from status.
13286[clinic start generated code]*/
13287
13288PyDoc_STRVAR(os_WEXITSTATUS__doc__,
13289"WEXITSTATUS($module, /, status)\n"
13290"--\n"
13291"\n"
13292"Return the process return code from status.");
13293
13294#define OS_WEXITSTATUS_METHODDEF \
13295 {"WEXITSTATUS", (PyCFunction)os_WEXITSTATUS, METH_VARARGS|METH_KEYWORDS, os_WEXITSTATUS__doc__},
13296
13297static int
13298os_WEXITSTATUS_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013299
13300static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013301os_WEXITSTATUS(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013302{
Larry Hastings2f936352014-08-05 14:04:04 +100013303 PyObject *return_value = NULL;
13304 static char *_keywords[] = {"status", NULL};
13305 int status;
13306 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013307
Larry Hastings2f936352014-08-05 14:04:04 +100013308 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13309 "i:WEXITSTATUS", _keywords,
13310 &status))
13311 goto exit;
13312 _return_value = os_WEXITSTATUS_impl(module, status);
13313 if ((_return_value == -1) && PyErr_Occurred())
13314 goto exit;
13315 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013316
Larry Hastings2f936352014-08-05 14:04:04 +100013317exit:
13318 return return_value;
13319}
13320
13321static int
13322os_WEXITSTATUS_impl(PyModuleDef *module, int status)
13323/*[clinic end generated code: output=13b6c270e2a326b1 input=e1fb4944e377585b]*/
13324{
13325 WAIT_TYPE wait_status;
13326 WAIT_STATUS_INT(wait_status) = status;
13327 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013328}
13329#endif /* WEXITSTATUS */
13330
Larry Hastings2f936352014-08-05 14:04:04 +100013331
Guido van Rossumc9641791998-08-04 15:26:23 +000013332#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100013333/*[clinic input]
13334os.WTERMSIG -> int
13335
13336 status: int
13337
13338Return the signal that terminated the process that provided the status value.
13339[clinic start generated code]*/
13340
13341PyDoc_STRVAR(os_WTERMSIG__doc__,
13342"WTERMSIG($module, /, status)\n"
13343"--\n"
13344"\n"
13345"Return the signal that terminated the process that provided the status value.");
13346
13347#define OS_WTERMSIG_METHODDEF \
13348 {"WTERMSIG", (PyCFunction)os_WTERMSIG, METH_VARARGS|METH_KEYWORDS, os_WTERMSIG__doc__},
13349
13350static int
13351os_WTERMSIG_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013352
13353static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013354os_WTERMSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013355{
Larry Hastings2f936352014-08-05 14:04:04 +100013356 PyObject *return_value = NULL;
13357 static char *_keywords[] = {"status", NULL};
13358 int status;
13359 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013360
Larry Hastings2f936352014-08-05 14:04:04 +100013361 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13362 "i:WTERMSIG", _keywords,
13363 &status))
13364 goto exit;
13365 _return_value = os_WTERMSIG_impl(module, status);
13366 if ((_return_value == -1) && PyErr_Occurred())
13367 goto exit;
13368 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013369
Larry Hastings2f936352014-08-05 14:04:04 +100013370exit:
13371 return return_value;
13372}
13373
13374static int
13375os_WTERMSIG_impl(PyModuleDef *module, int status)
13376/*[clinic end generated code: output=bf1fd4b002d0a9ed input=727fd7f84ec3f243]*/
13377{
13378 WAIT_TYPE wait_status;
13379 WAIT_STATUS_INT(wait_status) = status;
13380 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013381}
13382#endif /* WTERMSIG */
13383
Larry Hastings2f936352014-08-05 14:04:04 +100013384
Guido van Rossumc9641791998-08-04 15:26:23 +000013385#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100013386/*[clinic input]
13387os.WSTOPSIG -> int
13388
13389 status: int
13390
13391Return the signal that stopped the process that provided the status value.
13392[clinic start generated code]*/
13393
13394PyDoc_STRVAR(os_WSTOPSIG__doc__,
13395"WSTOPSIG($module, /, status)\n"
13396"--\n"
13397"\n"
13398"Return the signal that stopped the process that provided the status value.");
13399
13400#define OS_WSTOPSIG_METHODDEF \
13401 {"WSTOPSIG", (PyCFunction)os_WSTOPSIG, METH_VARARGS|METH_KEYWORDS, os_WSTOPSIG__doc__},
13402
13403static int
13404os_WSTOPSIG_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013405
13406static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013407os_WSTOPSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013408{
Larry Hastings2f936352014-08-05 14:04:04 +100013409 PyObject *return_value = NULL;
13410 static char *_keywords[] = {"status", NULL};
13411 int status;
13412 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013413
Larry Hastings2f936352014-08-05 14:04:04 +100013414 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13415 "i:WSTOPSIG", _keywords,
13416 &status))
13417 goto exit;
13418 _return_value = os_WSTOPSIG_impl(module, status);
13419 if ((_return_value == -1) && PyErr_Occurred())
13420 goto exit;
13421 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013422
Larry Hastings2f936352014-08-05 14:04:04 +100013423exit:
13424 return return_value;
13425}
13426
13427static int
13428os_WSTOPSIG_impl(PyModuleDef *module, int status)
13429/*[clinic end generated code: output=92e1647d29ee0549 input=46ebf1d1b293c5c1]*/
13430{
13431 WAIT_TYPE wait_status;
13432 WAIT_STATUS_INT(wait_status) = status;
13433 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013434}
13435#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000013436#endif /* HAVE_SYS_WAIT_H */
13437
13438
Larry Hastings2f936352014-08-05 14:04:04 +100013439#ifndef OS_WCOREDUMP_METHODDEF
13440#define OS_WCOREDUMP_METHODDEF
13441#endif /* OS_WCOREDUMP_METHODDEF */
13442
13443#ifndef OS_WIFCONTINUED_METHODDEF
13444#define OS_WIFCONTINUED_METHODDEF
13445#endif /* OS_WIFCONTINUED_METHODDEF */
13446
13447#ifndef OS_WIFSTOPPED_METHODDEF
13448#define OS_WIFSTOPPED_METHODDEF
13449#endif /* OS_WIFSTOPPED_METHODDEF */
13450
13451#ifndef OS_WIFSIGNALED_METHODDEF
13452#define OS_WIFSIGNALED_METHODDEF
13453#endif /* OS_WIFSIGNALED_METHODDEF */
13454
13455#ifndef OS_WIFEXITED_METHODDEF
13456#define OS_WIFEXITED_METHODDEF
13457#endif /* OS_WIFEXITED_METHODDEF */
13458
13459#ifndef OS_WEXITSTATUS_METHODDEF
13460#define OS_WEXITSTATUS_METHODDEF
13461#endif /* OS_WEXITSTATUS_METHODDEF */
13462
13463#ifndef OS_WTERMSIG_METHODDEF
13464#define OS_WTERMSIG_METHODDEF
13465#endif /* OS_WTERMSIG_METHODDEF */
13466
13467#ifndef OS_WSTOPSIG_METHODDEF
13468#define OS_WSTOPSIG_METHODDEF
13469#endif /* OS_WSTOPSIG_METHODDEF */
13470
13471
Thomas Wouters477c8d52006-05-27 19:21:47 +000013472#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000013473#ifdef _SCO_DS
13474/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
13475 needed definitions in sys/statvfs.h */
13476#define _SVID3
13477#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013478#include <sys/statvfs.h>
13479
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013480static PyObject*
13481_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +000013482 PyObject *v = PyStructSequence_New(&StatVFSResultType);
13483 if (v == NULL)
13484 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013485
13486#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000013487 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
13488 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
13489 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
13490 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
13491 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
13492 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
13493 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
13494 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
13495 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
13496 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013497#else
Victor Stinner8c62be82010-05-06 00:08:46 +000013498 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
13499 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
13500 PyStructSequence_SET_ITEM(v, 2,
13501 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
13502 PyStructSequence_SET_ITEM(v, 3,
13503 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
13504 PyStructSequence_SET_ITEM(v, 4,
13505 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
13506 PyStructSequence_SET_ITEM(v, 5,
13507 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
13508 PyStructSequence_SET_ITEM(v, 6,
13509 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
13510 PyStructSequence_SET_ITEM(v, 7,
13511 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
13512 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
13513 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013514#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010013515 if (PyErr_Occurred()) {
13516 Py_DECREF(v);
13517 return NULL;
13518 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013519
Victor Stinner8c62be82010-05-06 00:08:46 +000013520 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013521}
13522
Larry Hastings2f936352014-08-05 14:04:04 +100013523
13524/*[clinic input]
13525os.fstatvfs
13526 fd: int
13527 /
13528
13529Perform an fstatvfs system call on the given fd.
13530
13531Equivalent to statvfs(fd).
13532[clinic start generated code]*/
13533
13534PyDoc_STRVAR(os_fstatvfs__doc__,
13535"fstatvfs($module, fd, /)\n"
13536"--\n"
13537"\n"
13538"Perform an fstatvfs system call on the given fd.\n"
13539"\n"
13540"Equivalent to statvfs(fd).");
13541
13542#define OS_FSTATVFS_METHODDEF \
13543 {"fstatvfs", (PyCFunction)os_fstatvfs, METH_VARARGS, os_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000013544
13545static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013546os_fstatvfs_impl(PyModuleDef *module, int fd);
13547
13548static PyObject *
13549os_fstatvfs(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +000013550{
Larry Hastings2f936352014-08-05 14:04:04 +100013551 PyObject *return_value = NULL;
13552 int fd;
13553
13554 if (!PyArg_ParseTuple(args,
13555 "i:fstatvfs",
13556 &fd))
13557 goto exit;
13558 return_value = os_fstatvfs_impl(module, fd);
13559
13560exit:
13561 return return_value;
13562}
13563
13564static PyObject *
13565os_fstatvfs_impl(PyModuleDef *module, int fd)
13566/*[clinic end generated code: output=0e32bf07f946ec0d input=d8122243ac50975e]*/
13567{
13568 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000013569 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000013570 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013571
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000013572 do {
13573 Py_BEGIN_ALLOW_THREADS
13574 result = fstatvfs(fd, &st);
13575 Py_END_ALLOW_THREADS
13576 } while (result != 0 && errno == EINTR &&
13577 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100013578 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000013579 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013580
Victor Stinner8c62be82010-05-06 00:08:46 +000013581 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000013582}
Larry Hastings2f936352014-08-05 14:04:04 +100013583#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000013584
13585
Thomas Wouters477c8d52006-05-27 19:21:47 +000013586#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000013587#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100013588/*[clinic input]
13589os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000013590
Larry Hastings2f936352014-08-05 14:04:04 +100013591 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
13592
13593Perform a statvfs system call on the given path.
13594
13595path may always be specified as a string.
13596On some platforms, path may also be specified as an open file descriptor.
13597 If this functionality is unavailable, using it raises an exception.
13598[clinic start generated code]*/
13599
13600PyDoc_STRVAR(os_statvfs__doc__,
13601"statvfs($module, /, path)\n"
13602"--\n"
13603"\n"
13604"Perform a statvfs system call on the given path.\n"
13605"\n"
13606"path may always be specified as a string.\n"
13607"On some platforms, path may also be specified as an open file descriptor.\n"
13608" If this functionality is unavailable, using it raises an exception.");
13609
13610#define OS_STATVFS_METHODDEF \
13611 {"statvfs", (PyCFunction)os_statvfs, METH_VARARGS|METH_KEYWORDS, os_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000013612
13613static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013614os_statvfs_impl(PyModuleDef *module, path_t *path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013615
Larry Hastings2f936352014-08-05 14:04:04 +100013616static PyObject *
13617os_statvfs(PyModuleDef *module, PyObject *args, PyObject *kwargs)
13618{
13619 PyObject *return_value = NULL;
13620 static char *_keywords[] = {"path", NULL};
13621 path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS);
13622
13623 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13624 "O&:statvfs", _keywords,
13625 path_converter, &path))
13626 goto exit;
13627 return_value = os_statvfs_impl(module, &path);
13628
13629exit:
13630 /* Cleanup for path */
13631 path_cleanup(&path);
13632
13633 return return_value;
13634}
13635
13636static PyObject *
13637os_statvfs_impl(PyModuleDef *module, path_t *path)
13638/*[clinic end generated code: output=00ff54983360b446 input=3f5c35791c669bd9]*/
13639{
13640 int result;
13641 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013642
13643 Py_BEGIN_ALLOW_THREADS
13644#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100013645 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013646#ifdef __APPLE__
13647 /* handle weak-linking on Mac OS X 10.3 */
13648 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100013649 fd_specified("statvfs", path->fd);
13650 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013651 }
13652#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013653 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013654 }
13655 else
13656#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013657 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013658 Py_END_ALLOW_THREADS
13659
13660 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100013661 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013662 }
13663
Larry Hastings2f936352014-08-05 14:04:04 +100013664 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000013665}
Larry Hastings2f936352014-08-05 14:04:04 +100013666#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
13667
Guido van Rossum94f6f721999-01-06 18:42:14 +000013668
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013669#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013670/*[clinic input]
13671os._getdiskusage
13672
13673 path: Py_UNICODE
13674
13675Return disk usage statistics about the given path as a (total, free) tuple.
13676[clinic start generated code]*/
13677
13678PyDoc_STRVAR(os__getdiskusage__doc__,
13679"_getdiskusage($module, /, path)\n"
13680"--\n"
13681"\n"
13682"Return disk usage statistics about the given path as a (total, free) tuple.");
13683
13684#define OS__GETDISKUSAGE_METHODDEF \
13685 {"_getdiskusage", (PyCFunction)os__getdiskusage, METH_VARARGS|METH_KEYWORDS, os__getdiskusage__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013686
13687static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013688os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path);
13689
13690static PyObject *
13691os__getdiskusage(PyModuleDef *module, PyObject *args, PyObject *kwargs)
13692{
13693 PyObject *return_value = NULL;
13694 static char *_keywords[] = {"path", NULL};
13695 Py_UNICODE *path;
13696
13697 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13698 "u:_getdiskusage", _keywords,
13699 &path))
13700 goto exit;
13701 return_value = os__getdiskusage_impl(module, path);
13702
13703exit:
13704 return return_value;
13705}
13706
13707static PyObject *
13708os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
13709/*[clinic end generated code: output=054c972179b13708 input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013710{
13711 BOOL retval;
13712 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013713
13714 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +010013715 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013716 Py_END_ALLOW_THREADS
13717 if (retval == 0)
13718 return PyErr_SetFromWindowsErr(0);
13719
13720 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
13721}
Larry Hastings2f936352014-08-05 14:04:04 +100013722#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013723
13724
Fred Drakec9680921999-12-13 16:37:25 +000013725/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
13726 * It maps strings representing configuration variable names to
13727 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000013728 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000013729 * rarely-used constants. There are three separate tables that use
13730 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000013731 *
13732 * This code is always included, even if none of the interfaces that
13733 * need it are included. The #if hackery needed to avoid it would be
13734 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000013735 */
13736struct constdef {
13737 char *name;
13738 long value;
13739};
13740
Fred Drake12c6e2d1999-12-14 21:25:03 +000013741static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000013742conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000013743 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000013744{
Christian Heimes217cfd12007-12-02 14:31:20 +000013745 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +000013746 *valuep = PyLong_AS_LONG(arg);
13747 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000013748 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000013749 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000013750 /* look up the value in the table using a binary search */
13751 size_t lo = 0;
13752 size_t mid;
13753 size_t hi = tablesize;
13754 int cmp;
13755 const char *confname;
13756 if (!PyUnicode_Check(arg)) {
13757 PyErr_SetString(PyExc_TypeError,
13758 "configuration names must be strings or integers");
13759 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000013760 }
Stefan Krah0e803b32010-11-26 16:16:47 +000013761 confname = _PyUnicode_AsString(arg);
13762 if (confname == NULL)
13763 return 0;
13764 while (lo < hi) {
13765 mid = (lo + hi) / 2;
13766 cmp = strcmp(confname, table[mid].name);
13767 if (cmp < 0)
13768 hi = mid;
13769 else if (cmp > 0)
13770 lo = mid + 1;
13771 else {
13772 *valuep = table[mid].value;
13773 return 1;
13774 }
13775 }
13776 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
13777 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000013778 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000013779}
13780
13781
13782#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
13783static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000013784#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013785 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000013786#endif
13787#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013788 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000013789#endif
Fred Drakec9680921999-12-13 16:37:25 +000013790#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013791 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013792#endif
13793#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000013794 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000013795#endif
13796#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000013797 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000013798#endif
13799#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000013800 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000013801#endif
13802#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013803 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013804#endif
13805#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000013806 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000013807#endif
13808#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000013809 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000013810#endif
13811#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013812 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013813#endif
13814#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013815 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000013816#endif
13817#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013818 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013819#endif
13820#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000013821 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000013822#endif
13823#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013824 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013825#endif
13826#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000013827 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000013828#endif
13829#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013830 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013831#endif
13832#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000013833 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000013834#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000013835#ifdef _PC_ACL_ENABLED
13836 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
13837#endif
13838#ifdef _PC_MIN_HOLE_SIZE
13839 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
13840#endif
13841#ifdef _PC_ALLOC_SIZE_MIN
13842 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
13843#endif
13844#ifdef _PC_REC_INCR_XFER_SIZE
13845 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
13846#endif
13847#ifdef _PC_REC_MAX_XFER_SIZE
13848 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
13849#endif
13850#ifdef _PC_REC_MIN_XFER_SIZE
13851 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
13852#endif
13853#ifdef _PC_REC_XFER_ALIGN
13854 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
13855#endif
13856#ifdef _PC_SYMLINK_MAX
13857 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
13858#endif
13859#ifdef _PC_XATTR_ENABLED
13860 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
13861#endif
13862#ifdef _PC_XATTR_EXISTS
13863 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
13864#endif
13865#ifdef _PC_TIMESTAMP_RESOLUTION
13866 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
13867#endif
Fred Drakec9680921999-12-13 16:37:25 +000013868};
13869
Fred Drakec9680921999-12-13 16:37:25 +000013870static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000013871conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000013872{
13873 return conv_confname(arg, valuep, posix_constants_pathconf,
13874 sizeof(posix_constants_pathconf)
13875 / sizeof(struct constdef));
13876}
13877#endif
13878
Larry Hastings2f936352014-08-05 14:04:04 +100013879
Fred Drakec9680921999-12-13 16:37:25 +000013880#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100013881/*[clinic input]
13882os.fpathconf -> long
13883
13884 fd: int
13885 name: path_confname
13886 /
13887
13888Return the configuration limit name for the file descriptor fd.
13889
13890If there is no limit, return -1.
13891[clinic start generated code]*/
13892
13893PyDoc_STRVAR(os_fpathconf__doc__,
13894"fpathconf($module, fd, name, /)\n"
13895"--\n"
13896"\n"
13897"Return the configuration limit name for the file descriptor fd.\n"
13898"\n"
13899"If there is no limit, return -1.");
13900
13901#define OS_FPATHCONF_METHODDEF \
13902 {"fpathconf", (PyCFunction)os_fpathconf, METH_VARARGS, os_fpathconf__doc__},
13903
13904static long
13905os_fpathconf_impl(PyModuleDef *module, int fd, int name);
Fred Drakec9680921999-12-13 16:37:25 +000013906
13907static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013908os_fpathconf(PyModuleDef *module, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000013909{
Larry Hastings2f936352014-08-05 14:04:04 +100013910 PyObject *return_value = NULL;
13911 int fd;
13912 int name;
13913 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000013914
Larry Hastings2f936352014-08-05 14:04:04 +100013915 if (!PyArg_ParseTuple(args,
13916 "iO&:fpathconf",
13917 &fd, conv_path_confname, &name))
13918 goto exit;
13919 _return_value = os_fpathconf_impl(module, fd, name);
13920 if ((_return_value == -1) && PyErr_Occurred())
13921 goto exit;
13922 return_value = PyLong_FromLong(_return_value);
Fred Drakec9680921999-12-13 16:37:25 +000013923
Larry Hastings2f936352014-08-05 14:04:04 +100013924exit:
13925 return return_value;
Fred Drakec9680921999-12-13 16:37:25 +000013926}
Larry Hastings2f936352014-08-05 14:04:04 +100013927
13928static long
13929os_fpathconf_impl(PyModuleDef *module, int fd, int name)
13930/*[clinic end generated code: output=3bf04b40e0523a8c input=5942a024d3777810]*/
13931{
13932 long limit;
13933
13934 errno = 0;
13935 limit = fpathconf(fd, name);
13936 if (limit == -1 && errno != 0)
13937 posix_error();
13938
13939 return limit;
13940}
13941#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000013942
13943
13944#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100013945/*[clinic input]
13946os.pathconf -> long
13947 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
13948 name: path_confname
13949
13950Return the configuration limit name for the file or directory path.
13951
13952If there is no limit, return -1.
13953On some platforms, path may also be specified as an open file descriptor.
13954 If this functionality is unavailable, using it raises an exception.
13955[clinic start generated code]*/
13956
13957PyDoc_STRVAR(os_pathconf__doc__,
13958"pathconf($module, /, path, name)\n"
13959"--\n"
13960"\n"
13961"Return the configuration limit name for the file or directory path.\n"
13962"\n"
13963"If there is no limit, return -1.\n"
13964"On some platforms, path may also be specified as an open file descriptor.\n"
13965" If this functionality is unavailable, using it raises an exception.");
13966
13967#define OS_PATHCONF_METHODDEF \
13968 {"pathconf", (PyCFunction)os_pathconf, METH_VARARGS|METH_KEYWORDS, os_pathconf__doc__},
13969
13970static long
13971os_pathconf_impl(PyModuleDef *module, path_t *path, int name);
Fred Drakec9680921999-12-13 16:37:25 +000013972
13973static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013974os_pathconf(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +000013975{
Larry Hastings2f936352014-08-05 14:04:04 +100013976 PyObject *return_value = NULL;
13977 static char *_keywords[] = {"path", "name", NULL};
13978 path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF);
Fred Drakec9680921999-12-13 16:37:25 +000013979 int name;
Larry Hastings2f936352014-08-05 14:04:04 +100013980 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000013981
Larry Hastings2f936352014-08-05 14:04:04 +100013982 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13983 "O&O&:pathconf", _keywords,
13984 path_converter, &path, conv_path_confname, &name))
13985 goto exit;
13986 _return_value = os_pathconf_impl(module, &path, name);
13987 if ((_return_value == -1) && PyErr_Occurred())
13988 goto exit;
13989 return_value = PyLong_FromLong(_return_value);
13990
13991exit:
13992 /* Cleanup for path */
13993 path_cleanup(&path);
13994
13995 return return_value;
13996}
13997
13998static long
13999os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
14000/*[clinic end generated code: output=1a53e125b6cf63e4 input=bc3e2a985af27e5e]*/
14001{
Victor Stinner8c62be82010-05-06 00:08:46 +000014002 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000014003
Victor Stinner8c62be82010-05-06 00:08:46 +000014004 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020014005#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100014006 if (path->fd != -1)
14007 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020014008 else
14009#endif
Larry Hastings2f936352014-08-05 14:04:04 +100014010 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000014011 if (limit == -1 && errno != 0) {
14012 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000014013 /* could be a path or name problem */
14014 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000014015 else
Larry Hastings2f936352014-08-05 14:04:04 +100014016 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000014017 }
Larry Hastings2f936352014-08-05 14:04:04 +100014018
14019 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000014020}
Larry Hastings2f936352014-08-05 14:04:04 +100014021#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000014022
14023#ifdef HAVE_CONFSTR
14024static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000014025#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000014026 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000014027#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000014028#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014029 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000014030#endif
14031#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014032 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000014033#endif
Fred Draked86ed291999-12-15 15:34:33 +000014034#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014035 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000014036#endif
14037#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000014038 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000014039#endif
14040#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014041 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000014042#endif
14043#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014044 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014045#endif
Fred Drakec9680921999-12-13 16:37:25 +000014046#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014047 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014048#endif
14049#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014050 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014051#endif
14052#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014053 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014054#endif
14055#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014056 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014057#endif
14058#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014059 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014060#endif
14061#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014062 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014063#endif
14064#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014065 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014066#endif
14067#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014068 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014069#endif
Fred Draked86ed291999-12-15 15:34:33 +000014070#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000014071 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000014072#endif
Fred Drakec9680921999-12-13 16:37:25 +000014073#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000014074 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000014075#endif
Fred Draked86ed291999-12-15 15:34:33 +000014076#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000014077 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000014078#endif
14079#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014080 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000014081#endif
14082#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014083 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000014084#endif
14085#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014086 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000014087#endif
Fred Drakec9680921999-12-13 16:37:25 +000014088#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014089 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014090#endif
14091#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014092 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014093#endif
14094#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014095 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014096#endif
14097#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014098 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014099#endif
14100#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014101 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014102#endif
14103#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014104 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014105#endif
14106#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014107 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014108#endif
14109#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014110 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014111#endif
14112#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014113 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014114#endif
14115#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014116 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014117#endif
14118#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014119 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014120#endif
14121#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014122 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014123#endif
14124#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014125 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014126#endif
14127#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014128 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014129#endif
14130#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014131 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014132#endif
14133#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014134 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014135#endif
Fred Draked86ed291999-12-15 15:34:33 +000014136#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014137 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014138#endif
14139#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000014140 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000014141#endif
14142#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000014143 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000014144#endif
14145#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014146 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014147#endif
14148#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014149 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014150#endif
14151#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000014152 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000014153#endif
14154#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014155 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000014156#endif
14157#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000014158 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000014159#endif
14160#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014161 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014162#endif
14163#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000014164 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000014165#endif
14166#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014167 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014168#endif
14169#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014170 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000014171#endif
14172#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000014173 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000014174#endif
Fred Drakec9680921999-12-13 16:37:25 +000014175};
14176
14177static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014178conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000014179{
14180 return conv_confname(arg, valuep, posix_constants_confstr,
14181 sizeof(posix_constants_confstr)
14182 / sizeof(struct constdef));
14183}
14184
Larry Hastings2f936352014-08-05 14:04:04 +100014185
14186/*[clinic input]
14187os.confstr
14188
14189 name: confstr_confname
14190 /
14191
14192Return a string-valued system configuration variable.
14193[clinic start generated code]*/
14194
14195PyDoc_STRVAR(os_confstr__doc__,
14196"confstr($module, name, /)\n"
14197"--\n"
14198"\n"
14199"Return a string-valued system configuration variable.");
14200
14201#define OS_CONFSTR_METHODDEF \
14202 {"confstr", (PyCFunction)os_confstr, METH_VARARGS, os_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000014203
14204static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014205os_confstr_impl(PyModuleDef *module, int name);
14206
14207static PyObject *
14208os_confstr(PyModuleDef *module, PyObject *args)
14209{
14210 PyObject *return_value = NULL;
14211 int name;
14212
14213 if (!PyArg_ParseTuple(args,
14214 "O&:confstr",
14215 conv_confstr_confname, &name))
14216 goto exit;
14217 return_value = os_confstr_impl(module, name);
14218
14219exit:
14220 return return_value;
14221}
14222
14223static PyObject *
14224os_confstr_impl(PyModuleDef *module, int name)
14225/*[clinic end generated code: output=3f5e8aba9f8e3174 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000014226{
14227 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000014228 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020014229 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000014230
Victor Stinnercb043522010-09-10 23:49:04 +000014231 errno = 0;
14232 len = confstr(name, buffer, sizeof(buffer));
14233 if (len == 0) {
14234 if (errno) {
14235 posix_error();
14236 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000014237 }
14238 else {
Victor Stinnercb043522010-09-10 23:49:04 +000014239 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000014240 }
14241 }
Victor Stinnercb043522010-09-10 23:49:04 +000014242
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020014243 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010014244 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000014245 char *buf = PyMem_Malloc(len);
14246 if (buf == NULL)
14247 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010014248 len2 = confstr(name, buf, len);
14249 assert(len == len2);
Victor Stinnercb043522010-09-10 23:49:04 +000014250 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
14251 PyMem_Free(buf);
14252 }
14253 else
14254 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000014255 return result;
14256}
Larry Hastings2f936352014-08-05 14:04:04 +100014257#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000014258
14259
14260#ifdef HAVE_SYSCONF
14261static struct constdef posix_constants_sysconf[] = {
14262#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000014263 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000014264#endif
14265#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000014266 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000014267#endif
14268#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014269 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014270#endif
14271#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014272 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014273#endif
14274#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014275 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014276#endif
14277#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000014278 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000014279#endif
14280#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014281 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000014282#endif
14283#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014284 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014285#endif
14286#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000014287 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000014288#endif
14289#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014290 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014291#endif
Fred Draked86ed291999-12-15 15:34:33 +000014292#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014293 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000014294#endif
14295#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000014296 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000014297#endif
Fred Drakec9680921999-12-13 16:37:25 +000014298#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014299 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014300#endif
Fred Drakec9680921999-12-13 16:37:25 +000014301#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014302 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014303#endif
14304#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014305 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014306#endif
14307#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014308 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014309#endif
14310#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014311 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014312#endif
14313#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014314 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014315#endif
Fred Draked86ed291999-12-15 15:34:33 +000014316#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014317 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000014318#endif
Fred Drakec9680921999-12-13 16:37:25 +000014319#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000014320 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000014321#endif
14322#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014323 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014324#endif
14325#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014326 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014327#endif
14328#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014329 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014330#endif
14331#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014332 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014333#endif
Fred Draked86ed291999-12-15 15:34:33 +000014334#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000014335 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000014336#endif
Fred Drakec9680921999-12-13 16:37:25 +000014337#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014338 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014339#endif
14340#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014341 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014342#endif
14343#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014344 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014345#endif
14346#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014347 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014348#endif
14349#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014350 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014351#endif
14352#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000014353 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000014354#endif
14355#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014356 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014357#endif
14358#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014359 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014360#endif
14361#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000014362 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000014363#endif
14364#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014365 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014366#endif
14367#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014368 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000014369#endif
14370#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014371 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000014372#endif
14373#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014374 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014375#endif
14376#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014377 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014378#endif
14379#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014380 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014381#endif
14382#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014383 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014384#endif
14385#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014386 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000014387#endif
14388#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014389 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014390#endif
14391#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014392 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014393#endif
14394#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000014395 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000014396#endif
14397#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014398 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014399#endif
14400#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014401 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000014402#endif
14403#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014404 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000014405#endif
Fred Draked86ed291999-12-15 15:34:33 +000014406#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000014407 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000014408#endif
Fred Drakec9680921999-12-13 16:37:25 +000014409#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014410 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014411#endif
14412#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014413 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014414#endif
14415#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014416 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014417#endif
Fred Draked86ed291999-12-15 15:34:33 +000014418#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014419 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000014420#endif
Fred Drakec9680921999-12-13 16:37:25 +000014421#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000014422 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000014423#endif
Fred Draked86ed291999-12-15 15:34:33 +000014424#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000014425 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000014426#endif
14427#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000014428 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000014429#endif
Fred Drakec9680921999-12-13 16:37:25 +000014430#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014431 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014432#endif
14433#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014434 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014435#endif
14436#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014437 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014438#endif
14439#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014440 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014441#endif
Fred Draked86ed291999-12-15 15:34:33 +000014442#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000014443 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000014444#endif
Fred Drakec9680921999-12-13 16:37:25 +000014445#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000014446 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000014447#endif
14448#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000014449 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000014450#endif
14451#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014452 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014453#endif
14454#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000014455 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000014456#endif
14457#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000014458 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000014459#endif
14460#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000014461 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000014462#endif
14463#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000014464 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000014465#endif
Fred Draked86ed291999-12-15 15:34:33 +000014466#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000014467 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000014468#endif
Fred Drakec9680921999-12-13 16:37:25 +000014469#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014470 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014471#endif
14472#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014473 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014474#endif
Fred Draked86ed291999-12-15 15:34:33 +000014475#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014476 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000014477#endif
Fred Drakec9680921999-12-13 16:37:25 +000014478#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014479 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014480#endif
14481#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014482 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014483#endif
14484#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014485 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014486#endif
14487#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014488 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014489#endif
14490#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014491 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014492#endif
14493#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014494 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014495#endif
14496#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014497 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014498#endif
14499#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000014500 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000014501#endif
14502#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000014503 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000014504#endif
Fred Draked86ed291999-12-15 15:34:33 +000014505#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000014506 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000014507#endif
14508#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000014509 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000014510#endif
Fred Drakec9680921999-12-13 16:37:25 +000014511#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000014512 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000014513#endif
14514#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014515 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014516#endif
14517#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014518 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014519#endif
14520#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014521 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014522#endif
14523#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014524 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014525#endif
14526#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000014527 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000014528#endif
14529#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000014530 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000014531#endif
14532#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000014533 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000014534#endif
14535#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000014536 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000014537#endif
14538#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000014539 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000014540#endif
14541#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000014542 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000014543#endif
14544#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014545 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000014546#endif
14547#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014548 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000014549#endif
14550#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000014551 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000014552#endif
14553#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000014554 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000014555#endif
14556#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000014557 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000014558#endif
14559#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000014560 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000014561#endif
14562#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014563 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014564#endif
14565#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000014566 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000014567#endif
14568#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000014569 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000014570#endif
14571#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014572 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014573#endif
14574#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014575 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014576#endif
14577#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000014578 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000014579#endif
14580#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014581 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014582#endif
14583#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014584 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014585#endif
14586#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014587 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000014588#endif
14589#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000014590 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000014591#endif
14592#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014593 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014594#endif
14595#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014596 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014597#endif
14598#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014599 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000014600#endif
14601#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014602 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014603#endif
14604#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014605 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014606#endif
14607#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014608 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014609#endif
14610#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014611 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014612#endif
14613#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014614 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014615#endif
Fred Draked86ed291999-12-15 15:34:33 +000014616#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000014617 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000014618#endif
Fred Drakec9680921999-12-13 16:37:25 +000014619#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000014620 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000014621#endif
14622#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014623 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014624#endif
14625#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000014626 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000014627#endif
14628#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014629 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014630#endif
14631#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014632 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014633#endif
14634#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000014635 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000014636#endif
14637#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000014638 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000014639#endif
14640#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014641 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014642#endif
14643#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000014644 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000014645#endif
14646#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014647 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014648#endif
14649#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000014650 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000014651#endif
14652#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014653 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000014654#endif
14655#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014656 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000014657#endif
14658#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000014659 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000014660#endif
14661#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000014662 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000014663#endif
14664#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014665 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014666#endif
14667#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014668 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014669#endif
14670#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000014671 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000014672#endif
14673#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014674 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014675#endif
14676#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014677 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014678#endif
14679#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014680 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014681#endif
14682#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014683 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014684#endif
14685#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014686 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014687#endif
14688#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014689 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014690#endif
14691#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000014692 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000014693#endif
14694#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014695 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014696#endif
14697#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014698 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014699#endif
14700#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014701 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014702#endif
14703#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014704 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014705#endif
14706#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000014707 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000014708#endif
14709#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000014710 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000014711#endif
14712#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000014713 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000014714#endif
14715#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000014716 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000014717#endif
14718#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000014719 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000014720#endif
14721#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000014722 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000014723#endif
14724#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000014725 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000014726#endif
14727#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014728 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000014729#endif
14730#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000014731 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000014732#endif
14733#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000014734 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000014735#endif
14736#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000014737 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000014738#endif
14739#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014740 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014741#endif
14742#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014743 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014744#endif
14745#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000014746 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000014747#endif
14748#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000014749 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000014750#endif
14751#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000014752 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000014753#endif
14754};
14755
14756static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014757conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000014758{
14759 return conv_confname(arg, valuep, posix_constants_sysconf,
14760 sizeof(posix_constants_sysconf)
14761 / sizeof(struct constdef));
14762}
14763
Larry Hastings2f936352014-08-05 14:04:04 +100014764
14765/*[clinic input]
14766os.sysconf -> long
14767 name: sysconf_confname
14768 /
14769
14770Return an integer-valued system configuration variable.
14771[clinic start generated code]*/
14772
14773PyDoc_STRVAR(os_sysconf__doc__,
14774"sysconf($module, name, /)\n"
14775"--\n"
14776"\n"
14777"Return an integer-valued system configuration variable.");
14778
14779#define OS_SYSCONF_METHODDEF \
14780 {"sysconf", (PyCFunction)os_sysconf, METH_VARARGS, os_sysconf__doc__},
14781
14782static long
14783os_sysconf_impl(PyModuleDef *module, int name);
Fred Drakec9680921999-12-13 16:37:25 +000014784
14785static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014786os_sysconf(PyModuleDef *module, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000014787{
Larry Hastings2f936352014-08-05 14:04:04 +100014788 PyObject *return_value = NULL;
Fred Drakec9680921999-12-13 16:37:25 +000014789 int name;
Larry Hastings2f936352014-08-05 14:04:04 +100014790 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014791
Larry Hastings2f936352014-08-05 14:04:04 +100014792 if (!PyArg_ParseTuple(args,
14793 "O&:sysconf",
14794 conv_sysconf_confname, &name))
14795 goto exit;
14796 _return_value = os_sysconf_impl(module, name);
14797 if ((_return_value == -1) && PyErr_Occurred())
14798 goto exit;
14799 return_value = PyLong_FromLong(_return_value);
Fred Drakec9680921999-12-13 16:37:25 +000014800
Larry Hastings2f936352014-08-05 14:04:04 +100014801exit:
14802 return return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014803}
Larry Hastings2f936352014-08-05 14:04:04 +100014804
14805static long
14806os_sysconf_impl(PyModuleDef *module, int name)
14807/*[clinic end generated code: output=7b06dfdc472431e4 input=279e3430a33f29e4]*/
14808{
14809 long value;
14810
14811 errno = 0;
14812 value = sysconf(name);
14813 if (value == -1 && errno != 0)
14814 posix_error();
14815 return value;
14816}
14817#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000014818
14819
Fred Drakebec628d1999-12-15 18:31:10 +000014820/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020014821 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000014822 * the exported dictionaries that are used to publish information about the
14823 * names available on the host platform.
14824 *
14825 * Sorting the table at runtime ensures that the table is properly ordered
14826 * when used, even for platforms we're not able to test on. It also makes
14827 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000014828 */
Fred Drakebec628d1999-12-15 18:31:10 +000014829
14830static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014831cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000014832{
14833 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000014834 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000014835 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000014836 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000014837
14838 return strcmp(c1->name, c2->name);
14839}
14840
14841static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014842setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000014843 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000014844{
Fred Drakebec628d1999-12-15 18:31:10 +000014845 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000014846 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000014847
14848 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
14849 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000014850 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000014851 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000014852
Barry Warsaw3155db32000-04-13 15:20:40 +000014853 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000014854 PyObject *o = PyLong_FromLong(table[i].value);
14855 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
14856 Py_XDECREF(o);
14857 Py_DECREF(d);
14858 return -1;
14859 }
14860 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000014861 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000014862 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000014863}
14864
Fred Drakebec628d1999-12-15 18:31:10 +000014865/* Return -1 on failure, 0 on success. */
14866static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000014867setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000014868{
14869#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000014870 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000014871 sizeof(posix_constants_pathconf)
14872 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000014873 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000014874 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000014875#endif
14876#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000014877 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000014878 sizeof(posix_constants_confstr)
14879 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000014880 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000014881 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000014882#endif
14883#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000014884 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000014885 sizeof(posix_constants_sysconf)
14886 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000014887 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000014888 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000014889#endif
Fred Drakebec628d1999-12-15 18:31:10 +000014890 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000014891}
Fred Draked86ed291999-12-15 15:34:33 +000014892
14893
Larry Hastings2f936352014-08-05 14:04:04 +100014894/*[clinic input]
14895os.abort
14896
14897Abort the interpreter immediately.
14898
14899This function 'dumps core' or otherwise fails in the hardest way possible
14900on the hosting operating system. This function never returns.
14901[clinic start generated code]*/
14902
14903PyDoc_STRVAR(os_abort__doc__,
14904"abort($module, /)\n"
14905"--\n"
14906"\n"
14907"Abort the interpreter immediately.\n"
14908"\n"
14909"This function \'dumps core\' or otherwise fails in the hardest way possible\n"
14910"on the hosting operating system. This function never returns.");
14911
14912#define OS_ABORT_METHODDEF \
14913 {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014914
14915static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014916os_abort_impl(PyModuleDef *module);
14917
14918static PyObject *
14919os_abort(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
14920{
14921 return os_abort_impl(module);
14922}
14923
14924static PyObject *
14925os_abort_impl(PyModuleDef *module)
14926/*[clinic end generated code: output=cded2cc8c5453d3a input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014927{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014928 abort();
14929 /*NOTREACHED*/
14930 Py_FatalError("abort() called from Python code didn't abort!");
14931 return NULL;
14932}
Fred Drakebec628d1999-12-15 18:31:10 +000014933
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000014934#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100014935/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000014936PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100014937"startfile(filepath [, operation])\n\
14938\n\
14939Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000014940\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000014941When \"operation\" is not specified or \"open\", this acts like\n\
14942double-clicking the file in Explorer, or giving the file name as an\n\
14943argument to the DOS \"start\" command: the file is opened with whatever\n\
14944application (if any) its extension is associated.\n\
14945When another \"operation\" is given, it specifies what should be done with\n\
14946the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000014947\n\
14948startfile returns as soon as the associated application is launched.\n\
14949There is no option to wait for the application to close, and no way\n\
14950to retrieve the application's exit status.\n\
14951\n\
14952The filepath is relative to the current directory. If you want to use\n\
14953an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000014954the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000014955
Steve Dower7d0e0c92015-01-24 08:18:24 -080014956/* Grab ShellExecute dynamically from shell32 */
14957static int has_ShellExecute = -1;
14958static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
14959 LPCSTR, INT);
14960static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
14961 LPCWSTR, INT);
14962static int
14963check_ShellExecute()
14964{
14965 HINSTANCE hShell32;
14966
14967 /* only recheck */
14968 if (-1 == has_ShellExecute) {
14969 Py_BEGIN_ALLOW_THREADS
14970 hShell32 = LoadLibraryW(L"SHELL32");
14971 Py_END_ALLOW_THREADS
14972 if (hShell32) {
14973 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
14974 "ShellExecuteA");
14975 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
14976 "ShellExecuteW");
14977 has_ShellExecute = Py_ShellExecuteA &&
14978 Py_ShellExecuteW;
14979 } else {
14980 has_ShellExecute = 0;
14981 }
14982 }
14983 return has_ShellExecute;
14984}
14985
14986
Tim Petersf58a7aa2000-09-22 10:05:54 +000014987static PyObject *
14988win32_startfile(PyObject *self, PyObject *args)
14989{
Victor Stinner8c62be82010-05-06 00:08:46 +000014990 PyObject *ofilepath;
14991 char *filepath;
14992 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020014993 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000014994 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000014995
Victor Stinnereb5657a2011-09-30 01:44:27 +020014996 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080014997
14998 if(!check_ShellExecute()) {
14999 /* If the OS doesn't have ShellExecute, return a
15000 NotImplementedError. */
15001 return PyErr_Format(PyExc_NotImplementedError,
15002 "startfile not available on this platform");
15003 }
15004
Victor Stinner8c62be82010-05-06 00:08:46 +000015005 if (!PyArg_ParseTuple(args, "U|s:startfile",
15006 &unipath, &operation)) {
15007 PyErr_Clear();
15008 goto normal;
15009 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000015010
Victor Stinner8c62be82010-05-06 00:08:46 +000015011 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020015012 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000015013 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020015014 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000015015 PyErr_Clear();
15016 operation = NULL;
15017 goto normal;
15018 }
15019 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000015020
Victor Stinnereb5657a2011-09-30 01:44:27 +020015021 wpath = PyUnicode_AsUnicode(unipath);
15022 if (wpath == NULL)
15023 goto normal;
15024 if (uoperation) {
15025 woperation = PyUnicode_AsUnicode(uoperation);
15026 if (woperation == NULL)
15027 goto normal;
15028 }
15029 else
15030 woperation = NULL;
15031
Victor Stinner8c62be82010-05-06 00:08:46 +000015032 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080015033 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
15034 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000015035 Py_END_ALLOW_THREADS
15036
Victor Stinnereb5657a2011-09-30 01:44:27 +020015037 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000015038 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020015039 win32_error_object("startfile", unipath);
15040 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000015041 }
15042 Py_INCREF(Py_None);
15043 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015044
15045normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000015046 if (!PyArg_ParseTuple(args, "O&|s:startfile",
15047 PyUnicode_FSConverter, &ofilepath,
15048 &operation))
15049 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010015050 if (win32_warn_bytes_api()) {
15051 Py_DECREF(ofilepath);
15052 return NULL;
15053 }
Victor Stinner8c62be82010-05-06 00:08:46 +000015054 filepath = PyBytes_AsString(ofilepath);
15055 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080015056 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
15057 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000015058 Py_END_ALLOW_THREADS
15059 if (rc <= (HINSTANCE)32) {
15060 PyObject *errval = win32_error("startfile", filepath);
15061 Py_DECREF(ofilepath);
15062 return errval;
15063 }
15064 Py_DECREF(ofilepath);
15065 Py_INCREF(Py_None);
15066 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000015067}
Larry Hastings2f936352014-08-05 14:04:04 +100015068#endif /* MS_WINDOWS */
15069
Fred Drake5ab8eaf1999-12-09 21:13:07 +000015070
Martin v. Löwis438b5342002-12-27 10:16:42 +000015071#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100015072/*[clinic input]
15073os.getloadavg
15074
15075Return average recent system load information.
15076
15077Return the number of processes in the system run queue averaged over
15078the last 1, 5, and 15 minutes as a tuple of three floats.
15079Raises OSError if the load average was unobtainable.
15080[clinic start generated code]*/
15081
15082PyDoc_STRVAR(os_getloadavg__doc__,
15083"getloadavg($module, /)\n"
15084"--\n"
15085"\n"
15086"Return average recent system load information.\n"
15087"\n"
15088"Return the number of processes in the system run queue averaged over\n"
15089"the last 1, 5, and 15 minutes as a tuple of three floats.\n"
15090"Raises OSError if the load average was unobtainable.");
15091
15092#define OS_GETLOADAVG_METHODDEF \
15093 {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000015094
15095static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015096os_getloadavg_impl(PyModuleDef *module);
15097
15098static PyObject *
15099os_getloadavg(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15100{
15101 return os_getloadavg_impl(module);
15102}
15103
15104static PyObject *
15105os_getloadavg_impl(PyModuleDef *module)
15106/*[clinic end generated code: output=67593a92457d55af input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000015107{
15108 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000015109 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000015110 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
15111 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000015112 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000015113 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000015114}
Larry Hastings2f936352014-08-05 14:04:04 +100015115#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000015116
Larry Hastings2f936352014-08-05 14:04:04 +100015117
15118/*[clinic input]
15119os.device_encoding
15120 fd: int
15121
15122Return a string describing the encoding of a terminal's file descriptor.
15123
15124The file descriptor must be attached to a terminal.
15125If the device is not a terminal, return None.
15126[clinic start generated code]*/
15127
15128PyDoc_STRVAR(os_device_encoding__doc__,
15129"device_encoding($module, /, fd)\n"
15130"--\n"
15131"\n"
15132"Return a string describing the encoding of a terminal\'s file descriptor.\n"
15133"\n"
15134"The file descriptor must be attached to a terminal.\n"
15135"If the device is not a terminal, return None.");
15136
15137#define OS_DEVICE_ENCODING_METHODDEF \
15138 {"device_encoding", (PyCFunction)os_device_encoding, METH_VARARGS|METH_KEYWORDS, os_device_encoding__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015139
15140static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015141os_device_encoding_impl(PyModuleDef *module, int fd);
15142
15143static PyObject *
15144os_device_encoding(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015145{
Larry Hastings2f936352014-08-05 14:04:04 +100015146 PyObject *return_value = NULL;
15147 static char *_keywords[] = {"fd", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +000015148 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050015149
Larry Hastings2f936352014-08-05 14:04:04 +100015150 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15151 "i:device_encoding", _keywords,
15152 &fd))
15153 goto exit;
15154 return_value = os_device_encoding_impl(module, fd);
Brett Cannonefb00c02012-02-29 18:31:31 -050015155
Larry Hastings2f936352014-08-05 14:04:04 +100015156exit:
15157 return return_value;
15158}
15159
15160static PyObject *
15161os_device_encoding_impl(PyModuleDef *module, int fd)
15162/*[clinic end generated code: output=e9f8274d42f5cce3 input=9e1d4a42b66df312]*/
15163{
Brett Cannonefb00c02012-02-29 18:31:31 -050015164 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015165}
15166
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015167
Larry Hastings2f936352014-08-05 14:04:04 +100015168#ifdef HAVE_SETRESUID
15169/*[clinic input]
15170os.setresuid
15171
15172 ruid: uid_t
15173 euid: uid_t
15174 suid: uid_t
15175 /
15176
15177Set the current process's real, effective, and saved user ids.
15178[clinic start generated code]*/
15179
15180PyDoc_STRVAR(os_setresuid__doc__,
15181"setresuid($module, ruid, euid, suid, /)\n"
15182"--\n"
15183"\n"
15184"Set the current process\'s real, effective, and saved user ids.");
15185
15186#define OS_SETRESUID_METHODDEF \
15187 {"setresuid", (PyCFunction)os_setresuid, METH_VARARGS, os_setresuid__doc__},
15188
15189static PyObject *
15190os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid);
15191
15192static PyObject *
15193os_setresuid(PyModuleDef *module, PyObject *args)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015194{
Larry Hastings2f936352014-08-05 14:04:04 +100015195 PyObject *return_value = NULL;
15196 uid_t ruid;
15197 uid_t euid;
15198 uid_t suid;
15199
15200 if (!PyArg_ParseTuple(args,
15201 "O&O&O&:setresuid",
15202 _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid))
15203 goto exit;
15204 return_value = os_setresuid_impl(module, ruid, euid, suid);
15205
15206exit:
15207 return return_value;
15208}
15209
15210static PyObject *
15211os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
15212/*[clinic end generated code: output=2e3457cfe7cd1f94 input=9e33cb79a82792f3]*/
15213{
Victor Stinner8c62be82010-05-06 00:08:46 +000015214 if (setresuid(ruid, euid, suid) < 0)
15215 return posix_error();
15216 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015217}
Larry Hastings2f936352014-08-05 14:04:04 +100015218#endif /* HAVE_SETRESUID */
15219
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015220
15221#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100015222/*[clinic input]
15223os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015224
Larry Hastings2f936352014-08-05 14:04:04 +100015225 rgid: gid_t
15226 egid: gid_t
15227 sgid: gid_t
15228 /
15229
15230Set the current process's real, effective, and saved group ids.
15231[clinic start generated code]*/
15232
15233PyDoc_STRVAR(os_setresgid__doc__,
15234"setresgid($module, rgid, egid, sgid, /)\n"
15235"--\n"
15236"\n"
15237"Set the current process\'s real, effective, and saved group ids.");
15238
15239#define OS_SETRESGID_METHODDEF \
15240 {"setresgid", (PyCFunction)os_setresgid, METH_VARARGS, os_setresgid__doc__},
15241
15242static PyObject *
15243os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid);
15244
15245static PyObject *
15246os_setresgid(PyModuleDef *module, PyObject *args)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015247{
Larry Hastings2f936352014-08-05 14:04:04 +100015248 PyObject *return_value = NULL;
15249 gid_t rgid;
15250 gid_t egid;
15251 gid_t sgid;
15252
15253 if (!PyArg_ParseTuple(args,
15254 "O&O&O&:setresgid",
15255 _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid))
15256 goto exit;
15257 return_value = os_setresgid_impl(module, rgid, egid, sgid);
15258
15259exit:
15260 return return_value;
15261}
15262
15263static PyObject *
15264os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
15265/*[clinic end generated code: output=8a7ee6c1f2482362 input=33e9e0785ef426b1]*/
15266{
Victor Stinner8c62be82010-05-06 00:08:46 +000015267 if (setresgid(rgid, egid, sgid) < 0)
15268 return posix_error();
15269 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015270}
Larry Hastings2f936352014-08-05 14:04:04 +100015271#endif /* HAVE_SETRESGID */
15272
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015273
15274#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100015275/*[clinic input]
15276os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015277
Larry Hastings2f936352014-08-05 14:04:04 +100015278Return a tuple of the current process's real, effective, and saved user ids.
15279[clinic start generated code]*/
15280
15281PyDoc_STRVAR(os_getresuid__doc__,
15282"getresuid($module, /)\n"
15283"--\n"
15284"\n"
15285"Return a tuple of the current process\'s real, effective, and saved user ids.");
15286
15287#define OS_GETRESUID_METHODDEF \
15288 {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__},
15289
15290static PyObject *
15291os_getresuid_impl(PyModuleDef *module);
15292
15293static PyObject *
15294os_getresuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15295{
15296 return os_getresuid_impl(module);
15297}
15298
15299static PyObject *
15300os_getresuid_impl(PyModuleDef *module)
15301/*[clinic end generated code: output=d0786686a6ef1320 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015302{
Victor Stinner8c62be82010-05-06 00:08:46 +000015303 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000015304 if (getresuid(&ruid, &euid, &suid) < 0)
15305 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020015306 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
15307 _PyLong_FromUid(euid),
15308 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015309}
Larry Hastings2f936352014-08-05 14:04:04 +100015310#endif /* HAVE_GETRESUID */
15311
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015312
15313#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100015314/*[clinic input]
15315os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015316
Larry Hastings2f936352014-08-05 14:04:04 +100015317Return a tuple of the current process's real, effective, and saved group ids.
15318[clinic start generated code]*/
15319
15320PyDoc_STRVAR(os_getresgid__doc__,
15321"getresgid($module, /)\n"
15322"--\n"
15323"\n"
15324"Return a tuple of the current process\'s real, effective, and saved group ids.");
15325
15326#define OS_GETRESGID_METHODDEF \
15327 {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__},
15328
15329static PyObject *
15330os_getresgid_impl(PyModuleDef *module);
15331
15332static PyObject *
15333os_getresgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015334{
Larry Hastings2f936352014-08-05 14:04:04 +100015335 return os_getresgid_impl(module);
15336}
15337
15338static PyObject *
15339os_getresgid_impl(PyModuleDef *module)
15340/*[clinic end generated code: output=05249ac795fa759f input=517e68db9ca32df6]*/
15341{
15342 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000015343 if (getresgid(&rgid, &egid, &sgid) < 0)
15344 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020015345 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
15346 _PyLong_FromGid(egid),
15347 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015348}
Larry Hastings2f936352014-08-05 14:04:04 +100015349#endif /* HAVE_GETRESGID */
15350
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015351
Benjamin Peterson9428d532011-09-14 11:45:52 -040015352#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100015353/*[clinic input]
15354os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040015355
Larry Hastings2f936352014-08-05 14:04:04 +100015356 path: path_t(allow_fd=True)
15357 attribute: path_t
15358 *
15359 follow_symlinks: bool = True
15360
15361Return the value of extended attribute attribute on path.
15362
15363path may be either a string or an open file descriptor.
15364If follow_symlinks is False, and the last element of the path is a symbolic
15365 link, getxattr will examine the symbolic link itself instead of the file
15366 the link points to.
15367
15368[clinic start generated code]*/
15369
15370PyDoc_STRVAR(os_getxattr__doc__,
15371"getxattr($module, /, path, attribute, *, follow_symlinks=True)\n"
15372"--\n"
15373"\n"
15374"Return the value of extended attribute attribute on path.\n"
15375"\n"
15376"path may be either a string or an open file descriptor.\n"
15377"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15378" link, getxattr will examine the symbolic link itself instead of the file\n"
15379" the link points to.");
15380
15381#define OS_GETXATTR_METHODDEF \
15382 {"getxattr", (PyCFunction)os_getxattr, METH_VARARGS|METH_KEYWORDS, os_getxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015383
15384static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015385os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks);
15386
15387static PyObject *
15388os_getxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015389{
Larry Hastings2f936352014-08-05 14:04:04 +100015390 PyObject *return_value = NULL;
15391 static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL};
15392 path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1);
15393 path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015394 int follow_symlinks = 1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015395
Larry Hastings2f936352014-08-05 14:04:04 +100015396 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15397 "O&O&|$p:getxattr", _keywords,
15398 path_converter, &path, path_converter, &attribute, &follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015399 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +100015400 return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks);
15401
15402exit:
15403 /* Cleanup for path */
15404 path_cleanup(&path);
15405 /* Cleanup for attribute */
15406 path_cleanup(&attribute);
15407
15408 return return_value;
15409}
15410
15411static PyObject *
15412os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
15413/*[clinic end generated code: output=bbc9454fe2b9ea86 input=8c8ea3bab78d89c2]*/
15414{
15415 Py_ssize_t i;
15416 PyObject *buffer = NULL;
15417
15418 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
15419 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015420
Larry Hastings9cf065c2012-06-22 16:30:09 -070015421 for (i = 0; ; i++) {
15422 void *ptr;
15423 ssize_t result;
15424 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
15425 Py_ssize_t buffer_size = buffer_sizes[i];
15426 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100015427 path_error(path);
15428 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015429 }
15430 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
15431 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100015432 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015433 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015434
Larry Hastings9cf065c2012-06-22 16:30:09 -070015435 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015436 if (path->fd >= 0)
15437 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015438 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100015439 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015440 else
Larry Hastings2f936352014-08-05 14:04:04 +100015441 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015442 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015443
Larry Hastings9cf065c2012-06-22 16:30:09 -070015444 if (result < 0) {
15445 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015446 if (errno == ERANGE)
15447 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100015448 path_error(path);
15449 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015450 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015451
Larry Hastings9cf065c2012-06-22 16:30:09 -070015452 if (result != buffer_size) {
15453 /* Can only shrink. */
15454 _PyBytes_Resize(&buffer, result);
15455 }
15456 break;
15457 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015458
Larry Hastings9cf065c2012-06-22 16:30:09 -070015459 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015460}
15461
Larry Hastings2f936352014-08-05 14:04:04 +100015462
15463/*[clinic input]
15464os.setxattr
15465
15466 path: path_t(allow_fd=True)
15467 attribute: path_t
15468 value: Py_buffer
15469 flags: int = 0
15470 *
15471 follow_symlinks: bool = True
15472
15473Set extended attribute attribute on path to value.
15474
15475path may be either a string or an open file descriptor.
15476If follow_symlinks is False, and the last element of the path is a symbolic
15477 link, setxattr will modify the symbolic link itself instead of the file
15478 the link points to.
15479
15480[clinic start generated code]*/
15481
15482PyDoc_STRVAR(os_setxattr__doc__,
15483"setxattr($module, /, path, attribute, value, flags=0, *,\n"
15484" follow_symlinks=True)\n"
15485"--\n"
15486"\n"
15487"Set extended attribute attribute on path to value.\n"
15488"\n"
15489"path may be either a string or an open file descriptor.\n"
15490"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15491" link, setxattr will modify the symbolic link itself instead of the file\n"
15492" the link points to.");
15493
15494#define OS_SETXATTR_METHODDEF \
15495 {"setxattr", (PyCFunction)os_setxattr, METH_VARARGS|METH_KEYWORDS, os_setxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015496
15497static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015498os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks);
15499
15500static PyObject *
15501os_setxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015502{
Larry Hastings2f936352014-08-05 14:04:04 +100015503 PyObject *return_value = NULL;
15504 static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL};
15505 path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1);
15506 path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0);
15507 Py_buffer value = {NULL, NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -070015508 int flags = 0;
15509 int follow_symlinks = 1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015510
Larry Hastings2f936352014-08-05 14:04:04 +100015511 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15512 "O&O&y*|i$p:setxattr", _keywords,
15513 path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015514 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +100015515 return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015516
Larry Hastings9cf065c2012-06-22 16:30:09 -070015517exit:
Larry Hastings2f936352014-08-05 14:04:04 +100015518 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015519 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +100015520 /* Cleanup for attribute */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015521 path_cleanup(&attribute);
Larry Hastings2f936352014-08-05 14:04:04 +100015522 /* Cleanup for value */
15523 if (value.obj)
15524 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015525
Larry Hastings9cf065c2012-06-22 16:30:09 -070015526 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015527}
15528
Benjamin Peterson799bd802011-08-31 22:15:17 -040015529static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015530os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks)
15531/*[clinic end generated code: output=2ff845d8e024b218 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040015532{
Larry Hastings2f936352014-08-05 14:04:04 +100015533 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015534
Larry Hastings2f936352014-08-05 14:04:04 +100015535 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040015536 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015537
Benjamin Peterson799bd802011-08-31 22:15:17 -040015538 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015539 if (path->fd > -1)
15540 result = fsetxattr(path->fd, attribute->narrow,
15541 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015542 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100015543 result = setxattr(path->narrow, attribute->narrow,
15544 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015545 else
Larry Hastings2f936352014-08-05 14:04:04 +100015546 result = lsetxattr(path->narrow, attribute->narrow,
15547 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015548 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015549
Larry Hastings9cf065c2012-06-22 16:30:09 -070015550 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100015551 path_error(path);
15552 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015553 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015554
Larry Hastings2f936352014-08-05 14:04:04 +100015555 Py_RETURN_NONE;
15556}
15557
15558
15559/*[clinic input]
15560os.removexattr
15561
15562 path: path_t(allow_fd=True)
15563 attribute: path_t
15564 *
15565 follow_symlinks: bool = True
15566
15567Remove extended attribute attribute on path.
15568
15569path may be either a string or an open file descriptor.
15570If follow_symlinks is False, and the last element of the path is a symbolic
15571 link, removexattr will modify the symbolic link itself instead of the file
15572 the link points to.
15573
15574[clinic start generated code]*/
15575
15576PyDoc_STRVAR(os_removexattr__doc__,
15577"removexattr($module, /, path, attribute, *, follow_symlinks=True)\n"
15578"--\n"
15579"\n"
15580"Remove extended attribute attribute on path.\n"
15581"\n"
15582"path may be either a string or an open file descriptor.\n"
15583"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15584" link, removexattr will modify the symbolic link itself instead of the file\n"
15585" the link points to.");
15586
15587#define OS_REMOVEXATTR_METHODDEF \
15588 {"removexattr", (PyCFunction)os_removexattr, METH_VARARGS|METH_KEYWORDS, os_removexattr__doc__},
15589
15590static PyObject *
15591os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks);
15592
15593static PyObject *
15594os_removexattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
15595{
15596 PyObject *return_value = NULL;
15597 static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL};
15598 path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1);
15599 path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0);
15600 int follow_symlinks = 1;
15601
15602 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15603 "O&O&|$p:removexattr", _keywords,
15604 path_converter, &path, path_converter, &attribute, &follow_symlinks))
15605 goto exit;
15606 return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015607
Larry Hastings9cf065c2012-06-22 16:30:09 -070015608exit:
Larry Hastings2f936352014-08-05 14:04:04 +100015609 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015610 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +100015611 /* Cleanup for attribute */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015612 path_cleanup(&attribute);
15613
15614 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015615}
15616
Larry Hastings2f936352014-08-05 14:04:04 +100015617static PyObject *
15618os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
15619/*[clinic end generated code: output=8dfc715bf607c4cf input=cdb54834161e3329]*/
15620{
15621 ssize_t result;
15622
15623 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
15624 return NULL;
15625
15626 Py_BEGIN_ALLOW_THREADS;
15627 if (path->fd > -1)
15628 result = fremovexattr(path->fd, attribute->narrow);
15629 else if (follow_symlinks)
15630 result = removexattr(path->narrow, attribute->narrow);
15631 else
15632 result = lremovexattr(path->narrow, attribute->narrow);
15633 Py_END_ALLOW_THREADS;
15634
15635 if (result) {
15636 return path_error(path);
15637 }
15638
15639 Py_RETURN_NONE;
15640}
15641
15642
15643/*[clinic input]
15644os.listxattr
15645
15646 path: path_t(allow_fd=True, nullable=True) = None
15647 *
15648 follow_symlinks: bool = True
15649
15650Return a list of extended attributes on path.
15651
15652path may be either None, a string, or an open file descriptor.
15653if path is None, listxattr will examine the current directory.
15654If follow_symlinks is False, and the last element of the path is a symbolic
15655 link, listxattr will examine the symbolic link itself instead of the file
15656 the link points to.
15657[clinic start generated code]*/
15658
15659PyDoc_STRVAR(os_listxattr__doc__,
15660"listxattr($module, /, path=None, *, follow_symlinks=True)\n"
15661"--\n"
15662"\n"
15663"Return a list of extended attributes on path.\n"
15664"\n"
15665"path may be either None, a string, or an open file descriptor.\n"
15666"if path is None, listxattr will examine the current directory.\n"
15667"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15668" link, listxattr will examine the symbolic link itself instead of the file\n"
15669" the link points to.");
15670
15671#define OS_LISTXATTR_METHODDEF \
15672 {"listxattr", (PyCFunction)os_listxattr, METH_VARARGS|METH_KEYWORDS, os_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015673
15674static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015675os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks);
15676
15677static PyObject *
15678os_listxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015679{
Larry Hastings2f936352014-08-05 14:04:04 +100015680 PyObject *return_value = NULL;
15681 static char *_keywords[] = {"path", "follow_symlinks", NULL};
15682 path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015683 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +100015684
15685 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15686 "|O&$p:listxattr", _keywords,
15687 path_converter, &path, &follow_symlinks))
15688 goto exit;
15689 return_value = os_listxattr_impl(module, &path, follow_symlinks);
15690
15691exit:
15692 /* Cleanup for path */
15693 path_cleanup(&path);
15694
15695 return return_value;
15696}
15697
15698static PyObject *
15699os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
15700/*[clinic end generated code: output=3104cafda1a3d887 input=08cca53ac0b07c13]*/
15701{
Larry Hastings9cf065c2012-06-22 16:30:09 -070015702 Py_ssize_t i;
15703 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100015704 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015705 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015706
Larry Hastings2f936352014-08-05 14:04:04 +100015707 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015708 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015709
Larry Hastings2f936352014-08-05 14:04:04 +100015710 name = path->narrow ? path->narrow : ".";
15711
Larry Hastings9cf065c2012-06-22 16:30:09 -070015712 for (i = 0; ; i++) {
15713 char *start, *trace, *end;
15714 ssize_t length;
15715 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
15716 Py_ssize_t buffer_size = buffer_sizes[i];
15717 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020015718 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100015719 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015720 break;
15721 }
15722 buffer = PyMem_MALLOC(buffer_size);
15723 if (!buffer) {
15724 PyErr_NoMemory();
15725 break;
15726 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015727
Larry Hastings9cf065c2012-06-22 16:30:09 -070015728 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015729 if (path->fd > -1)
15730 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015731 else if (follow_symlinks)
15732 length = listxattr(name, buffer, buffer_size);
15733 else
15734 length = llistxattr(name, buffer, buffer_size);
15735 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015736
Larry Hastings9cf065c2012-06-22 16:30:09 -070015737 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020015738 if (errno == ERANGE) {
15739 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050015740 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015741 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020015742 }
Larry Hastings2f936352014-08-05 14:04:04 +100015743 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015744 break;
15745 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015746
Larry Hastings9cf065c2012-06-22 16:30:09 -070015747 result = PyList_New(0);
15748 if (!result) {
15749 goto exit;
15750 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015751
Larry Hastings9cf065c2012-06-22 16:30:09 -070015752 end = buffer + length;
15753 for (trace = start = buffer; trace != end; trace++) {
15754 if (!*trace) {
15755 int error;
15756 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
15757 trace - start);
15758 if (!attribute) {
15759 Py_DECREF(result);
15760 result = NULL;
15761 goto exit;
15762 }
15763 error = PyList_Append(result, attribute);
15764 Py_DECREF(attribute);
15765 if (error) {
15766 Py_DECREF(result);
15767 result = NULL;
15768 goto exit;
15769 }
15770 start = trace + 1;
15771 }
15772 }
15773 break;
15774 }
15775exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070015776 if (buffer)
15777 PyMem_FREE(buffer);
15778 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015779}
Benjamin Peterson9428d532011-09-14 11:45:52 -040015780#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040015781
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015782
Larry Hastings2f936352014-08-05 14:04:04 +100015783/*[clinic input]
15784os.urandom
15785
15786 size: Py_ssize_t
15787 /
15788
15789Return a bytes object containing random bytes suitable for cryptographic use.
15790[clinic start generated code]*/
15791
15792PyDoc_STRVAR(os_urandom__doc__,
15793"urandom($module, size, /)\n"
15794"--\n"
15795"\n"
15796"Return a bytes object containing random bytes suitable for cryptographic use.");
15797
15798#define OS_URANDOM_METHODDEF \
15799 {"urandom", (PyCFunction)os_urandom, METH_VARARGS, os_urandom__doc__},
Georg Brandl2fb477c2012-02-21 00:33:36 +010015800
15801static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015802os_urandom_impl(PyModuleDef *module, Py_ssize_t size);
Georg Brandl2fb477c2012-02-21 00:33:36 +010015803
Larry Hastings2f936352014-08-05 14:04:04 +100015804static PyObject *
15805os_urandom(PyModuleDef *module, PyObject *args)
15806{
15807 PyObject *return_value = NULL;
15808 Py_ssize_t size;
15809
15810 if (!PyArg_ParseTuple(args,
15811 "n:urandom",
15812 &size))
15813 goto exit;
15814 return_value = os_urandom_impl(module, size);
15815
15816exit:
15817 return return_value;
15818}
15819
15820static PyObject *
15821os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
15822/*[clinic end generated code: output=5dbff582cab94cb9 input=4067cdb1b6776c29]*/
15823{
15824 PyObject *bytes;
15825 int result;
15826
Georg Brandl2fb477c2012-02-21 00:33:36 +010015827 if (size < 0)
15828 return PyErr_Format(PyExc_ValueError,
15829 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100015830 bytes = PyBytes_FromStringAndSize(NULL, size);
15831 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010015832 return NULL;
15833
Larry Hastings2f936352014-08-05 14:04:04 +100015834 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
15835 PyBytes_GET_SIZE(bytes));
15836 if (result == -1) {
15837 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010015838 return NULL;
15839 }
Larry Hastings2f936352014-08-05 14:04:04 +100015840 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010015841}
15842
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015843/* Terminal size querying */
15844
15845static PyTypeObject TerminalSizeType;
15846
15847PyDoc_STRVAR(TerminalSize_docstring,
15848 "A tuple of (columns, lines) for holding terminal window size");
15849
15850static PyStructSequence_Field TerminalSize_fields[] = {
15851 {"columns", "width of the terminal window in characters"},
15852 {"lines", "height of the terminal window in characters"},
15853 {NULL, NULL}
15854};
15855
15856static PyStructSequence_Desc TerminalSize_desc = {
15857 "os.terminal_size",
15858 TerminalSize_docstring,
15859 TerminalSize_fields,
15860 2,
15861};
15862
15863#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100015864/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015865PyDoc_STRVAR(termsize__doc__,
15866 "Return the size of the terminal window as (columns, lines).\n" \
15867 "\n" \
15868 "The optional argument fd (default standard output) specifies\n" \
15869 "which file descriptor should be queried.\n" \
15870 "\n" \
15871 "If the file descriptor is not connected to a terminal, an OSError\n" \
15872 "is thrown.\n" \
15873 "\n" \
15874 "This function will only be defined if an implementation is\n" \
15875 "available for this system.\n" \
15876 "\n" \
15877 "shutil.get_terminal_size is the high-level function which should \n" \
15878 "normally be used, os.get_terminal_size is the low-level implementation.");
15879
15880static PyObject*
15881get_terminal_size(PyObject *self, PyObject *args)
15882{
15883 int columns, lines;
15884 PyObject *termsize;
15885
15886 int fd = fileno(stdout);
15887 /* Under some conditions stdout may not be connected and
15888 * fileno(stdout) may point to an invalid file descriptor. For example
15889 * GUI apps don't have valid standard streams by default.
15890 *
15891 * If this happens, and the optional fd argument is not present,
15892 * the ioctl below will fail returning EBADF. This is what we want.
15893 */
15894
15895 if (!PyArg_ParseTuple(args, "|i", &fd))
15896 return NULL;
15897
15898#ifdef TERMSIZE_USE_IOCTL
15899 {
15900 struct winsize w;
15901 if (ioctl(fd, TIOCGWINSZ, &w))
15902 return PyErr_SetFromErrno(PyExc_OSError);
15903 columns = w.ws_col;
15904 lines = w.ws_row;
15905 }
15906#endif /* TERMSIZE_USE_IOCTL */
15907
15908#ifdef TERMSIZE_USE_CONIO
15909 {
15910 DWORD nhandle;
15911 HANDLE handle;
15912 CONSOLE_SCREEN_BUFFER_INFO csbi;
15913 switch (fd) {
15914 case 0: nhandle = STD_INPUT_HANDLE;
15915 break;
15916 case 1: nhandle = STD_OUTPUT_HANDLE;
15917 break;
15918 case 2: nhandle = STD_ERROR_HANDLE;
15919 break;
15920 default:
15921 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
15922 }
15923 handle = GetStdHandle(nhandle);
15924 if (handle == NULL)
15925 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
15926 if (handle == INVALID_HANDLE_VALUE)
15927 return PyErr_SetFromWindowsErr(0);
15928
15929 if (!GetConsoleScreenBufferInfo(handle, &csbi))
15930 return PyErr_SetFromWindowsErr(0);
15931
15932 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
15933 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
15934 }
15935#endif /* TERMSIZE_USE_CONIO */
15936
15937 termsize = PyStructSequence_New(&TerminalSizeType);
15938 if (termsize == NULL)
15939 return NULL;
15940 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
15941 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
15942 if (PyErr_Occurred()) {
15943 Py_DECREF(termsize);
15944 return NULL;
15945 }
15946 return termsize;
15947}
15948#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
15949
Larry Hastings2f936352014-08-05 14:04:04 +100015950
15951/*[clinic input]
15952os.cpu_count
15953
15954Return the number of CPUs in the system; return None if indeterminable.
15955[clinic start generated code]*/
15956
15957PyDoc_STRVAR(os_cpu_count__doc__,
15958"cpu_count($module, /)\n"
15959"--\n"
15960"\n"
15961"Return the number of CPUs in the system; return None if indeterminable.");
15962
15963#define OS_CPU_COUNT_METHODDEF \
15964 {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__},
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015965
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015966static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015967os_cpu_count_impl(PyModuleDef *module);
15968
15969static PyObject *
15970os_cpu_count(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15971{
15972 return os_cpu_count_impl(module);
15973}
15974
15975static PyObject *
15976os_cpu_count_impl(PyModuleDef *module)
15977/*[clinic end generated code: output=92e2a4a729eb7740 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015978{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020015979 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015980#ifdef MS_WINDOWS
15981 SYSTEM_INFO sysinfo;
15982 GetSystemInfo(&sysinfo);
15983 ncpu = sysinfo.dwNumberOfProcessors;
15984#elif defined(__hpux)
15985 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
15986#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
15987 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015988#elif defined(__DragonFly__) || \
15989 defined(__OpenBSD__) || \
15990 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020015991 defined(__NetBSD__) || \
15992 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020015993 int mib[2];
15994 size_t len = sizeof(ncpu);
15995 mib[0] = CTL_HW;
15996 mib[1] = HW_NCPU;
15997 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
15998 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020015999#endif
16000 if (ncpu >= 1)
16001 return PyLong_FromLong(ncpu);
16002 else
16003 Py_RETURN_NONE;
16004}
16005
Victor Stinnerdaf45552013-08-28 00:53:59 +020016006
Larry Hastings2f936352014-08-05 14:04:04 +100016007/*[clinic input]
16008os.get_inheritable -> bool
16009
16010 fd: int
16011 /
16012
16013Get the close-on-exe flag of the specified file descriptor.
16014[clinic start generated code]*/
16015
16016PyDoc_STRVAR(os_get_inheritable__doc__,
16017"get_inheritable($module, fd, /)\n"
16018"--\n"
16019"\n"
16020"Get the close-on-exe flag of the specified file descriptor.");
16021
16022#define OS_GET_INHERITABLE_METHODDEF \
16023 {"get_inheritable", (PyCFunction)os_get_inheritable, METH_VARARGS, os_get_inheritable__doc__},
16024
16025static int
16026os_get_inheritable_impl(PyModuleDef *module, int fd);
16027
16028static PyObject *
16029os_get_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016030{
Larry Hastings2f936352014-08-05 14:04:04 +100016031 PyObject *return_value = NULL;
16032 int fd;
16033 int _return_value;
16034
16035 if (!PyArg_ParseTuple(args,
16036 "i:get_inheritable",
16037 &fd))
16038 goto exit;
16039 _return_value = os_get_inheritable_impl(module, fd);
16040 if ((_return_value == -1) && PyErr_Occurred())
16041 goto exit;
16042 return_value = PyBool_FromLong((long)_return_value);
16043
16044exit:
16045 return return_value;
16046}
16047
16048static int
16049os_get_inheritable_impl(PyModuleDef *module, int fd)
16050/*[clinic end generated code: output=261d1dd2b0dbdc35 input=89ac008dc9ab6b95]*/
16051{
16052 if (!_PyVerify_fd(fd)){
16053 posix_error();
16054 return -1;
16055 }
16056
16057 return _Py_get_inheritable(fd);
16058}
16059
16060
16061/*[clinic input]
16062os.set_inheritable
16063 fd: int
16064 inheritable: int
16065 /
16066
16067Set the inheritable flag of the specified file descriptor.
16068[clinic start generated code]*/
16069
16070PyDoc_STRVAR(os_set_inheritable__doc__,
16071"set_inheritable($module, fd, inheritable, /)\n"
16072"--\n"
16073"\n"
16074"Set the inheritable flag of the specified file descriptor.");
16075
16076#define OS_SET_INHERITABLE_METHODDEF \
16077 {"set_inheritable", (PyCFunction)os_set_inheritable, METH_VARARGS, os_set_inheritable__doc__},
16078
16079static PyObject *
16080os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable);
16081
16082static PyObject *
16083os_set_inheritable(PyModuleDef *module, PyObject *args)
16084{
16085 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016086 int fd;
16087 int inheritable;
16088
Larry Hastings2f936352014-08-05 14:04:04 +100016089 if (!PyArg_ParseTuple(args,
16090 "ii:set_inheritable",
16091 &fd, &inheritable))
16092 goto exit;
16093 return_value = os_set_inheritable_impl(module, fd, inheritable);
Victor Stinnerdaf45552013-08-28 00:53:59 +020016094
Larry Hastings2f936352014-08-05 14:04:04 +100016095exit:
16096 return return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016097}
16098
Larry Hastings2f936352014-08-05 14:04:04 +100016099static PyObject *
16100os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
16101/*[clinic end generated code: output=64dfe5e15c906539 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020016102{
Victor Stinnerdaf45552013-08-28 00:53:59 +020016103 if (!_PyVerify_fd(fd))
16104 return posix_error();
16105
16106 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
16107 return NULL;
16108 Py_RETURN_NONE;
16109}
16110
16111
16112#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100016113/*[clinic input]
16114os.get_handle_inheritable -> bool
16115 handle: Py_intptr_t
16116 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020016117
Larry Hastings2f936352014-08-05 14:04:04 +100016118Get the close-on-exe flag of the specified file descriptor.
16119[clinic start generated code]*/
16120
16121PyDoc_STRVAR(os_get_handle_inheritable__doc__,
16122"get_handle_inheritable($module, handle, /)\n"
16123"--\n"
16124"\n"
16125"Get the close-on-exe flag of the specified file descriptor.");
16126
16127#define OS_GET_HANDLE_INHERITABLE_METHODDEF \
16128 {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_VARARGS, os_get_handle_inheritable__doc__},
16129
16130static int
16131os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle);
16132
16133static PyObject *
16134os_get_handle_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016135{
Larry Hastings2f936352014-08-05 14:04:04 +100016136 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016137 Py_intptr_t handle;
Larry Hastings2f936352014-08-05 14:04:04 +100016138 int _return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016139
Larry Hastings2f936352014-08-05 14:04:04 +100016140 if (!PyArg_ParseTuple(args,
16141 "" _Py_PARSE_INTPTR ":get_handle_inheritable",
16142 &handle))
16143 goto exit;
16144 _return_value = os_get_handle_inheritable_impl(module, handle);
16145 if ((_return_value == -1) && PyErr_Occurred())
16146 goto exit;
16147 return_value = PyBool_FromLong((long)_return_value);
16148
16149exit:
16150 return return_value;
16151}
16152
16153static int
16154os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
16155/*[clinic end generated code: output=d5bf9d86900bf457 input=5f7759443aae3dc5]*/
16156{
16157 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016158
16159 if (!GetHandleInformation((HANDLE)handle, &flags)) {
16160 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100016161 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016162 }
16163
Larry Hastings2f936352014-08-05 14:04:04 +100016164 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016165}
16166
Victor Stinnerdaf45552013-08-28 00:53:59 +020016167
Larry Hastings2f936352014-08-05 14:04:04 +100016168/*[clinic input]
16169os.set_handle_inheritable
16170 handle: Py_intptr_t
16171 inheritable: bool
16172 /
16173
16174Set the inheritable flag of the specified handle.
16175[clinic start generated code]*/
16176
16177PyDoc_STRVAR(os_set_handle_inheritable__doc__,
16178"set_handle_inheritable($module, handle, inheritable, /)\n"
16179"--\n"
16180"\n"
16181"Set the inheritable flag of the specified handle.");
16182
16183#define OS_SET_HANDLE_INHERITABLE_METHODDEF \
16184 {"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__},
16185
16186static PyObject *
16187os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable);
16188
16189static PyObject *
16190os_set_handle_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016191{
Larry Hastings2f936352014-08-05 14:04:04 +100016192 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016193 Py_intptr_t handle;
Larry Hastings2f936352014-08-05 14:04:04 +100016194 int inheritable;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016195
Larry Hastings2f936352014-08-05 14:04:04 +100016196 if (!PyArg_ParseTuple(args,
16197 "" _Py_PARSE_INTPTR "p:set_handle_inheritable",
16198 &handle, &inheritable))
16199 goto exit;
16200 return_value = os_set_handle_inheritable_impl(module, handle, inheritable);
Victor Stinnerdaf45552013-08-28 00:53:59 +020016201
Larry Hastings2f936352014-08-05 14:04:04 +100016202exit:
16203 return return_value;
16204}
16205
16206static PyObject *
16207os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable)
16208/*[clinic end generated code: output=ee5fcc6d9f0d4f8b input=e64b2b2730469def]*/
16209{
16210 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016211 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
16212 PyErr_SetFromWindowsErr(0);
16213 return NULL;
16214 }
16215 Py_RETURN_NONE;
16216}
Larry Hastings2f936352014-08-05 14:04:04 +100016217#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010016218
Victor Stinner1db9e7b2014-07-29 22:32:47 +020016219#ifndef MS_WINDOWS
16220PyDoc_STRVAR(get_blocking__doc__,
16221 "get_blocking(fd) -> bool\n" \
16222 "\n" \
16223 "Get the blocking mode of the file descriptor:\n" \
16224 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
16225
16226static PyObject*
16227posix_get_blocking(PyObject *self, PyObject *args)
16228{
16229 int fd;
16230 int blocking;
16231
16232 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
16233 return NULL;
16234
16235 if (!_PyVerify_fd(fd))
16236 return posix_error();
16237
16238 blocking = _Py_get_blocking(fd);
16239 if (blocking < 0)
16240 return NULL;
16241 return PyBool_FromLong(blocking);
16242}
16243
16244PyDoc_STRVAR(set_blocking__doc__,
16245 "set_blocking(fd, blocking)\n" \
16246 "\n" \
16247 "Set the blocking mode of the specified file descriptor.\n" \
16248 "Set the O_NONBLOCK flag if blocking is False,\n" \
16249 "clear the O_NONBLOCK flag otherwise.");
16250
16251static PyObject*
16252posix_set_blocking(PyObject *self, PyObject *args)
16253{
16254 int fd, blocking;
16255
16256 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
16257 return NULL;
16258
16259 if (!_PyVerify_fd(fd))
16260 return posix_error();
16261
16262 if (_Py_set_blocking(fd, blocking) < 0)
16263 return NULL;
16264 Py_RETURN_NONE;
16265}
16266#endif /* !MS_WINDOWS */
16267
16268
Victor Stinner6036e442015-03-08 01:58:04 +010016269PyDoc_STRVAR(posix_scandir__doc__,
16270"scandir(path='.') -> iterator of DirEntry objects for given path");
16271
16272static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
16273
16274typedef struct {
16275 PyObject_HEAD
16276 PyObject *name;
16277 PyObject *path;
16278 PyObject *stat;
16279 PyObject *lstat;
16280#ifdef MS_WINDOWS
16281 struct _Py_stat_struct win32_lstat;
16282 __int64 win32_file_index;
16283 int got_file_index;
16284#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010016285#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010016286 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010016287#endif
Victor Stinner6036e442015-03-08 01:58:04 +010016288 ino_t d_ino;
16289#endif
16290} DirEntry;
16291
16292static void
16293DirEntry_dealloc(DirEntry *entry)
16294{
16295 Py_XDECREF(entry->name);
16296 Py_XDECREF(entry->path);
16297 Py_XDECREF(entry->stat);
16298 Py_XDECREF(entry->lstat);
16299 Py_TYPE(entry)->tp_free((PyObject *)entry);
16300}
16301
16302/* Forward reference */
16303static int
16304DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
16305
16306/* Set exception and return -1 on error, 0 for False, 1 for True */
16307static int
16308DirEntry_is_symlink(DirEntry *self)
16309{
16310#ifdef MS_WINDOWS
16311 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010016312#elif defined(HAVE_DIRENT_D_TYPE)
16313 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010016314 if (self->d_type != DT_UNKNOWN)
16315 return self->d_type == DT_LNK;
16316 else
16317 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010016318#else
16319 /* POSIX without d_type */
16320 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010016321#endif
16322}
16323
16324static PyObject *
16325DirEntry_py_is_symlink(DirEntry *self)
16326{
16327 int result;
16328
16329 result = DirEntry_is_symlink(self);
16330 if (result == -1)
16331 return NULL;
16332 return PyBool_FromLong(result);
16333}
16334
16335static PyObject *
16336DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
16337{
16338 int result;
16339 struct _Py_stat_struct st;
16340
16341#ifdef MS_WINDOWS
16342 wchar_t *path;
16343
16344 path = PyUnicode_AsUnicode(self->path);
16345 if (!path)
16346 return NULL;
16347
16348 if (follow_symlinks)
16349 result = win32_stat_w(path, &st);
16350 else
16351 result = win32_lstat_w(path, &st);
16352
16353 if (result != 0) {
16354 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
16355 0, self->path);
16356 }
16357#else /* POSIX */
16358 PyObject *bytes;
16359 char *path;
16360
16361 if (!PyUnicode_FSConverter(self->path, &bytes))
16362 return NULL;
16363 path = PyBytes_AS_STRING(bytes);
16364
16365 if (follow_symlinks)
16366 result = STAT(path, &st);
16367 else
16368 result = LSTAT(path, &st);
16369 Py_DECREF(bytes);
16370
16371 if (result != 0)
16372 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
16373#endif
16374
16375 return _pystat_fromstructstat(&st);
16376}
16377
16378static PyObject *
16379DirEntry_get_lstat(DirEntry *self)
16380{
16381 if (!self->lstat) {
16382#ifdef MS_WINDOWS
16383 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
16384#else /* POSIX */
16385 self->lstat = DirEntry_fetch_stat(self, 0);
16386#endif
16387 }
16388 Py_XINCREF(self->lstat);
16389 return self->lstat;
16390}
16391
16392static PyObject *
16393DirEntry_get_stat(DirEntry *self, int follow_symlinks)
16394{
16395 if (!follow_symlinks)
16396 return DirEntry_get_lstat(self);
16397
16398 if (!self->stat) {
16399 int result = DirEntry_is_symlink(self);
16400 if (result == -1)
16401 return NULL;
16402 else if (result)
16403 self->stat = DirEntry_fetch_stat(self, 1);
16404 else
16405 self->stat = DirEntry_get_lstat(self);
16406 }
16407
16408 Py_XINCREF(self->stat);
16409 return self->stat;
16410}
16411
16412static PyObject *
16413DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
16414{
16415 int follow_symlinks = 1;
16416
16417 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
16418 follow_symlinks_keywords, &follow_symlinks))
16419 return NULL;
16420
16421 return DirEntry_get_stat(self, follow_symlinks);
16422}
16423
16424/* Set exception and return -1 on error, 0 for False, 1 for True */
16425static int
16426DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
16427{
16428 PyObject *stat = NULL;
16429 PyObject *st_mode = NULL;
16430 long mode;
16431 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010016432#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010016433 int is_symlink;
16434 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010016435#endif
Victor Stinner6036e442015-03-08 01:58:04 +010016436#ifdef MS_WINDOWS
16437 unsigned long dir_bits;
16438#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010016439 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010016440
16441#ifdef MS_WINDOWS
16442 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
16443 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010016444#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010016445 is_symlink = self->d_type == DT_LNK;
16446 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
16447#endif
16448
Victor Stinner35a97c02015-03-08 02:59:09 +010016449#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010016450 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010016451#endif
Victor Stinner6036e442015-03-08 01:58:04 +010016452 stat = DirEntry_get_stat(self, follow_symlinks);
16453 if (!stat) {
16454 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
16455 /* If file doesn't exist (anymore), then return False
16456 (i.e., say it's not a file/directory) */
16457 PyErr_Clear();
16458 return 0;
16459 }
16460 goto error;
16461 }
16462 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
16463 if (!st_mode)
16464 goto error;
16465
16466 mode = PyLong_AsLong(st_mode);
16467 if (mode == -1 && PyErr_Occurred())
16468 goto error;
16469 Py_CLEAR(st_mode);
16470 Py_CLEAR(stat);
16471 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010016472#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010016473 }
16474 else if (is_symlink) {
16475 assert(mode_bits != S_IFLNK);
16476 result = 0;
16477 }
16478 else {
16479 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
16480#ifdef MS_WINDOWS
16481 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
16482 if (mode_bits == S_IFDIR)
16483 result = dir_bits != 0;
16484 else
16485 result = dir_bits == 0;
16486#else /* POSIX */
16487 if (mode_bits == S_IFDIR)
16488 result = self->d_type == DT_DIR;
16489 else
16490 result = self->d_type == DT_REG;
16491#endif
16492 }
Victor Stinner35a97c02015-03-08 02:59:09 +010016493#endif
Victor Stinner6036e442015-03-08 01:58:04 +010016494
16495 return result;
16496
16497error:
16498 Py_XDECREF(st_mode);
16499 Py_XDECREF(stat);
16500 return -1;
16501}
16502
16503static PyObject *
16504DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
16505{
16506 int result;
16507
16508 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
16509 if (result == -1)
16510 return NULL;
16511 return PyBool_FromLong(result);
16512}
16513
16514static PyObject *
16515DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
16516{
16517 int follow_symlinks = 1;
16518
16519 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
16520 follow_symlinks_keywords, &follow_symlinks))
16521 return NULL;
16522
16523 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
16524}
16525
16526static PyObject *
16527DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
16528{
16529 int follow_symlinks = 1;
16530
16531 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
16532 follow_symlinks_keywords, &follow_symlinks))
16533 return NULL;
16534
16535 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
16536}
16537
16538static PyObject *
16539DirEntry_inode(DirEntry *self)
16540{
16541#ifdef MS_WINDOWS
16542 if (!self->got_file_index) {
16543 wchar_t *path;
16544 struct _Py_stat_struct stat;
16545
16546 path = PyUnicode_AsUnicode(self->path);
16547 if (!path)
16548 return NULL;
16549
16550 if (win32_lstat_w(path, &stat) != 0) {
16551 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
16552 0, self->path);
16553 }
16554
16555 self->win32_file_index = stat.st_ino;
16556 self->got_file_index = 1;
16557 }
16558 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
16559#else /* POSIX */
16560#ifdef HAVE_LARGEFILE_SUPPORT
16561 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
16562#else
16563 return PyLong_FromLong((long)self->d_ino);
16564#endif
16565#endif
16566}
16567
16568static PyObject *
16569DirEntry_repr(DirEntry *self)
16570{
16571 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
16572}
16573
16574static PyMemberDef DirEntry_members[] = {
16575 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
16576 "the entry's base filename, relative to scandir() \"path\" argument"},
16577 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
16578 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
16579 {NULL}
16580};
16581
16582static PyMethodDef DirEntry_methods[] = {
16583 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
16584 "return True if the entry is a directory; cached per entry"
16585 },
16586 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
16587 "return True if the entry is a file; cached per entry"
16588 },
16589 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
16590 "return True if the entry is a symbolic link; cached per entry"
16591 },
16592 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
16593 "return stat_result object for the entry; cached per entry"
16594 },
16595 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
16596 "return inode of the entry; cached per entry",
16597 },
16598 {NULL}
16599};
16600
16601PyTypeObject DirEntryType = {
16602 PyVarObject_HEAD_INIT(NULL, 0)
16603 MODNAME ".DirEntry", /* tp_name */
16604 sizeof(DirEntry), /* tp_basicsize */
16605 0, /* tp_itemsize */
16606 /* methods */
16607 (destructor)DirEntry_dealloc, /* tp_dealloc */
16608 0, /* tp_print */
16609 0, /* tp_getattr */
16610 0, /* tp_setattr */
16611 0, /* tp_compare */
16612 (reprfunc)DirEntry_repr, /* tp_repr */
16613 0, /* tp_as_number */
16614 0, /* tp_as_sequence */
16615 0, /* tp_as_mapping */
16616 0, /* tp_hash */
16617 0, /* tp_call */
16618 0, /* tp_str */
16619 0, /* tp_getattro */
16620 0, /* tp_setattro */
16621 0, /* tp_as_buffer */
16622 Py_TPFLAGS_DEFAULT, /* tp_flags */
16623 0, /* tp_doc */
16624 0, /* tp_traverse */
16625 0, /* tp_clear */
16626 0, /* tp_richcompare */
16627 0, /* tp_weaklistoffset */
16628 0, /* tp_iter */
16629 0, /* tp_iternext */
16630 DirEntry_methods, /* tp_methods */
16631 DirEntry_members, /* tp_members */
16632};
16633
16634#ifdef MS_WINDOWS
16635
16636static wchar_t *
16637join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
16638{
16639 Py_ssize_t path_len;
16640 Py_ssize_t size;
16641 wchar_t *result;
16642 wchar_t ch;
16643
16644 if (!path_wide) { /* Default arg: "." */
16645 path_wide = L".";
16646 path_len = 1;
16647 }
16648 else {
16649 path_len = wcslen(path_wide);
16650 }
16651
16652 /* The +1's are for the path separator and the NUL */
16653 size = path_len + 1 + wcslen(filename) + 1;
16654 result = PyMem_New(wchar_t, size);
16655 if (!result) {
16656 PyErr_NoMemory();
16657 return NULL;
16658 }
16659 wcscpy(result, path_wide);
16660 if (path_len > 0) {
16661 ch = result[path_len - 1];
16662 if (ch != SEP && ch != ALTSEP && ch != L':')
16663 result[path_len++] = SEP;
16664 wcscpy(result + path_len, filename);
16665 }
16666 return result;
16667}
16668
16669static PyObject *
16670DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
16671{
16672 DirEntry *entry;
16673 BY_HANDLE_FILE_INFORMATION file_info;
16674 ULONG reparse_tag;
16675 wchar_t *joined_path;
16676
16677 entry = PyObject_New(DirEntry, &DirEntryType);
16678 if (!entry)
16679 return NULL;
16680 entry->name = NULL;
16681 entry->path = NULL;
16682 entry->stat = NULL;
16683 entry->lstat = NULL;
16684 entry->got_file_index = 0;
16685
16686 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
16687 if (!entry->name)
16688 goto error;
16689
16690 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
16691 if (!joined_path)
16692 goto error;
16693
16694 entry->path = PyUnicode_FromWideChar(joined_path, -1);
16695 PyMem_Free(joined_path);
16696 if (!entry->path)
16697 goto error;
16698
16699 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
16700 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
16701
16702 return (PyObject *)entry;
16703
16704error:
16705 Py_DECREF(entry);
16706 return NULL;
16707}
16708
16709#else /* POSIX */
16710
16711static char *
16712join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
16713{
16714 Py_ssize_t path_len;
16715 Py_ssize_t size;
16716 char *result;
16717
16718 if (!path_narrow) { /* Default arg: "." */
16719 path_narrow = ".";
16720 path_len = 1;
16721 }
16722 else {
16723 path_len = strlen(path_narrow);
16724 }
16725
16726 if (filename_len == -1)
16727 filename_len = strlen(filename);
16728
16729 /* The +1's are for the path separator and the NUL */
16730 size = path_len + 1 + filename_len + 1;
16731 result = PyMem_New(char, size);
16732 if (!result) {
16733 PyErr_NoMemory();
16734 return NULL;
16735 }
16736 strcpy(result, path_narrow);
16737 if (path_len > 0 && result[path_len - 1] != '/')
16738 result[path_len++] = '/';
16739 strcpy(result + path_len, filename);
16740 return result;
16741}
16742
16743static PyObject *
16744DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010016745 ino_t d_ino
16746#ifdef HAVE_DIRENT_D_TYPE
16747 , unsigned char d_type
16748#endif
16749 )
Victor Stinner6036e442015-03-08 01:58:04 +010016750{
16751 DirEntry *entry;
16752 char *joined_path;
16753
16754 entry = PyObject_New(DirEntry, &DirEntryType);
16755 if (!entry)
16756 return NULL;
16757 entry->name = NULL;
16758 entry->path = NULL;
16759 entry->stat = NULL;
16760 entry->lstat = NULL;
16761
16762 joined_path = join_path_filename(path->narrow, name, name_len);
16763 if (!joined_path)
16764 goto error;
16765
16766 if (!path->narrow || !PyBytes_Check(path->object)) {
16767 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
16768 entry->path = PyUnicode_DecodeFSDefault(joined_path);
16769 }
16770 else {
16771 entry->name = PyBytes_FromStringAndSize(name, name_len);
16772 entry->path = PyBytes_FromString(joined_path);
16773 }
16774 PyMem_Free(joined_path);
16775 if (!entry->name || !entry->path)
16776 goto error;
16777
Victor Stinner35a97c02015-03-08 02:59:09 +010016778#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010016779 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010016780#endif
Victor Stinner6036e442015-03-08 01:58:04 +010016781 entry->d_ino = d_ino;
16782
16783 return (PyObject *)entry;
16784
16785error:
16786 Py_XDECREF(entry);
16787 return NULL;
16788}
16789
16790#endif
16791
16792
16793typedef struct {
16794 PyObject_HEAD
16795 path_t path;
16796#ifdef MS_WINDOWS
16797 HANDLE handle;
16798 WIN32_FIND_DATAW file_data;
16799 int first_time;
16800#else /* POSIX */
16801 DIR *dirp;
16802#endif
16803} ScandirIterator;
16804
16805#ifdef MS_WINDOWS
16806
16807static void
16808ScandirIterator_close(ScandirIterator *iterator)
16809{
16810 if (iterator->handle == INVALID_HANDLE_VALUE)
16811 return;
16812
16813 Py_BEGIN_ALLOW_THREADS
16814 FindClose(iterator->handle);
16815 Py_END_ALLOW_THREADS
16816 iterator->handle = INVALID_HANDLE_VALUE;
16817}
16818
16819static PyObject *
16820ScandirIterator_iternext(ScandirIterator *iterator)
16821{
16822 WIN32_FIND_DATAW *file_data = &iterator->file_data;
16823 BOOL success;
16824
16825 /* Happens if the iterator is iterated twice */
16826 if (iterator->handle == INVALID_HANDLE_VALUE) {
16827 PyErr_SetNone(PyExc_StopIteration);
16828 return NULL;
16829 }
16830
16831 while (1) {
16832 if (!iterator->first_time) {
16833 Py_BEGIN_ALLOW_THREADS
16834 success = FindNextFileW(iterator->handle, file_data);
16835 Py_END_ALLOW_THREADS
16836 if (!success) {
16837 if (GetLastError() != ERROR_NO_MORE_FILES)
16838 return path_error(&iterator->path);
16839 /* No more files found in directory, stop iterating */
16840 break;
16841 }
16842 }
16843 iterator->first_time = 0;
16844
16845 /* Skip over . and .. */
16846 if (wcscmp(file_data->cFileName, L".") != 0 &&
16847 wcscmp(file_data->cFileName, L"..") != 0)
16848 return DirEntry_from_find_data(&iterator->path, file_data);
16849
16850 /* Loop till we get a non-dot directory or finish iterating */
16851 }
16852
16853 ScandirIterator_close(iterator);
16854
16855 PyErr_SetNone(PyExc_StopIteration);
16856 return NULL;
16857}
16858
16859#else /* POSIX */
16860
16861static void
16862ScandirIterator_close(ScandirIterator *iterator)
16863{
16864 if (!iterator->dirp)
16865 return;
16866
16867 Py_BEGIN_ALLOW_THREADS
16868 closedir(iterator->dirp);
16869 Py_END_ALLOW_THREADS
16870 iterator->dirp = NULL;
16871 return;
16872}
16873
16874static PyObject *
16875ScandirIterator_iternext(ScandirIterator *iterator)
16876{
16877 struct dirent *direntp;
16878 Py_ssize_t name_len;
16879 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010016880
16881 /* Happens if the iterator is iterated twice */
16882 if (!iterator->dirp) {
16883 PyErr_SetNone(PyExc_StopIteration);
16884 return NULL;
16885 }
16886
16887 while (1) {
16888 errno = 0;
16889 Py_BEGIN_ALLOW_THREADS
16890 direntp = readdir(iterator->dirp);
16891 Py_END_ALLOW_THREADS
16892
16893 if (!direntp) {
16894 if (errno != 0)
16895 return path_error(&iterator->path);
16896 /* No more files found in directory, stop iterating */
16897 break;
16898 }
16899
16900 /* Skip over . and .. */
16901 name_len = NAMLEN(direntp);
16902 is_dot = direntp->d_name[0] == '.' &&
16903 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
16904 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010016905 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010016906 name_len, direntp->d_ino
16907#ifdef HAVE_DIRENT_D_TYPE
16908 , direntp->d_type
16909#endif
16910 );
Victor Stinner6036e442015-03-08 01:58:04 +010016911 }
16912
16913 /* Loop till we get a non-dot directory or finish iterating */
16914 }
16915
16916 ScandirIterator_close(iterator);
16917
16918 PyErr_SetNone(PyExc_StopIteration);
16919 return NULL;
16920}
16921
16922#endif
16923
16924static void
16925ScandirIterator_dealloc(ScandirIterator *iterator)
16926{
16927 ScandirIterator_close(iterator);
16928 Py_XDECREF(iterator->path.object);
16929 path_cleanup(&iterator->path);
16930 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
16931}
16932
16933PyTypeObject ScandirIteratorType = {
16934 PyVarObject_HEAD_INIT(NULL, 0)
16935 MODNAME ".ScandirIterator", /* tp_name */
16936 sizeof(ScandirIterator), /* tp_basicsize */
16937 0, /* tp_itemsize */
16938 /* methods */
16939 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
16940 0, /* tp_print */
16941 0, /* tp_getattr */
16942 0, /* tp_setattr */
16943 0, /* tp_compare */
16944 0, /* tp_repr */
16945 0, /* tp_as_number */
16946 0, /* tp_as_sequence */
16947 0, /* tp_as_mapping */
16948 0, /* tp_hash */
16949 0, /* tp_call */
16950 0, /* tp_str */
16951 0, /* tp_getattro */
16952 0, /* tp_setattro */
16953 0, /* tp_as_buffer */
16954 Py_TPFLAGS_DEFAULT, /* tp_flags */
16955 0, /* tp_doc */
16956 0, /* tp_traverse */
16957 0, /* tp_clear */
16958 0, /* tp_richcompare */
16959 0, /* tp_weaklistoffset */
16960 PyObject_SelfIter, /* tp_iter */
16961 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
16962};
16963
16964static PyObject *
16965posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
16966{
16967 ScandirIterator *iterator;
16968 static char *keywords[] = {"path", NULL};
16969#ifdef MS_WINDOWS
16970 wchar_t *path_strW;
16971#else
16972 char *path;
16973#endif
16974
16975 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
16976 if (!iterator)
16977 return NULL;
16978 memset(&iterator->path, 0, sizeof(path_t));
16979 iterator->path.function_name = "scandir";
16980 iterator->path.nullable = 1;
16981
16982#ifdef MS_WINDOWS
16983 iterator->handle = INVALID_HANDLE_VALUE;
16984#else
16985 iterator->dirp = NULL;
16986#endif
16987
16988 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
16989 path_converter, &iterator->path))
16990 goto error;
16991
16992 /* path_converter doesn't keep path.object around, so do it
16993 manually for the lifetime of the iterator here (the refcount
16994 is decremented in ScandirIterator_dealloc)
16995 */
16996 Py_XINCREF(iterator->path.object);
16997
16998#ifdef MS_WINDOWS
16999 if (iterator->path.narrow) {
17000 PyErr_SetString(PyExc_TypeError,
17001 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
17002 goto error;
17003 }
17004 iterator->first_time = 1;
17005
17006 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
17007 if (!path_strW)
17008 goto error;
17009
17010 Py_BEGIN_ALLOW_THREADS
17011 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
17012 Py_END_ALLOW_THREADS
17013
17014 PyMem_Free(path_strW);
17015
17016 if (iterator->handle == INVALID_HANDLE_VALUE) {
17017 path_error(&iterator->path);
17018 goto error;
17019 }
17020#else /* POSIX */
17021 if (iterator->path.narrow)
17022 path = iterator->path.narrow;
17023 else
17024 path = ".";
17025
17026 errno = 0;
17027 Py_BEGIN_ALLOW_THREADS
17028 iterator->dirp = opendir(path);
17029 Py_END_ALLOW_THREADS
17030
17031 if (!iterator->dirp) {
17032 path_error(&iterator->path);
17033 goto error;
17034 }
17035#endif
17036
17037 return (PyObject *)iterator;
17038
17039error:
17040 Py_DECREF(iterator);
17041 return NULL;
17042}
17043
17044
Larry Hastings7726ac92014-01-31 22:03:12 -080017045/*[clinic input]
17046dump buffer
17047[clinic start generated code]*/
17048
17049#ifndef OS_TTYNAME_METHODDEF
17050 #define OS_TTYNAME_METHODDEF
17051#endif /* !defined(OS_TTYNAME_METHODDEF) */
Larry Hastings2f936352014-08-05 14:04:04 +100017052
17053#ifndef OS_CTERMID_METHODDEF
17054 #define OS_CTERMID_METHODDEF
17055#endif /* !defined(OS_CTERMID_METHODDEF) */
17056
17057#ifndef OS_FCHDIR_METHODDEF
17058 #define OS_FCHDIR_METHODDEF
17059#endif /* !defined(OS_FCHDIR_METHODDEF) */
17060
17061#ifndef OS_FCHMOD_METHODDEF
17062 #define OS_FCHMOD_METHODDEF
17063#endif /* !defined(OS_FCHMOD_METHODDEF) */
17064
17065#ifndef OS_LCHMOD_METHODDEF
17066 #define OS_LCHMOD_METHODDEF
17067#endif /* !defined(OS_LCHMOD_METHODDEF) */
17068
17069#ifndef OS_CHFLAGS_METHODDEF
17070 #define OS_CHFLAGS_METHODDEF
17071#endif /* !defined(OS_CHFLAGS_METHODDEF) */
17072
17073#ifndef OS_LCHFLAGS_METHODDEF
17074 #define OS_LCHFLAGS_METHODDEF
17075#endif /* !defined(OS_LCHFLAGS_METHODDEF) */
17076
17077#ifndef OS_CHROOT_METHODDEF
17078 #define OS_CHROOT_METHODDEF
17079#endif /* !defined(OS_CHROOT_METHODDEF) */
17080
17081#ifndef OS_FSYNC_METHODDEF
17082 #define OS_FSYNC_METHODDEF
17083#endif /* !defined(OS_FSYNC_METHODDEF) */
17084
17085#ifndef OS_SYNC_METHODDEF
17086 #define OS_SYNC_METHODDEF
17087#endif /* !defined(OS_SYNC_METHODDEF) */
17088
17089#ifndef OS_FDATASYNC_METHODDEF
17090 #define OS_FDATASYNC_METHODDEF
17091#endif /* !defined(OS_FDATASYNC_METHODDEF) */
17092
17093#ifndef OS_CHOWN_METHODDEF
17094 #define OS_CHOWN_METHODDEF
17095#endif /* !defined(OS_CHOWN_METHODDEF) */
17096
17097#ifndef OS_FCHOWN_METHODDEF
17098 #define OS_FCHOWN_METHODDEF
17099#endif /* !defined(OS_FCHOWN_METHODDEF) */
17100
17101#ifndef OS_LCHOWN_METHODDEF
17102 #define OS_LCHOWN_METHODDEF
17103#endif /* !defined(OS_LCHOWN_METHODDEF) */
17104
17105#ifndef OS_LINK_METHODDEF
17106 #define OS_LINK_METHODDEF
17107#endif /* !defined(OS_LINK_METHODDEF) */
17108
17109#ifndef OS__GETFINALPATHNAME_METHODDEF
17110 #define OS__GETFINALPATHNAME_METHODDEF
17111#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */
17112
17113#ifndef OS__GETVOLUMEPATHNAME_METHODDEF
17114 #define OS__GETVOLUMEPATHNAME_METHODDEF
17115#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */
17116
17117#ifndef OS_NICE_METHODDEF
17118 #define OS_NICE_METHODDEF
17119#endif /* !defined(OS_NICE_METHODDEF) */
17120
17121#ifndef OS_GETPRIORITY_METHODDEF
17122 #define OS_GETPRIORITY_METHODDEF
17123#endif /* !defined(OS_GETPRIORITY_METHODDEF) */
17124
17125#ifndef OS_SETPRIORITY_METHODDEF
17126 #define OS_SETPRIORITY_METHODDEF
17127#endif /* !defined(OS_SETPRIORITY_METHODDEF) */
17128
17129#ifndef OS_SYSTEM_METHODDEF
17130 #define OS_SYSTEM_METHODDEF
17131#endif /* !defined(OS_SYSTEM_METHODDEF) */
17132
17133#ifndef OS_SYSTEM_METHODDEF
17134 #define OS_SYSTEM_METHODDEF
17135#endif /* !defined(OS_SYSTEM_METHODDEF) */
17136
17137#ifndef OS_UNAME_METHODDEF
17138 #define OS_UNAME_METHODDEF
17139#endif /* !defined(OS_UNAME_METHODDEF) */
17140
17141#ifndef OS_EXECV_METHODDEF
17142 #define OS_EXECV_METHODDEF
17143#endif /* !defined(OS_EXECV_METHODDEF) */
17144
17145#ifndef OS_EXECVE_METHODDEF
17146 #define OS_EXECVE_METHODDEF
17147#endif /* !defined(OS_EXECVE_METHODDEF) */
17148
17149#ifndef OS_SPAWNV_METHODDEF
17150 #define OS_SPAWNV_METHODDEF
17151#endif /* !defined(OS_SPAWNV_METHODDEF) */
17152
17153#ifndef OS_SPAWNVE_METHODDEF
17154 #define OS_SPAWNVE_METHODDEF
17155#endif /* !defined(OS_SPAWNVE_METHODDEF) */
17156
17157#ifndef OS_FORK1_METHODDEF
17158 #define OS_FORK1_METHODDEF
17159#endif /* !defined(OS_FORK1_METHODDEF) */
17160
17161#ifndef OS_FORK_METHODDEF
17162 #define OS_FORK_METHODDEF
17163#endif /* !defined(OS_FORK_METHODDEF) */
17164
17165#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF
17166 #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF
17167#endif /* !defined(OS_SCHED_GET_PRIORITY_MAX_METHODDEF) */
17168
17169#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF
17170 #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF
17171#endif /* !defined(OS_SCHED_GET_PRIORITY_MIN_METHODDEF) */
17172
17173#ifndef OS_SCHED_GETSCHEDULER_METHODDEF
17174 #define OS_SCHED_GETSCHEDULER_METHODDEF
17175#endif /* !defined(OS_SCHED_GETSCHEDULER_METHODDEF) */
17176
17177#ifndef OS_SCHED_SETSCHEDULER_METHODDEF
17178 #define OS_SCHED_SETSCHEDULER_METHODDEF
17179#endif /* !defined(OS_SCHED_SETSCHEDULER_METHODDEF) */
17180
17181#ifndef OS_SCHED_GETPARAM_METHODDEF
17182 #define OS_SCHED_GETPARAM_METHODDEF
17183#endif /* !defined(OS_SCHED_GETPARAM_METHODDEF) */
17184
17185#ifndef OS_SCHED_SETPARAM_METHODDEF
17186 #define OS_SCHED_SETPARAM_METHODDEF
17187#endif /* !defined(OS_SCHED_SETPARAM_METHODDEF) */
17188
17189#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF
17190 #define OS_SCHED_RR_GET_INTERVAL_METHODDEF
17191#endif /* !defined(OS_SCHED_RR_GET_INTERVAL_METHODDEF) */
17192
17193#ifndef OS_SCHED_YIELD_METHODDEF
17194 #define OS_SCHED_YIELD_METHODDEF
17195#endif /* !defined(OS_SCHED_YIELD_METHODDEF) */
17196
17197#ifndef OS_SCHED_SETAFFINITY_METHODDEF
17198 #define OS_SCHED_SETAFFINITY_METHODDEF
17199#endif /* !defined(OS_SCHED_SETAFFINITY_METHODDEF) */
17200
17201#ifndef OS_SCHED_GETAFFINITY_METHODDEF
17202 #define OS_SCHED_GETAFFINITY_METHODDEF
17203#endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */
17204
17205#ifndef OS_OPENPTY_METHODDEF
17206 #define OS_OPENPTY_METHODDEF
17207#endif /* !defined(OS_OPENPTY_METHODDEF) */
17208
17209#ifndef OS_FORKPTY_METHODDEF
17210 #define OS_FORKPTY_METHODDEF
17211#endif /* !defined(OS_FORKPTY_METHODDEF) */
17212
17213#ifndef OS_GETEGID_METHODDEF
17214 #define OS_GETEGID_METHODDEF
17215#endif /* !defined(OS_GETEGID_METHODDEF) */
17216
17217#ifndef OS_GETEUID_METHODDEF
17218 #define OS_GETEUID_METHODDEF
17219#endif /* !defined(OS_GETEUID_METHODDEF) */
17220
17221#ifndef OS_GETGID_METHODDEF
17222 #define OS_GETGID_METHODDEF
17223#endif /* !defined(OS_GETGID_METHODDEF) */
17224
17225#ifndef OS_GETGROUPS_METHODDEF
17226 #define OS_GETGROUPS_METHODDEF
17227#endif /* !defined(OS_GETGROUPS_METHODDEF) */
17228
17229#ifndef OS_GETPGID_METHODDEF
17230 #define OS_GETPGID_METHODDEF
17231#endif /* !defined(OS_GETPGID_METHODDEF) */
17232
17233#ifndef OS_GETPGRP_METHODDEF
17234 #define OS_GETPGRP_METHODDEF
17235#endif /* !defined(OS_GETPGRP_METHODDEF) */
17236
17237#ifndef OS_SETPGRP_METHODDEF
17238 #define OS_SETPGRP_METHODDEF
17239#endif /* !defined(OS_SETPGRP_METHODDEF) */
17240
17241#ifndef OS_GETPPID_METHODDEF
17242 #define OS_GETPPID_METHODDEF
17243#endif /* !defined(OS_GETPPID_METHODDEF) */
17244
17245#ifndef OS_GETLOGIN_METHODDEF
17246 #define OS_GETLOGIN_METHODDEF
17247#endif /* !defined(OS_GETLOGIN_METHODDEF) */
17248
17249#ifndef OS_GETUID_METHODDEF
17250 #define OS_GETUID_METHODDEF
17251#endif /* !defined(OS_GETUID_METHODDEF) */
17252
17253#ifndef OS_KILL_METHODDEF
17254 #define OS_KILL_METHODDEF
17255#endif /* !defined(OS_KILL_METHODDEF) */
17256
17257#ifndef OS_KILLPG_METHODDEF
17258 #define OS_KILLPG_METHODDEF
17259#endif /* !defined(OS_KILLPG_METHODDEF) */
17260
17261#ifndef OS_PLOCK_METHODDEF
17262 #define OS_PLOCK_METHODDEF
17263#endif /* !defined(OS_PLOCK_METHODDEF) */
17264
17265#ifndef OS_SETUID_METHODDEF
17266 #define OS_SETUID_METHODDEF
17267#endif /* !defined(OS_SETUID_METHODDEF) */
17268
17269#ifndef OS_SETEUID_METHODDEF
17270 #define OS_SETEUID_METHODDEF
17271#endif /* !defined(OS_SETEUID_METHODDEF) */
17272
17273#ifndef OS_SETEGID_METHODDEF
17274 #define OS_SETEGID_METHODDEF
17275#endif /* !defined(OS_SETEGID_METHODDEF) */
17276
17277#ifndef OS_SETREUID_METHODDEF
17278 #define OS_SETREUID_METHODDEF
17279#endif /* !defined(OS_SETREUID_METHODDEF) */
17280
17281#ifndef OS_SETREGID_METHODDEF
17282 #define OS_SETREGID_METHODDEF
17283#endif /* !defined(OS_SETREGID_METHODDEF) */
17284
17285#ifndef OS_SETGID_METHODDEF
17286 #define OS_SETGID_METHODDEF
17287#endif /* !defined(OS_SETGID_METHODDEF) */
17288
17289#ifndef OS_SETGROUPS_METHODDEF
17290 #define OS_SETGROUPS_METHODDEF
17291#endif /* !defined(OS_SETGROUPS_METHODDEF) */
17292
17293#ifndef OS_WAIT3_METHODDEF
17294 #define OS_WAIT3_METHODDEF
17295#endif /* !defined(OS_WAIT3_METHODDEF) */
17296
17297#ifndef OS_WAIT4_METHODDEF
17298 #define OS_WAIT4_METHODDEF
17299#endif /* !defined(OS_WAIT4_METHODDEF) */
17300
17301#ifndef OS_WAITID_METHODDEF
17302 #define OS_WAITID_METHODDEF
17303#endif /* !defined(OS_WAITID_METHODDEF) */
17304
17305#ifndef OS_WAITPID_METHODDEF
17306 #define OS_WAITPID_METHODDEF
17307#endif /* !defined(OS_WAITPID_METHODDEF) */
17308
17309#ifndef OS_WAITPID_METHODDEF
17310 #define OS_WAITPID_METHODDEF
17311#endif /* !defined(OS_WAITPID_METHODDEF) */
17312
17313#ifndef OS_WAIT_METHODDEF
17314 #define OS_WAIT_METHODDEF
17315#endif /* !defined(OS_WAIT_METHODDEF) */
17316
17317#ifndef OS_SYMLINK_METHODDEF
17318 #define OS_SYMLINK_METHODDEF
17319#endif /* !defined(OS_SYMLINK_METHODDEF) */
17320
17321#ifndef OS_TIMES_METHODDEF
17322 #define OS_TIMES_METHODDEF
17323#endif /* !defined(OS_TIMES_METHODDEF) */
17324
17325#ifndef OS_GETSID_METHODDEF
17326 #define OS_GETSID_METHODDEF
17327#endif /* !defined(OS_GETSID_METHODDEF) */
17328
17329#ifndef OS_SETSID_METHODDEF
17330 #define OS_SETSID_METHODDEF
17331#endif /* !defined(OS_SETSID_METHODDEF) */
17332
17333#ifndef OS_SETPGID_METHODDEF
17334 #define OS_SETPGID_METHODDEF
17335#endif /* !defined(OS_SETPGID_METHODDEF) */
17336
17337#ifndef OS_TCGETPGRP_METHODDEF
17338 #define OS_TCGETPGRP_METHODDEF
17339#endif /* !defined(OS_TCGETPGRP_METHODDEF) */
17340
17341#ifndef OS_TCSETPGRP_METHODDEF
17342 #define OS_TCSETPGRP_METHODDEF
17343#endif /* !defined(OS_TCSETPGRP_METHODDEF) */
17344
17345#ifndef OS_LOCKF_METHODDEF
17346 #define OS_LOCKF_METHODDEF
17347#endif /* !defined(OS_LOCKF_METHODDEF) */
17348
17349#ifndef OS_READV_METHODDEF
17350 #define OS_READV_METHODDEF
17351#endif /* !defined(OS_READV_METHODDEF) */
17352
17353#ifndef OS_PREAD_METHODDEF
17354 #define OS_PREAD_METHODDEF
17355#endif /* !defined(OS_PREAD_METHODDEF) */
17356
17357#ifndef OS_PIPE_METHODDEF
17358 #define OS_PIPE_METHODDEF
17359#endif /* !defined(OS_PIPE_METHODDEF) */
17360
17361#ifndef OS_PIPE2_METHODDEF
17362 #define OS_PIPE2_METHODDEF
17363#endif /* !defined(OS_PIPE2_METHODDEF) */
17364
17365#ifndef OS_WRITEV_METHODDEF
17366 #define OS_WRITEV_METHODDEF
17367#endif /* !defined(OS_WRITEV_METHODDEF) */
17368
17369#ifndef OS_PWRITE_METHODDEF
17370 #define OS_PWRITE_METHODDEF
17371#endif /* !defined(OS_PWRITE_METHODDEF) */
17372
17373#ifndef OS_MKFIFO_METHODDEF
17374 #define OS_MKFIFO_METHODDEF
17375#endif /* !defined(OS_MKFIFO_METHODDEF) */
17376
17377#ifndef OS_MKNOD_METHODDEF
17378 #define OS_MKNOD_METHODDEF
17379#endif /* !defined(OS_MKNOD_METHODDEF) */
17380
17381#ifndef OS_MAJOR_METHODDEF
17382 #define OS_MAJOR_METHODDEF
17383#endif /* !defined(OS_MAJOR_METHODDEF) */
17384
17385#ifndef OS_MINOR_METHODDEF
17386 #define OS_MINOR_METHODDEF
17387#endif /* !defined(OS_MINOR_METHODDEF) */
17388
17389#ifndef OS_MAKEDEV_METHODDEF
17390 #define OS_MAKEDEV_METHODDEF
17391#endif /* !defined(OS_MAKEDEV_METHODDEF) */
17392
17393#ifndef OS_FTRUNCATE_METHODDEF
17394 #define OS_FTRUNCATE_METHODDEF
17395#endif /* !defined(OS_FTRUNCATE_METHODDEF) */
17396
17397#ifndef OS_TRUNCATE_METHODDEF
17398 #define OS_TRUNCATE_METHODDEF
17399#endif /* !defined(OS_TRUNCATE_METHODDEF) */
17400
17401#ifndef OS_POSIX_FALLOCATE_METHODDEF
17402 #define OS_POSIX_FALLOCATE_METHODDEF
17403#endif /* !defined(OS_POSIX_FALLOCATE_METHODDEF) */
17404
17405#ifndef OS_POSIX_FADVISE_METHODDEF
17406 #define OS_POSIX_FADVISE_METHODDEF
17407#endif /* !defined(OS_POSIX_FADVISE_METHODDEF) */
17408
17409#ifndef OS_PUTENV_METHODDEF
17410 #define OS_PUTENV_METHODDEF
17411#endif /* !defined(OS_PUTENV_METHODDEF) */
17412
17413#ifndef OS_PUTENV_METHODDEF
17414 #define OS_PUTENV_METHODDEF
17415#endif /* !defined(OS_PUTENV_METHODDEF) */
17416
17417#ifndef OS_UNSETENV_METHODDEF
17418 #define OS_UNSETENV_METHODDEF
17419#endif /* !defined(OS_UNSETENV_METHODDEF) */
17420
17421#ifndef OS_WCOREDUMP_METHODDEF
17422 #define OS_WCOREDUMP_METHODDEF
17423#endif /* !defined(OS_WCOREDUMP_METHODDEF) */
17424
17425#ifndef OS_WIFCONTINUED_METHODDEF
17426 #define OS_WIFCONTINUED_METHODDEF
17427#endif /* !defined(OS_WIFCONTINUED_METHODDEF) */
17428
17429#ifndef OS_WIFSTOPPED_METHODDEF
17430 #define OS_WIFSTOPPED_METHODDEF
17431#endif /* !defined(OS_WIFSTOPPED_METHODDEF) */
17432
17433#ifndef OS_WIFSIGNALED_METHODDEF
17434 #define OS_WIFSIGNALED_METHODDEF
17435#endif /* !defined(OS_WIFSIGNALED_METHODDEF) */
17436
17437#ifndef OS_WIFEXITED_METHODDEF
17438 #define OS_WIFEXITED_METHODDEF
17439#endif /* !defined(OS_WIFEXITED_METHODDEF) */
17440
17441#ifndef OS_WEXITSTATUS_METHODDEF
17442 #define OS_WEXITSTATUS_METHODDEF
17443#endif /* !defined(OS_WEXITSTATUS_METHODDEF) */
17444
17445#ifndef OS_WTERMSIG_METHODDEF
17446 #define OS_WTERMSIG_METHODDEF
17447#endif /* !defined(OS_WTERMSIG_METHODDEF) */
17448
17449#ifndef OS_WSTOPSIG_METHODDEF
17450 #define OS_WSTOPSIG_METHODDEF
17451#endif /* !defined(OS_WSTOPSIG_METHODDEF) */
17452
17453#ifndef OS_FSTATVFS_METHODDEF
17454 #define OS_FSTATVFS_METHODDEF
17455#endif /* !defined(OS_FSTATVFS_METHODDEF) */
17456
17457#ifndef OS_STATVFS_METHODDEF
17458 #define OS_STATVFS_METHODDEF
17459#endif /* !defined(OS_STATVFS_METHODDEF) */
17460
17461#ifndef OS__GETDISKUSAGE_METHODDEF
17462 #define OS__GETDISKUSAGE_METHODDEF
17463#endif /* !defined(OS__GETDISKUSAGE_METHODDEF) */
17464
17465#ifndef OS_FPATHCONF_METHODDEF
17466 #define OS_FPATHCONF_METHODDEF
17467#endif /* !defined(OS_FPATHCONF_METHODDEF) */
17468
17469#ifndef OS_PATHCONF_METHODDEF
17470 #define OS_PATHCONF_METHODDEF
17471#endif /* !defined(OS_PATHCONF_METHODDEF) */
17472
17473#ifndef OS_CONFSTR_METHODDEF
17474 #define OS_CONFSTR_METHODDEF
17475#endif /* !defined(OS_CONFSTR_METHODDEF) */
17476
17477#ifndef OS_SYSCONF_METHODDEF
17478 #define OS_SYSCONF_METHODDEF
17479#endif /* !defined(OS_SYSCONF_METHODDEF) */
17480
17481#ifndef OS_GETLOADAVG_METHODDEF
17482 #define OS_GETLOADAVG_METHODDEF
17483#endif /* !defined(OS_GETLOADAVG_METHODDEF) */
17484
17485#ifndef OS_SETRESUID_METHODDEF
17486 #define OS_SETRESUID_METHODDEF
17487#endif /* !defined(OS_SETRESUID_METHODDEF) */
17488
17489#ifndef OS_SETRESGID_METHODDEF
17490 #define OS_SETRESGID_METHODDEF
17491#endif /* !defined(OS_SETRESGID_METHODDEF) */
17492
17493#ifndef OS_GETRESUID_METHODDEF
17494 #define OS_GETRESUID_METHODDEF
17495#endif /* !defined(OS_GETRESUID_METHODDEF) */
17496
17497#ifndef OS_GETRESGID_METHODDEF
17498 #define OS_GETRESGID_METHODDEF
17499#endif /* !defined(OS_GETRESGID_METHODDEF) */
17500
17501#ifndef OS_GETXATTR_METHODDEF
17502 #define OS_GETXATTR_METHODDEF
17503#endif /* !defined(OS_GETXATTR_METHODDEF) */
17504
17505#ifndef OS_SETXATTR_METHODDEF
17506 #define OS_SETXATTR_METHODDEF
17507#endif /* !defined(OS_SETXATTR_METHODDEF) */
17508
17509#ifndef OS_REMOVEXATTR_METHODDEF
17510 #define OS_REMOVEXATTR_METHODDEF
17511#endif /* !defined(OS_REMOVEXATTR_METHODDEF) */
17512
17513#ifndef OS_LISTXATTR_METHODDEF
17514 #define OS_LISTXATTR_METHODDEF
17515#endif /* !defined(OS_LISTXATTR_METHODDEF) */
17516
17517#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF
17518 #define OS_GET_HANDLE_INHERITABLE_METHODDEF
17519#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */
17520
17521#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF
17522 #define OS_SET_HANDLE_INHERITABLE_METHODDEF
17523#endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */
17524/*[clinic end generated code: output=52a6140b0b052ce6 input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080017525
Larry Hastings31826802013-10-19 00:09:25 -070017526
Fred Drake5ab8eaf1999-12-09 21:13:07 +000017527static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070017528
17529 OS_STAT_METHODDEF
17530 OS_ACCESS_METHODDEF
17531 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100017532 OS_CHDIR_METHODDEF
17533 OS_CHFLAGS_METHODDEF
17534 OS_CHMOD_METHODDEF
17535 OS_FCHMOD_METHODDEF
17536 OS_LCHMOD_METHODDEF
17537 OS_CHOWN_METHODDEF
17538 OS_FCHOWN_METHODDEF
17539 OS_LCHOWN_METHODDEF
17540 OS_LCHFLAGS_METHODDEF
17541 OS_CHROOT_METHODDEF
17542 OS_CTERMID_METHODDEF
17543 OS_GETCWD_METHODDEF
17544 OS_GETCWDB_METHODDEF
17545 OS_LINK_METHODDEF
17546 OS_LISTDIR_METHODDEF
17547 OS_LSTAT_METHODDEF
17548 OS_MKDIR_METHODDEF
17549 OS_NICE_METHODDEF
17550 OS_GETPRIORITY_METHODDEF
17551 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000017552#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070017553 {"readlink", (PyCFunction)posix_readlink,
17554 METH_VARARGS | METH_KEYWORDS,
17555 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000017556#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000017557#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070017558 {"readlink", (PyCFunction)win_readlink,
17559 METH_VARARGS | METH_KEYWORDS,
17560 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000017561#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100017562 OS_RENAME_METHODDEF
17563 OS_REPLACE_METHODDEF
17564 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000017565 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100017566 OS_SYMLINK_METHODDEF
17567 OS_SYSTEM_METHODDEF
17568 OS_UMASK_METHODDEF
17569 OS_UNAME_METHODDEF
17570 OS_UNLINK_METHODDEF
17571 OS_REMOVE_METHODDEF
17572 OS_UTIME_METHODDEF
17573 OS_TIMES_METHODDEF
17574 OS__EXIT_METHODDEF
17575 OS_EXECV_METHODDEF
17576 OS_EXECVE_METHODDEF
17577 OS_SPAWNV_METHODDEF
17578 OS_SPAWNVE_METHODDEF
17579 OS_FORK1_METHODDEF
17580 OS_FORK_METHODDEF
17581 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
17582 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
17583 OS_SCHED_GETPARAM_METHODDEF
17584 OS_SCHED_GETSCHEDULER_METHODDEF
17585 OS_SCHED_RR_GET_INTERVAL_METHODDEF
17586 OS_SCHED_SETPARAM_METHODDEF
17587 OS_SCHED_SETSCHEDULER_METHODDEF
17588 OS_SCHED_YIELD_METHODDEF
17589 OS_SCHED_SETAFFINITY_METHODDEF
17590 OS_SCHED_GETAFFINITY_METHODDEF
17591 OS_OPENPTY_METHODDEF
17592 OS_FORKPTY_METHODDEF
17593 OS_GETEGID_METHODDEF
17594 OS_GETEUID_METHODDEF
17595 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020017596#ifdef HAVE_GETGROUPLIST
17597 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
17598#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017599 OS_GETGROUPS_METHODDEF
17600 OS_GETPID_METHODDEF
17601 OS_GETPGRP_METHODDEF
17602 OS_GETPPID_METHODDEF
17603 OS_GETUID_METHODDEF
17604 OS_GETLOGIN_METHODDEF
17605 OS_KILL_METHODDEF
17606 OS_KILLPG_METHODDEF
17607 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000017608#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000017609 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000017610#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017611 OS_SETUID_METHODDEF
17612 OS_SETEUID_METHODDEF
17613 OS_SETREUID_METHODDEF
17614 OS_SETGID_METHODDEF
17615 OS_SETEGID_METHODDEF
17616 OS_SETREGID_METHODDEF
17617 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000017618#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000017619 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000017620#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100017621 OS_GETPGID_METHODDEF
17622 OS_SETPGRP_METHODDEF
17623 OS_WAIT_METHODDEF
17624 OS_WAIT3_METHODDEF
17625 OS_WAIT4_METHODDEF
17626 OS_WAITID_METHODDEF
17627 OS_WAITPID_METHODDEF
17628 OS_GETSID_METHODDEF
17629 OS_SETSID_METHODDEF
17630 OS_SETPGID_METHODDEF
17631 OS_TCGETPGRP_METHODDEF
17632 OS_TCSETPGRP_METHODDEF
17633 OS_OPEN_METHODDEF
17634 OS_CLOSE_METHODDEF
17635 OS_CLOSERANGE_METHODDEF
17636 OS_DEVICE_ENCODING_METHODDEF
17637 OS_DUP_METHODDEF
17638 OS_DUP2_METHODDEF
17639 OS_LOCKF_METHODDEF
17640 OS_LSEEK_METHODDEF
17641 OS_READ_METHODDEF
17642 OS_READV_METHODDEF
17643 OS_PREAD_METHODDEF
17644 OS_WRITE_METHODDEF
17645 OS_WRITEV_METHODDEF
17646 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000017647#ifdef HAVE_SENDFILE
17648 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
17649 posix_sendfile__doc__},
17650#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017651 OS_FSTAT_METHODDEF
17652 OS_ISATTY_METHODDEF
17653 OS_PIPE_METHODDEF
17654 OS_PIPE2_METHODDEF
17655 OS_MKFIFO_METHODDEF
17656 OS_MKNOD_METHODDEF
17657 OS_MAJOR_METHODDEF
17658 OS_MINOR_METHODDEF
17659 OS_MAKEDEV_METHODDEF
17660 OS_FTRUNCATE_METHODDEF
17661 OS_TRUNCATE_METHODDEF
17662 OS_POSIX_FALLOCATE_METHODDEF
17663 OS_POSIX_FADVISE_METHODDEF
17664 OS_PUTENV_METHODDEF
17665 OS_UNSETENV_METHODDEF
17666 OS_STRERROR_METHODDEF
17667 OS_FCHDIR_METHODDEF
17668 OS_FSYNC_METHODDEF
17669 OS_SYNC_METHODDEF
17670 OS_FDATASYNC_METHODDEF
17671 OS_WCOREDUMP_METHODDEF
17672 OS_WIFCONTINUED_METHODDEF
17673 OS_WIFSTOPPED_METHODDEF
17674 OS_WIFSIGNALED_METHODDEF
17675 OS_WIFEXITED_METHODDEF
17676 OS_WEXITSTATUS_METHODDEF
17677 OS_WTERMSIG_METHODDEF
17678 OS_WSTOPSIG_METHODDEF
17679 OS_FSTATVFS_METHODDEF
17680 OS_STATVFS_METHODDEF
17681 OS_CONFSTR_METHODDEF
17682 OS_SYSCONF_METHODDEF
17683 OS_FPATHCONF_METHODDEF
17684 OS_PATHCONF_METHODDEF
17685 OS_ABORT_METHODDEF
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000017686#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000017687 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050017688 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000017689#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017690 OS__GETDISKUSAGE_METHODDEF
17691 OS__GETFINALPATHNAME_METHODDEF
17692 OS__GETVOLUMEPATHNAME_METHODDEF
17693 OS_GETLOADAVG_METHODDEF
17694 OS_URANDOM_METHODDEF
17695 OS_SETRESUID_METHODDEF
17696 OS_SETRESGID_METHODDEF
17697 OS_GETRESUID_METHODDEF
17698 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000017699
Larry Hastings2f936352014-08-05 14:04:04 +100017700 OS_GETXATTR_METHODDEF
17701 OS_SETXATTR_METHODDEF
17702 OS_REMOVEXATTR_METHODDEF
17703 OS_LISTXATTR_METHODDEF
17704
Antoine Pitroubcf2b592012-02-08 23:28:36 +010017705#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
17706 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
17707#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017708 OS_CPU_COUNT_METHODDEF
17709 OS_GET_INHERITABLE_METHODDEF
17710 OS_SET_INHERITABLE_METHODDEF
17711 OS_GET_HANDLE_INHERITABLE_METHODDEF
17712 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020017713#ifndef MS_WINDOWS
17714 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
17715 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
17716#endif
Victor Stinner6036e442015-03-08 01:58:04 +010017717 {"scandir", (PyCFunction)posix_scandir,
17718 METH_VARARGS | METH_KEYWORDS,
17719 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000017720 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000017721};
17722
17723
Brian Curtin52173d42010-12-02 18:29:18 +000017724#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000017725static int
Brian Curtin52173d42010-12-02 18:29:18 +000017726enable_symlink()
17727{
17728 HANDLE tok;
17729 TOKEN_PRIVILEGES tok_priv;
17730 LUID luid;
17731 int meth_idx = 0;
17732
17733 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017734 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017735
17736 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017737 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017738
17739 tok_priv.PrivilegeCount = 1;
17740 tok_priv.Privileges[0].Luid = luid;
17741 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
17742
17743 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
17744 sizeof(TOKEN_PRIVILEGES),
17745 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017746 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017747
Brian Curtin3b4499c2010-12-28 14:31:47 +000017748 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
17749 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000017750}
17751#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
17752
Barry Warsaw4a342091996-12-19 23:50:02 +000017753static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017754all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000017755{
Guido van Rossum94f6f721999-01-06 18:42:14 +000017756#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017757 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017758#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017759#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017760 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017761#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017762#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017763 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017764#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017765#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017766 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017767#endif
Fred Drakec9680921999-12-13 16:37:25 +000017768#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017769 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000017770#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000017771#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017772 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000017773#endif
Fred Drake106c1a02002-04-23 15:58:02 +000017774#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017775 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000017776#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000017777#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017778 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017779#endif
Fred Drake106c1a02002-04-23 15:58:02 +000017780#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017781 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000017782#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000017783#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017784 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017785#endif
17786#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017787 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017788#endif
17789#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017790 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017791#endif
17792#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017793 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017794#endif
17795#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017796 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017797#endif
17798#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017799 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017800#endif
17801#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017802 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017803#endif
17804#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017805 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017806#endif
17807#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017808 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017809#endif
17810#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017811 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017812#endif
17813#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017814 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017815#endif
17816#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017817 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017818#endif
17819#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017820 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017821#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000017822#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017823 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000017824#endif
17825#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017826 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000017827#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017828#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017829 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017830#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017831#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017832 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017833#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000017834#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017835 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000017836#endif
17837#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017838 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000017839#endif
Jesus Ceacf381202012-04-24 20:44:40 +020017840#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017841 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017842#endif
17843#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017844 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017845#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050017846#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017847 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050017848#endif
Jesus Ceacf381202012-04-24 20:44:40 +020017849#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017850 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017851#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020017852#ifdef O_TMPFILE
17853 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
17854#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017855#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017856 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017857#endif
17858#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017859 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017860#endif
17861#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017862 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017863#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020017864#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017865 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020017866#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017867#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017868 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017869#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017870
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017871
Jesus Cea94363612012-06-22 18:32:07 +020017872#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017873 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020017874#endif
17875#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017876 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020017877#endif
17878
Tim Peters5aa91602002-01-30 05:46:57 +000017879/* MS Windows */
17880#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000017881 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017882 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017883#endif
17884#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000017885 /* Optimize for short life (keep in memory). */
17886 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017887 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017888#endif
17889#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000017890 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017891 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017892#endif
17893#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000017894 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017895 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017896#endif
17897#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000017898 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017899 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017900#endif
17901
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017902/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000017903#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000017904 /* Send a SIGIO signal whenever input or output
17905 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017906 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000017907#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017908#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000017909 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017910 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017911#endif
17912#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000017913 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017914 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017915#endif
17916#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000017917 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017918 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017919#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017920#ifdef O_NOLINKS
17921 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017922 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017923#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000017924#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000017925 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017926 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000017927#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000017928
Victor Stinner8c62be82010-05-06 00:08:46 +000017929 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017930#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017931 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017932#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017933#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017934 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017935#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017936#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017937 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017938#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017939#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017940 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017941#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017942#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017943 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017944#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017945#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017946 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017947#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017948#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017949 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017950#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017951#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017952 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017953#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017954#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017955 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017956#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017957#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017958 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017959#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017960#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017961 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017962#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017963#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017964 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017965#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017966#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017967 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017968#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017969#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017970 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017971#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017972#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017973 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017974#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017975#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017976 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017977#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017978#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017979 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017980#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017981
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000017982 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017983#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017984 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017985#endif /* ST_RDONLY */
17986#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017987 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017988#endif /* ST_NOSUID */
17989
doko@ubuntu.comca616a22013-12-08 15:23:07 +010017990 /* GNU extensions */
17991#ifdef ST_NODEV
17992 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
17993#endif /* ST_NODEV */
17994#ifdef ST_NOEXEC
17995 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
17996#endif /* ST_NOEXEC */
17997#ifdef ST_SYNCHRONOUS
17998 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
17999#endif /* ST_SYNCHRONOUS */
18000#ifdef ST_MANDLOCK
18001 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
18002#endif /* ST_MANDLOCK */
18003#ifdef ST_WRITE
18004 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
18005#endif /* ST_WRITE */
18006#ifdef ST_APPEND
18007 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
18008#endif /* ST_APPEND */
18009#ifdef ST_NOATIME
18010 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
18011#endif /* ST_NOATIME */
18012#ifdef ST_NODIRATIME
18013 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
18014#endif /* ST_NODIRATIME */
18015#ifdef ST_RELATIME
18016 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
18017#endif /* ST_RELATIME */
18018
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000018019 /* FreeBSD sendfile() constants */
18020#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018021 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000018022#endif
18023#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018024 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000018025#endif
18026#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018027 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000018028#endif
18029
Ross Lagerwall7807c352011-03-17 20:20:30 +020018030 /* constants for posix_fadvise */
18031#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018032 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018033#endif
18034#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018035 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018036#endif
18037#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018038 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018039#endif
18040#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018041 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018042#endif
18043#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018044 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018045#endif
18046#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018047 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018048#endif
18049
18050 /* constants for waitid */
18051#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018052 if (PyModule_AddIntMacro(m, P_PID)) return -1;
18053 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
18054 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018055#endif
18056#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018057 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018058#endif
18059#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018060 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018061#endif
18062#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018063 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018064#endif
18065#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018066 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018067#endif
18068#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018069 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018070#endif
18071#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018072 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018073#endif
18074#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018075 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018076#endif
18077
18078 /* constants for lockf */
18079#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018080 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018081#endif
18082#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018083 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018084#endif
18085#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018086 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018087#endif
18088#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018089 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018090#endif
18091
Guido van Rossum246bc171999-02-01 23:54:31 +000018092#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018093 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
18094 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
18095 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
18096 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
18097 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000018098#endif
18099
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018100#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018101 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
18102 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
18103 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018104#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018105 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018106#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018107#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018108 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018109#endif
18110#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018111 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018112#endif
18113#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018114 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018115#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020018116#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018117 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020018118#endif
18119#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018120 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020018121#endif
18122#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018123 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020018124#endif
18125#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018126 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020018127#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018128#endif
18129
Benjamin Peterson9428d532011-09-14 11:45:52 -040018130#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018131 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
18132 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
18133 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040018134#endif
18135
Victor Stinner8b905bd2011-10-25 13:34:04 +020018136#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018137 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018138#endif
18139#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018140 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018141#endif
18142#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018143 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018144#endif
18145#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018146 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018147#endif
18148#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018149 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018150#endif
18151#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018152 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018153#endif
18154#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020018155 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020018156#endif
18157
Victor Stinner8c62be82010-05-06 00:08:46 +000018158 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000018159}
18160
18161
Martin v. Löwis1a214512008-06-11 05:26:20 +000018162static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000018163 PyModuleDef_HEAD_INIT,
18164 MODNAME,
18165 posix__doc__,
18166 -1,
18167 posix_methods,
18168 NULL,
18169 NULL,
18170 NULL,
18171 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000018172};
18173
18174
Larry Hastings9cf065c2012-06-22 16:30:09 -070018175static char *have_functions[] = {
18176
18177#ifdef HAVE_FACCESSAT
18178 "HAVE_FACCESSAT",
18179#endif
18180
18181#ifdef HAVE_FCHDIR
18182 "HAVE_FCHDIR",
18183#endif
18184
18185#ifdef HAVE_FCHMOD
18186 "HAVE_FCHMOD",
18187#endif
18188
18189#ifdef HAVE_FCHMODAT
18190 "HAVE_FCHMODAT",
18191#endif
18192
18193#ifdef HAVE_FCHOWN
18194 "HAVE_FCHOWN",
18195#endif
18196
Larry Hastings00964ed2013-08-12 13:49:30 -040018197#ifdef HAVE_FCHOWNAT
18198 "HAVE_FCHOWNAT",
18199#endif
18200
Larry Hastings9cf065c2012-06-22 16:30:09 -070018201#ifdef HAVE_FEXECVE
18202 "HAVE_FEXECVE",
18203#endif
18204
18205#ifdef HAVE_FDOPENDIR
18206 "HAVE_FDOPENDIR",
18207#endif
18208
Georg Brandl306336b2012-06-24 12:55:33 +020018209#ifdef HAVE_FPATHCONF
18210 "HAVE_FPATHCONF",
18211#endif
18212
Larry Hastings9cf065c2012-06-22 16:30:09 -070018213#ifdef HAVE_FSTATAT
18214 "HAVE_FSTATAT",
18215#endif
18216
18217#ifdef HAVE_FSTATVFS
18218 "HAVE_FSTATVFS",
18219#endif
18220
Georg Brandl306336b2012-06-24 12:55:33 +020018221#ifdef HAVE_FTRUNCATE
18222 "HAVE_FTRUNCATE",
18223#endif
18224
Larry Hastings9cf065c2012-06-22 16:30:09 -070018225#ifdef HAVE_FUTIMENS
18226 "HAVE_FUTIMENS",
18227#endif
18228
18229#ifdef HAVE_FUTIMES
18230 "HAVE_FUTIMES",
18231#endif
18232
18233#ifdef HAVE_FUTIMESAT
18234 "HAVE_FUTIMESAT",
18235#endif
18236
18237#ifdef HAVE_LINKAT
18238 "HAVE_LINKAT",
18239#endif
18240
18241#ifdef HAVE_LCHFLAGS
18242 "HAVE_LCHFLAGS",
18243#endif
18244
18245#ifdef HAVE_LCHMOD
18246 "HAVE_LCHMOD",
18247#endif
18248
18249#ifdef HAVE_LCHOWN
18250 "HAVE_LCHOWN",
18251#endif
18252
18253#ifdef HAVE_LSTAT
18254 "HAVE_LSTAT",
18255#endif
18256
18257#ifdef HAVE_LUTIMES
18258 "HAVE_LUTIMES",
18259#endif
18260
18261#ifdef HAVE_MKDIRAT
18262 "HAVE_MKDIRAT",
18263#endif
18264
18265#ifdef HAVE_MKFIFOAT
18266 "HAVE_MKFIFOAT",
18267#endif
18268
18269#ifdef HAVE_MKNODAT
18270 "HAVE_MKNODAT",
18271#endif
18272
18273#ifdef HAVE_OPENAT
18274 "HAVE_OPENAT",
18275#endif
18276
18277#ifdef HAVE_READLINKAT
18278 "HAVE_READLINKAT",
18279#endif
18280
18281#ifdef HAVE_RENAMEAT
18282 "HAVE_RENAMEAT",
18283#endif
18284
18285#ifdef HAVE_SYMLINKAT
18286 "HAVE_SYMLINKAT",
18287#endif
18288
18289#ifdef HAVE_UNLINKAT
18290 "HAVE_UNLINKAT",
18291#endif
18292
18293#ifdef HAVE_UTIMENSAT
18294 "HAVE_UTIMENSAT",
18295#endif
18296
18297#ifdef MS_WINDOWS
18298 "MS_WINDOWS",
18299#endif
18300
18301 NULL
18302};
18303
18304
Mark Hammondfe51c6d2002-08-02 02:27:13 +000018305PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000018306INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000018307{
Victor Stinner8c62be82010-05-06 00:08:46 +000018308 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070018309 PyObject *list;
18310 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000018311
Brian Curtin52173d42010-12-02 18:29:18 +000018312#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000018313 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000018314#endif
18315
Victor Stinner8c62be82010-05-06 00:08:46 +000018316 m = PyModule_Create(&posixmodule);
18317 if (m == NULL)
18318 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000018319
Victor Stinner8c62be82010-05-06 00:08:46 +000018320 /* Initialize environ dictionary */
18321 v = convertenviron();
18322 Py_XINCREF(v);
18323 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
18324 return NULL;
18325 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000018326
Victor Stinner8c62be82010-05-06 00:08:46 +000018327 if (all_ins(m))
18328 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000018329
Victor Stinner8c62be82010-05-06 00:08:46 +000018330 if (setup_confname_tables(m))
18331 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000018332
Victor Stinner8c62be82010-05-06 00:08:46 +000018333 Py_INCREF(PyExc_OSError);
18334 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000018335
Guido van Rossumb3d39562000-01-31 18:41:26 +000018336#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000018337 if (posix_putenv_garbage == NULL)
18338 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000018339#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000018340
Victor Stinner8c62be82010-05-06 00:08:46 +000018341 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020018342#if defined(HAVE_WAITID) && !defined(__APPLE__)
18343 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020018344 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
18345 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020018346#endif
18347
Christian Heimes25827622013-10-12 01:27:08 +020018348 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000018349 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
18350 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
18351 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020018352 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
18353 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000018354 structseq_new = StatResultType.tp_new;
18355 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018356
Christian Heimes25827622013-10-12 01:27:08 +020018357 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020018358 if (PyStructSequence_InitType2(&StatVFSResultType,
18359 &statvfs_result_desc) < 0)
18360 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000018361#ifdef NEED_TICKS_PER_SECOND
18362# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000018363 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000018364# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000018365 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000018366# else
Victor Stinner8c62be82010-05-06 00:08:46 +000018367 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000018368# endif
18369#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018370
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050018371#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018372 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020018373 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
18374 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100018375 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018376#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010018377
18378 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020018379 if (PyStructSequence_InitType2(&TerminalSizeType,
18380 &TerminalSize_desc) < 0)
18381 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010018382
18383 /* initialize scandir types */
18384 if (PyType_Ready(&ScandirIteratorType) < 0)
18385 return NULL;
18386 if (PyType_Ready(&DirEntryType) < 0)
18387 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000018388 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020018389#if defined(HAVE_WAITID) && !defined(__APPLE__)
18390 Py_INCREF((PyObject*) &WaitidResultType);
18391 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
18392#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000018393 Py_INCREF((PyObject*) &StatResultType);
18394 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
18395 Py_INCREF((PyObject*) &StatVFSResultType);
18396 PyModule_AddObject(m, "statvfs_result",
18397 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050018398
18399#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050018400 Py_INCREF(&SchedParamType);
18401 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050018402#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000018403
Larry Hastings605a62d2012-06-24 04:33:36 -070018404 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020018405 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
18406 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070018407 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
18408
18409 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020018410 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
18411 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070018412 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
18413
Thomas Wouters477c8d52006-05-27 19:21:47 +000018414#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000018415 /*
18416 * Step 2 of weak-linking support on Mac OS X.
18417 *
18418 * The code below removes functions that are not available on the
18419 * currently active platform.
18420 *
18421 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070018422 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000018423 * OSX 10.4.
18424 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000018425#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000018426 if (fstatvfs == NULL) {
18427 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
18428 return NULL;
18429 }
18430 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000018431#endif /* HAVE_FSTATVFS */
18432
18433#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000018434 if (statvfs == NULL) {
18435 if (PyObject_DelAttrString(m, "statvfs") == -1) {
18436 return NULL;
18437 }
18438 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000018439#endif /* HAVE_STATVFS */
18440
18441# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000018442 if (lchown == NULL) {
18443 if (PyObject_DelAttrString(m, "lchown") == -1) {
18444 return NULL;
18445 }
18446 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000018447#endif /* HAVE_LCHOWN */
18448
18449
18450#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010018451
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020018452 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010018453 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
18454
Larry Hastings6fe20b32012-04-19 15:07:49 -070018455 billion = PyLong_FromLong(1000000000);
18456 if (!billion)
18457 return NULL;
18458
Larry Hastings9cf065c2012-06-22 16:30:09 -070018459 /* suppress "function not used" warnings */
18460 {
18461 int ignored;
18462 fd_specified("", -1);
18463 follow_symlinks_specified("", 1);
18464 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
18465 dir_fd_converter(Py_None, &ignored);
18466 dir_fd_unavailable(Py_None, &ignored);
18467 }
18468
18469 /*
18470 * provide list of locally available functions
18471 * so os.py can populate support_* lists
18472 */
18473 list = PyList_New(0);
18474 if (!list)
18475 return NULL;
18476 for (trace = have_functions; *trace; trace++) {
18477 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
18478 if (!unicode)
18479 return NULL;
18480 if (PyList_Append(list, unicode))
18481 return NULL;
18482 Py_DECREF(unicode);
18483 }
18484 PyModule_AddObject(m, "_have_functions", list);
18485
18486 initialized = 1;
18487
Victor Stinner8c62be82010-05-06 00:08:46 +000018488 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000018489}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018490
18491#ifdef __cplusplus
18492}
18493#endif