blob: d8e244133184b7dd5675d19cbfe18cc234af026b [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"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020028#ifndef MS_WINDOWS
29#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010030#else
31#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020032#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000033
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034#ifdef __cplusplus
35extern "C" {
36#endif
37
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000038PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000039"This module provides access to operating system functionality that is\n\
40standardized by the C Standard and the POSIX standard (a thinly\n\
41disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000044
Ross Lagerwall4d076da2011-03-18 06:56:53 +020045#ifdef HAVE_SYS_UIO_H
46#include <sys/uio.h>
47#endif
48
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000050#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051#endif /* HAVE_SYS_TYPES_H */
52
53#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000054#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000055#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000056
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000058#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000059#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000060
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000062#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000064
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#ifdef HAVE_FCNTL_H
66#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000067#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000068
Guido van Rossuma6535fd2001-10-18 19:44:10 +000069#ifdef HAVE_GRP_H
70#include <grp.h>
71#endif
72
Barry Warsaw5676bd12003-01-07 20:57:09 +000073#ifdef HAVE_SYSEXITS_H
74#include <sysexits.h>
75#endif /* HAVE_SYSEXITS_H */
76
Anthony Baxter8a560de2004-10-13 15:30:56 +000077#ifdef HAVE_SYS_LOADAVG_H
78#include <sys/loadavg.h>
79#endif
80
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000081#ifdef HAVE_LANGINFO_H
82#include <langinfo.h>
83#endif
84
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000085#ifdef HAVE_SYS_SENDFILE_H
86#include <sys/sendfile.h>
87#endif
88
Benjamin Peterson94b580d2011-08-02 17:30:04 -050089#ifdef HAVE_SCHED_H
90#include <sched.h>
91#endif
92
Benjamin Peterson2dbda072012-03-16 10:12:55 -050093#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050094#undef HAVE_SCHED_SETAFFINITY
95#endif
96
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020097#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040098#define USE_XATTRS
99#endif
100
101#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400102#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400103#endif
104
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000105#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
106#ifdef HAVE_SYS_SOCKET_H
107#include <sys/socket.h>
108#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000109#endif
110
Victor Stinner8b905bd2011-10-25 13:34:04 +0200111#ifdef HAVE_DLFCN_H
112#include <dlfcn.h>
113#endif
114
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200115#ifdef __hpux
116#include <sys/mpctl.h>
117#endif
118
119#if defined(__DragonFly__) || \
120 defined(__OpenBSD__) || \
121 defined(__FreeBSD__) || \
122 defined(__NetBSD__) || \
123 defined(__APPLE__)
124#include <sys/sysctl.h>
125#endif
126
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100127#if defined(MS_WINDOWS)
128# define TERMSIZE_USE_CONIO
129#elif defined(HAVE_SYS_IOCTL_H)
130# include <sys/ioctl.h>
131# if defined(HAVE_TERMIOS_H)
132# include <termios.h>
133# endif
134# if defined(TIOCGWINSZ)
135# define TERMSIZE_USE_IOCTL
136# endif
137#endif /* MS_WINDOWS */
138
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000140/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000143#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#include <process.h>
145#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000146#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000147#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000148#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_EXECV 1
151#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
153#define HAVE_CWAIT 1
154#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000155#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000156#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157/* Unix functions that the configure script doesn't check for */
158#define HAVE_EXECV 1
159#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000160#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000161#define HAVE_FORK1 1
162#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#define HAVE_GETEGID 1
164#define HAVE_GETEUID 1
165#define HAVE_GETGID 1
166#define HAVE_GETPPID 1
167#define HAVE_GETUID 1
168#define HAVE_KILL 1
169#define HAVE_OPENDIR 1
170#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000173#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000175#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000176
Victor Stinnera2f7c002012-02-08 03:36:25 +0100177
Larry Hastings61272b72014-01-07 12:41:53 -0800178/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000179# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800180module os
Larry Hastings61272b72014-01-07 12:41:53 -0800181[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000182/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100183
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000184#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000185
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000186#if defined(__sgi)&&_COMPILER_VERSION>=700
187/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
188 (default) */
189extern char *ctermid_r(char *);
190#endif
191
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000192#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000193#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000195#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000196#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000201#endif
202#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int chdir(char *);
204extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000205#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int chdir(const char *);
207extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000210/*#ifdef HAVE_FCHMOD
211extern int fchmod(int, mode_t);
212#endif*/
213/*#ifdef HAVE_LCHMOD
214extern int lchmod(const char *, mode_t);
215#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int chown(const char *, uid_t, gid_t);
217extern char *getcwd(char *, int);
218extern char *strerror(int);
219extern int link(const char *, const char *);
220extern int rename(const char *, const char *);
221extern int stat(const char *, struct stat *);
222extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000225#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000228#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000230
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#ifdef HAVE_UTIME_H
234#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000237#ifdef HAVE_SYS_UTIME_H
238#include <sys/utime.h>
239#define HAVE_UTIME_H /* pretend we do for the rest of this file */
240#endif /* HAVE_SYS_UTIME_H */
241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_SYS_TIMES_H
243#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
246#ifdef HAVE_SYS_PARAM_H
247#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249
250#ifdef HAVE_SYS_UTSNAME_H
251#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000252#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#define NAMLEN(dirent) strlen((dirent)->d_name)
257#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000258#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000259#include <direct.h>
260#define NAMLEN(dirent) strlen((dirent)->d_name)
261#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000264#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#endif
268#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#endif
271#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#endif
274#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000277#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279#endif
280#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282#endif
283#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000285#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000286#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000287#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000288#endif
289#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000290#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000291#endif
292#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000293#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000294#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100295#ifndef IO_REPARSE_TAG_MOUNT_POINT
296#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
297#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000298#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000299#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000301#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000302#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000303#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
304#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000305static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000306#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000307#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000308
Tim Petersbc2e10e2002-03-03 23:17:02 +0000309#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000310#if defined(PATH_MAX) && PATH_MAX > 1024
311#define MAXPATHLEN PATH_MAX
312#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000313#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000314#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#endif /* MAXPATHLEN */
316
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000317#ifdef UNION_WAIT
318/* Emulate some macros on systems that have a union instead of macros */
319
320#ifndef WIFEXITED
321#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
322#endif
323
324#ifndef WEXITSTATUS
325#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
326#endif
327
328#ifndef WTERMSIG
329#define WTERMSIG(u_wait) ((u_wait).w_termsig)
330#endif
331
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000332#define WAIT_TYPE union wait
333#define WAIT_STATUS_INT(s) (s.w_status)
334
335#else /* !UNION_WAIT */
336#define WAIT_TYPE int
337#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000338#endif /* UNION_WAIT */
339
Greg Wardb48bc172000-03-01 21:51:56 +0000340/* Don't use the "_r" form if we don't need it (also, won't have a
341 prototype for it, at least on Solaris -- maybe others as well?). */
342#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
343#define USE_CTERMID_R
344#endif
345
Fred Drake699f3522000-06-29 21:12:41 +0000346/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000347#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000348#undef FSTAT
349#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200350#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000351# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700352# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000353# define FSTAT win32_fstat
354# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000355#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000356# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700357# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000358# define FSTAT fstat
359# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000360#endif
361
Tim Peters11b23062003-04-23 02:39:17 +0000362#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000363#include <sys/mkdev.h>
364#else
365#if defined(MAJOR_IN_SYSMACROS)
366#include <sys/sysmacros.h>
367#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000368#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
369#include <sys/mkdev.h>
370#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000371#endif
Fred Drake699f3522000-06-29 21:12:41 +0000372
Victor Stinner6edddfa2013-11-24 19:22:57 +0100373#define DWORD_MAX 4294967295U
374
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375
376#ifdef MS_WINDOWS
377static int
378win32_warn_bytes_api()
379{
380 return PyErr_WarnEx(PyExc_DeprecationWarning,
381 "The Windows bytes API has been deprecated, "
382 "use Unicode filenames instead",
383 1);
384}
385#endif
386
387
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200388#ifndef MS_WINDOWS
389PyObject *
390_PyLong_FromUid(uid_t uid)
391{
392 if (uid == (uid_t)-1)
393 return PyLong_FromLong(-1);
394 return PyLong_FromUnsignedLong(uid);
395}
396
397PyObject *
398_PyLong_FromGid(gid_t gid)
399{
400 if (gid == (gid_t)-1)
401 return PyLong_FromLong(-1);
402 return PyLong_FromUnsignedLong(gid);
403}
404
405int
406_Py_Uid_Converter(PyObject *obj, void *p)
407{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700408 uid_t uid;
409 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200410 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200411 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700412 unsigned long uresult;
413
414 index = PyNumber_Index(obj);
415 if (index == NULL) {
416 PyErr_Format(PyExc_TypeError,
417 "uid should be integer, not %.200s",
418 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200419 return 0;
420 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700421
422 /*
423 * Handling uid_t is complicated for two reasons:
424 * * Although uid_t is (always?) unsigned, it still
425 * accepts -1.
426 * * We don't know its size in advance--it may be
427 * bigger than an int, or it may be smaller than
428 * a long.
429 *
430 * So a bit of defensive programming is in order.
431 * Start with interpreting the value passed
432 * in as a signed long and see if it works.
433 */
434
435 result = PyLong_AsLongAndOverflow(index, &overflow);
436
437 if (!overflow) {
438 uid = (uid_t)result;
439
440 if (result == -1) {
441 if (PyErr_Occurred())
442 goto fail;
443 /* It's a legitimate -1, we're done. */
444 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200445 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700446
447 /* Any other negative number is disallowed. */
448 if (result < 0)
449 goto underflow;
450
451 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200452 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453 (long)uid != result)
454 goto underflow;
455 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200456 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700457
458 if (overflow < 0)
459 goto underflow;
460
461 /*
462 * Okay, the value overflowed a signed long. If it
463 * fits in an *unsigned* long, it may still be okay,
464 * as uid_t may be unsigned long on this platform.
465 */
466 uresult = PyLong_AsUnsignedLong(index);
467 if (PyErr_Occurred()) {
468 if (PyErr_ExceptionMatches(PyExc_OverflowError))
469 goto overflow;
470 goto fail;
471 }
472
473 uid = (uid_t)uresult;
474
475 /*
476 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
477 * but this value would get interpreted as (uid_t)-1 by chown
478 * and its siblings. That's not what the user meant! So we
479 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100480 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700481 */
482 if (uid == (uid_t)-1)
483 goto overflow;
484
485 /* Ensure the value wasn't truncated. */
486 if (sizeof(uid_t) < sizeof(long) &&
487 (unsigned long)uid != uresult)
488 goto overflow;
489 /* fallthrough */
490
491success:
492 Py_DECREF(index);
493 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200494 return 1;
495
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700496underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200497 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700498 "uid is less than minimum");
499 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700501overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200502 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700503 "uid is greater than maximum");
504 /* fallthrough */
505
506fail:
507 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 return 0;
509}
510
511int
512_Py_Gid_Converter(PyObject *obj, void *p)
513{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700514 gid_t gid;
515 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200516 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200517 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518 unsigned long uresult;
519
520 index = PyNumber_Index(obj);
521 if (index == NULL) {
522 PyErr_Format(PyExc_TypeError,
523 "gid should be integer, not %.200s",
524 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200525 return 0;
526 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700527
528 /*
529 * Handling gid_t is complicated for two reasons:
530 * * Although gid_t is (always?) unsigned, it still
531 * accepts -1.
532 * * We don't know its size in advance--it may be
533 * bigger than an int, or it may be smaller than
534 * a long.
535 *
536 * So a bit of defensive programming is in order.
537 * Start with interpreting the value passed
538 * in as a signed long and see if it works.
539 */
540
541 result = PyLong_AsLongAndOverflow(index, &overflow);
542
543 if (!overflow) {
544 gid = (gid_t)result;
545
546 if (result == -1) {
547 if (PyErr_Occurred())
548 goto fail;
549 /* It's a legitimate -1, we're done. */
550 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200551 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700552
553 /* Any other negative number is disallowed. */
554 if (result < 0) {
555 goto underflow;
556 }
557
558 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200559 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700560 (long)gid != result)
561 goto underflow;
562 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200563 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700564
565 if (overflow < 0)
566 goto underflow;
567
568 /*
569 * Okay, the value overflowed a signed long. If it
570 * fits in an *unsigned* long, it may still be okay,
571 * as gid_t may be unsigned long on this platform.
572 */
573 uresult = PyLong_AsUnsignedLong(index);
574 if (PyErr_Occurred()) {
575 if (PyErr_ExceptionMatches(PyExc_OverflowError))
576 goto overflow;
577 goto fail;
578 }
579
580 gid = (gid_t)uresult;
581
582 /*
583 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
584 * but this value would get interpreted as (gid_t)-1 by chown
585 * and its siblings. That's not what the user meant! So we
586 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100587 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700588 */
589 if (gid == (gid_t)-1)
590 goto overflow;
591
592 /* Ensure the value wasn't truncated. */
593 if (sizeof(gid_t) < sizeof(long) &&
594 (unsigned long)gid != uresult)
595 goto overflow;
596 /* fallthrough */
597
598success:
599 Py_DECREF(index);
600 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200601 return 1;
602
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200604 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700605 "gid is less than minimum");
606 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610 "gid is greater than maximum");
611 /* fallthrough */
612
613fail:
614 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 return 0;
616}
617#endif /* MS_WINDOWS */
618
619
Larry Hastings9cf065c2012-06-22 16:30:09 -0700620#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400621/*
622 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
623 * without the int cast, the value gets interpreted as uint (4291925331),
624 * which doesn't play nicely with all the initializer lines in this file that
625 * look like this:
626 * int dir_fd = DEFAULT_DIR_FD;
627 */
628#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700629#else
630#define DEFAULT_DIR_FD (-100)
631#endif
632
633static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200634_fd_converter(PyObject *o, int *p, const char *allowed)
635{
636 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 long long_value;
638
639 PyObject *index = PyNumber_Index(o);
640 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200641 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "argument should be %s, not %.200s",
643 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700644 return 0;
645 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700646
647 long_value = PyLong_AsLongAndOverflow(index, &overflow);
648 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200649 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700650 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700651 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700652 return 0;
653 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200654 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700655 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700656 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700657 return 0;
658 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700659
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660 *p = (int)long_value;
661 return 1;
662}
663
664static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200665dir_fd_converter(PyObject *o, void *p)
666{
667 if (o == Py_None) {
668 *(int *)p = DEFAULT_DIR_FD;
669 return 1;
670 }
671 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700672}
673
674
Larry Hastings9cf065c2012-06-22 16:30:09 -0700675/*
676 * A PyArg_ParseTuple "converter" function
677 * that handles filesystem paths in the manner
678 * preferred by the os module.
679 *
680 * path_converter accepts (Unicode) strings and their
681 * subclasses, and bytes and their subclasses. What
682 * it does with the argument depends on the platform:
683 *
684 * * On Windows, if we get a (Unicode) string we
685 * extract the wchar_t * and return it; if we get
686 * bytes we extract the char * and return that.
687 *
688 * * On all other platforms, strings are encoded
689 * to bytes using PyUnicode_FSConverter, then we
690 * extract the char * from the bytes object and
691 * return that.
692 *
693 * path_converter also optionally accepts signed
694 * integers (representing open file descriptors) instead
695 * of path strings.
696 *
697 * Input fields:
698 * path.nullable
699 * If nonzero, the path is permitted to be None.
700 * path.allow_fd
701 * If nonzero, the path is permitted to be a file handle
702 * (a signed int) instead of a string.
703 * path.function_name
704 * If non-NULL, path_converter will use that as the name
705 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700706 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700707 * path.argument_name
708 * If non-NULL, path_converter will use that as the name
709 * of the parameter in error messages.
710 * (If path.argument_name is NULL it uses "path".)
711 *
712 * Output fields:
713 * path.wide
714 * Points to the path if it was expressed as Unicode
715 * and was not encoded. (Only used on Windows.)
716 * path.narrow
717 * Points to the path if it was expressed as bytes,
718 * or it was Unicode and was encoded to bytes.
719 * path.fd
720 * Contains a file descriptor if path.accept_fd was true
721 * and the caller provided a signed integer instead of any
722 * sort of string.
723 *
724 * WARNING: if your "path" parameter is optional, and is
725 * unspecified, path_converter will never get called.
726 * So if you set allow_fd, you *MUST* initialize path.fd = -1
727 * yourself!
728 * path.length
729 * The length of the path in characters, if specified as
730 * a string.
731 * path.object
732 * The original object passed in.
733 * path.cleanup
734 * For internal use only. May point to a temporary object.
735 * (Pay no attention to the man behind the curtain.)
736 *
737 * At most one of path.wide or path.narrow will be non-NULL.
738 * If path was None and path.nullable was set,
739 * or if path was an integer and path.allow_fd was set,
740 * both path.wide and path.narrow will be NULL
741 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200742 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700743 * path_converter takes care to not write to the path_t
744 * unless it's successful. However it must reset the
745 * "cleanup" field each time it's called.
746 *
747 * Use as follows:
748 * path_t path;
749 * memset(&path, 0, sizeof(path));
750 * PyArg_ParseTuple(args, "O&", path_converter, &path);
751 * // ... use values from path ...
752 * path_cleanup(&path);
753 *
754 * (Note that if PyArg_Parse fails you don't need to call
755 * path_cleanup(). However it is safe to do so.)
756 */
757typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100758 const char *function_name;
759 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760 int nullable;
761 int allow_fd;
762 wchar_t *wide;
763 char *narrow;
764 int fd;
765 Py_ssize_t length;
766 PyObject *object;
767 PyObject *cleanup;
768} path_t;
769
Larry Hastings2f936352014-08-05 14:04:04 +1000770#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
771 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700772
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773static void
774path_cleanup(path_t *path) {
775 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200776 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700777 }
778}
779
780static int
781path_converter(PyObject *o, void *p) {
782 path_t *path = (path_t *)p;
783 PyObject *unicode, *bytes;
784 Py_ssize_t length;
785 char *narrow;
786
787#define FORMAT_EXCEPTION(exc, fmt) \
788 PyErr_Format(exc, "%s%s" fmt, \
789 path->function_name ? path->function_name : "", \
790 path->function_name ? ": " : "", \
791 path->argument_name ? path->argument_name : "path")
792
793 /* Py_CLEANUP_SUPPORTED support */
794 if (o == NULL) {
795 path_cleanup(path);
796 return 1;
797 }
798
799 /* ensure it's always safe to call path_cleanup() */
800 path->cleanup = NULL;
801
802 if (o == Py_None) {
803 if (!path->nullable) {
804 FORMAT_EXCEPTION(PyExc_TypeError,
805 "can't specify None for %s argument");
806 return 0;
807 }
808 path->wide = NULL;
809 path->narrow = NULL;
810 path->length = 0;
811 path->object = o;
812 path->fd = -1;
813 return 1;
814 }
815
816 unicode = PyUnicode_FromObject(o);
817 if (unicode) {
818#ifdef MS_WINDOWS
819 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100820
821 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
822 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700823 Py_DECREF(unicode);
824 return 0;
825 }
Victor Stinner59799a82013-11-13 14:17:30 +0100826 if (length > 32767) {
827 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700828 Py_DECREF(unicode);
829 return 0;
830 }
831
832 path->wide = wide;
833 path->narrow = NULL;
834 path->length = length;
835 path->object = o;
836 path->fd = -1;
837 path->cleanup = unicode;
838 return Py_CLEANUP_SUPPORTED;
839#else
840 int converted = PyUnicode_FSConverter(unicode, &bytes);
841 Py_DECREF(unicode);
842 if (!converted)
843 bytes = NULL;
844#endif
845 }
846 else {
847 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200848 if (PyObject_CheckBuffer(o))
849 bytes = PyBytes_FromObject(o);
850 else
851 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700852 if (!bytes) {
853 PyErr_Clear();
854 if (path->allow_fd) {
855 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200856 int result = _fd_converter(o, &fd,
857 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 if (result) {
859 path->wide = NULL;
860 path->narrow = NULL;
861 path->length = 0;
862 path->object = o;
863 path->fd = fd;
864 return result;
865 }
866 }
867 }
868 }
869
870 if (!bytes) {
871 if (!PyErr_Occurred())
872 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
873 return 0;
874 }
875
876#ifdef MS_WINDOWS
877 if (win32_warn_bytes_api()) {
878 Py_DECREF(bytes);
879 return 0;
880 }
881#endif
882
883 length = PyBytes_GET_SIZE(bytes);
884#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100885 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700886 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
887 Py_DECREF(bytes);
888 return 0;
889 }
890#endif
891
892 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200893 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300894 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895 Py_DECREF(bytes);
896 return 0;
897 }
898
899 path->wide = NULL;
900 path->narrow = narrow;
901 path->length = length;
902 path->object = o;
903 path->fd = -1;
904 path->cleanup = bytes;
905 return Py_CLEANUP_SUPPORTED;
906}
907
908static void
909argument_unavailable_error(char *function_name, char *argument_name) {
910 PyErr_Format(PyExc_NotImplementedError,
911 "%s%s%s unavailable on this platform",
912 (function_name != NULL) ? function_name : "",
913 (function_name != NULL) ? ": ": "",
914 argument_name);
915}
916
917static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200918dir_fd_unavailable(PyObject *o, void *p)
919{
920 int dir_fd;
921 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200923 if (dir_fd != DEFAULT_DIR_FD) {
924 argument_unavailable_error(NULL, "dir_fd");
925 return 0;
926 }
927 *(int *)p = dir_fd;
928 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929}
930
931static int
932fd_specified(char *function_name, int fd) {
933 if (fd == -1)
934 return 0;
935
936 argument_unavailable_error(function_name, "fd");
937 return 1;
938}
939
940static int
941follow_symlinks_specified(char *function_name, int follow_symlinks) {
942 if (follow_symlinks)
943 return 0;
944
945 argument_unavailable_error(function_name, "follow_symlinks");
946 return 1;
947}
948
949static int
950path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
951 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
952 PyErr_Format(PyExc_ValueError,
953 "%s: can't specify dir_fd without matching path",
954 function_name);
955 return 1;
956 }
957 return 0;
958}
959
960static int
961dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
962 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
963 PyErr_Format(PyExc_ValueError,
964 "%s: can't specify both dir_fd and fd",
965 function_name);
966 return 1;
967 }
968 return 0;
969}
970
971static int
972fd_and_follow_symlinks_invalid(char *function_name, int fd,
973 int follow_symlinks) {
974 if ((fd > 0) && (!follow_symlinks)) {
975 PyErr_Format(PyExc_ValueError,
976 "%s: cannot use fd and follow_symlinks together",
977 function_name);
978 return 1;
979 }
980 return 0;
981}
982
983static int
984dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
985 int follow_symlinks) {
986 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: cannot use dir_fd and follow_symlinks together",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
Larry Hastings2f936352014-08-05 14:04:04 +1000995#ifdef MS_WINDOWS
996 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000997#else
Larry Hastings2f936352014-08-05 14:04:04 +1000998 typedef off_t Py_off_t;
999#endif
1000
1001static int
1002Py_off_t_converter(PyObject *arg, void *addr)
1003{
1004#ifdef HAVE_LARGEFILE_SUPPORT
1005 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1006#else
1007 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001008#endif
1009 if (PyErr_Occurred())
1010 return 0;
1011 return 1;
1012}
Larry Hastings2f936352014-08-05 14:04:04 +10001013
1014static PyObject *
1015PyLong_FromPy_off_t(Py_off_t offset)
1016{
1017#ifdef HAVE_LARGEFILE_SUPPORT
1018 return PyLong_FromLongLong(offset);
1019#else
1020 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001021#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001022}
1023
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001024
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001025#if defined _MSC_VER && _MSC_VER >= 1400
1026/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001027 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001028 * Normally, an invalid fd is likely to be a C program error and therefore
1029 * an assertion can be useful, but it does contradict the POSIX standard
1030 * which for write(2) states:
1031 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1032 * "[EBADF] The fildes argument is not a valid file descriptor open for
1033 * writing."
1034 * Furthermore, python allows the user to enter any old integer
1035 * as a fd and should merely raise a python exception on error.
1036 * The Microsoft CRT doesn't provide an official way to check for the
1037 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001038 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001039 * internal structures involved.
1040 * The structures below must be updated for each version of visual studio
1041 * according to the file internal.h in the CRT source, until MS comes
1042 * up with a less hacky way to do this.
1043 * (all of this is to avoid globally modifying the CRT behaviour using
1044 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1045 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001046/* The actual size of the structure is determined at runtime.
1047 * Only the first items must be present.
1048 */
Steve Dower65e4cb12014-11-22 12:54:57 -08001049
1050#if _MSC_VER >= 1900
1051
1052typedef struct {
1053 CRITICAL_SECTION lock;
1054 intptr_t osfhnd;
1055 __int64 startpos;
1056 char osfile;
1057} my_ioinfo;
1058
1059#define IOINFO_L2E 6
1060#define IOINFO_ARRAYS 128
1061
1062#else
1063
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001064typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 intptr_t osfhnd;
1066 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001067} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001069#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001070#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001071
1072#endif
1073
1074extern __declspec(dllimport) char * __pioinfo[];
1075#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001076#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1077#define FOPEN 0x01
1078#define _NO_CONSOLE_FILENO (intptr_t)-2
1079
1080/* This function emulates what the windows CRT does to validate file handles */
1081int
1082_PyVerify_fd(int fd)
1083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 const int i1 = fd >> IOINFO_L2E;
1085 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001086
Antoine Pitrou22e41552010-08-15 18:07:50 +00001087 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001088
Victor Stinner8c62be82010-05-06 00:08:46 +00001089 /* Determine the actual size of the ioinfo structure,
1090 * as used by the CRT loaded in memory
1091 */
1092 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1093 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1094 }
1095 if (sizeof_ioinfo == 0) {
1096 /* This should not happen... */
1097 goto fail;
1098 }
1099
1100 /* See that it isn't a special CLEAR fileno */
1101 if (fd != _NO_CONSOLE_FILENO) {
1102 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1103 * we check pointer validity and other info
1104 */
1105 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1106 /* finally, check that the file is open */
1107 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1108 if (info->osfile & FOPEN) {
1109 return 1;
1110 }
1111 }
1112 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001113 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001114 errno = EBADF;
1115 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001116}
1117
1118/* the special case of checking dup2. The target fd must be in a sensible range */
1119static int
1120_PyVerify_fd_dup2(int fd1, int fd2)
1121{
Victor Stinner8c62be82010-05-06 00:08:46 +00001122 if (!_PyVerify_fd(fd1))
1123 return 0;
1124 if (fd2 == _NO_CONSOLE_FILENO)
1125 return 0;
1126 if ((unsigned)fd2 < _NHANDLE_)
1127 return 1;
1128 else
1129 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001130}
1131#else
1132/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1133#define _PyVerify_fd_dup2(A, B) (1)
1134#endif
1135
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001136#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001137
1138static int
Brian Curtind25aef52011-06-13 15:16:04 -05001139win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001140{
1141 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1142 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1143 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001144
1145 if (0 == DeviceIoControl(
1146 reparse_point_handle,
1147 FSCTL_GET_REPARSE_POINT,
1148 NULL, 0, /* in buffer */
1149 target_buffer, sizeof(target_buffer),
1150 &n_bytes_returned,
1151 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001152 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001153
1154 if (reparse_tag)
1155 *reparse_tag = rdb->ReparseTag;
1156
Brian Curtind25aef52011-06-13 15:16:04 -05001157 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001158}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001159
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001160#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001161
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001163#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001164/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001165** environ directly, we must obtain it with _NSGetEnviron(). See also
1166** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001167*/
1168#include <crt_externs.h>
1169static char **environ;
1170#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173
Barry Warsaw53699e91996-12-10 23:23:01 +00001174static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001175convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176{
Victor Stinner8c62be82010-05-06 00:08:46 +00001177 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001178#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001179 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001180#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001181 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001182#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001183
Victor Stinner8c62be82010-05-06 00:08:46 +00001184 d = PyDict_New();
1185 if (d == NULL)
1186 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001187#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001188 if (environ == NULL)
1189 environ = *_NSGetEnviron();
1190#endif
1191#ifdef MS_WINDOWS
1192 /* _wenviron must be initialized in this way if the program is started
1193 through main() instead of wmain(). */
1194 _wgetenv(L"");
1195 if (_wenviron == NULL)
1196 return d;
1197 /* This part ignores errors */
1198 for (e = _wenviron; *e != NULL; e++) {
1199 PyObject *k;
1200 PyObject *v;
1201 wchar_t *p = wcschr(*e, L'=');
1202 if (p == NULL)
1203 continue;
1204 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1205 if (k == NULL) {
1206 PyErr_Clear();
1207 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001208 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001209 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1210 if (v == NULL) {
1211 PyErr_Clear();
1212 Py_DECREF(k);
1213 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001214 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001215 if (PyDict_GetItem(d, k) == NULL) {
1216 if (PyDict_SetItem(d, k, v) != 0)
1217 PyErr_Clear();
1218 }
1219 Py_DECREF(k);
1220 Py_DECREF(v);
1221 }
1222#else
1223 if (environ == NULL)
1224 return d;
1225 /* This part ignores errors */
1226 for (e = environ; *e != NULL; e++) {
1227 PyObject *k;
1228 PyObject *v;
1229 char *p = strchr(*e, '=');
1230 if (p == NULL)
1231 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001232 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 if (k == NULL) {
1234 PyErr_Clear();
1235 continue;
1236 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001237 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001238 if (v == NULL) {
1239 PyErr_Clear();
1240 Py_DECREF(k);
1241 continue;
1242 }
1243 if (PyDict_GetItem(d, k) == NULL) {
1244 if (PyDict_SetItem(d, k, v) != 0)
1245 PyErr_Clear();
1246 }
1247 Py_DECREF(k);
1248 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001249 }
1250#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001251 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252}
1253
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254/* Set a POSIX-specific error from errno, and return NULL */
1255
Barry Warsawd58d7641998-07-23 16:14:40 +00001256static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001257posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001258{
Victor Stinner8c62be82010-05-06 00:08:46 +00001259 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001260}
Mark Hammondef8b6542001-05-13 08:04:26 +00001261
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001262#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001263static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001264win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001265{
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 /* XXX We should pass the function name along in the future.
1267 (winreg.c also wants to pass the function name.)
1268 This would however require an additional param to the
1269 Windows error object, which is non-trivial.
1270 */
1271 errno = GetLastError();
1272 if (filename)
1273 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1274 else
1275 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001276}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001277
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001278static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001279win32_error_object(char* function, PyObject* filename)
1280{
1281 /* XXX - see win32_error for comments on 'function' */
1282 errno = GetLastError();
1283 if (filename)
1284 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001285 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 errno,
1287 filename);
1288 else
1289 return PyErr_SetFromWindowsErr(errno);
1290}
1291
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001292#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293
Larry Hastings9cf065c2012-06-22 16:30:09 -07001294static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001295path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001296{
1297#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001298 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1299 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001300#else
Victor Stinner292c8352012-10-30 02:17:38 +01001301 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001302#endif
1303}
1304
Larry Hastings31826802013-10-19 00:09:25 -07001305
Larry Hastingsb0827312014-02-09 22:05:19 -08001306static PyObject *
1307path_error2(path_t *path, path_t *path2)
1308{
1309#ifdef MS_WINDOWS
1310 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1311 0, path->object, path2->object);
1312#else
1313 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1314 path->object, path2->object);
1315#endif
1316}
1317
1318
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001319/* POSIX generic methods */
1320
Larry Hastings2f936352014-08-05 14:04:04 +10001321static int
1322fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001323{
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001325 int *pointer = (int *)p;
1326 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001327 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001328 return 0;
1329 if (!_PyVerify_fd(fd)) {
1330 posix_error();
1331 return 0;
1332 }
1333 *pointer = fd;
1334 return 1;
1335}
1336
1337static PyObject *
1338posix_fildes_fd(int fd, int (*func)(int))
1339{
1340 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00001341 Py_BEGIN_ALLOW_THREADS
1342 res = (*func)(fd);
1343 Py_END_ALLOW_THREADS
1344 if (res < 0)
1345 return posix_error();
1346 Py_INCREF(Py_None);
1347 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001348}
Guido van Rossum21142a01999-01-08 21:05:37 +00001349
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001351#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352/* This is a reimplementation of the C library's chdir function,
1353 but one that produces Win32 errors instead of DOS error codes.
1354 chdir is essentially a wrapper around SetCurrentDirectory; however,
1355 it also needs to set "magic" environment variables indicating
1356 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001357static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001358win32_chdir(LPCSTR path)
1359{
Victor Stinner75875072013-11-24 19:23:25 +01001360 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 int result;
1362 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001363
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if(!SetCurrentDirectoryA(path))
1365 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001366 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 if (!result)
1368 return FALSE;
1369 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001370 than MAX_PATH-1 (not including the final null character). */
1371 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (strncmp(new_path, "\\\\", 2) == 0 ||
1373 strncmp(new_path, "//", 2) == 0)
1374 /* UNC path, nothing to do. */
1375 return TRUE;
1376 env[1] = new_path[0];
1377 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378}
1379
1380/* The Unicode version differs from the ANSI version
1381 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001382static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001383win32_wchdir(LPCWSTR path)
1384{
Victor Stinner75875072013-11-24 19:23:25 +01001385 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 int result;
1387 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001388
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 if(!SetCurrentDirectoryW(path))
1390 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001391 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001392 if (!result)
1393 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001394 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001395 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 if (!new_path) {
1397 SetLastError(ERROR_OUTOFMEMORY);
1398 return FALSE;
1399 }
1400 result = GetCurrentDirectoryW(result, new_path);
1401 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001402 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001403 return FALSE;
1404 }
1405 }
1406 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1407 wcsncmp(new_path, L"//", 2) == 0)
1408 /* UNC path, nothing to do. */
1409 return TRUE;
1410 env[1] = new_path[0];
1411 result = SetEnvironmentVariableW(env, new_path);
1412 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001413 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415}
1416#endif
1417
Martin v. Löwis14694662006-02-03 12:54:16 +00001418#ifdef MS_WINDOWS
1419/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1420 - time stamps are restricted to second resolution
1421 - file modification times suffer from forth-and-back conversions between
1422 UTC and local time
1423 Therefore, we implement our own stat, based on the Win32 API directly.
1424*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001425#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001426#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001427
1428struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001429 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001430 __int64 st_ino;
1431 unsigned short st_mode;
1432 int st_nlink;
1433 int st_uid;
1434 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001435 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001436 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001437 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001438 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001439 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001440 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001441 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442 int st_ctime_nsec;
Zachary Ware63f277b2014-06-19 09:46:37 -05001443 unsigned long st_file_attributes;
Martin v. Löwis14694662006-02-03 12:54:16 +00001444};
1445
1446static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1447
1448static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001449FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001450{
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1452 /* Cannot simply cast and dereference in_ptr,
1453 since it might not be aligned properly */
1454 __int64 in;
1455 memcpy(&in, in_ptr, sizeof(in));
1456 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001457 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001458}
1459
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001461time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462{
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 /* XXX endianness */
1464 __int64 out;
1465 out = time_in + secs_between_epochs;
1466 out = out * 10000000 + nsec_in / 100;
1467 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468}
1469
Martin v. Löwis14694662006-02-03 12:54:16 +00001470/* Below, we *know* that ugo+r is 0444 */
1471#if _S_IREAD != 0400
1472#error Unsupported C library
1473#endif
1474static int
1475attributes_to_mode(DWORD attr)
1476{
Victor Stinner8c62be82010-05-06 00:08:46 +00001477 int m = 0;
1478 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1479 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1480 else
1481 m |= _S_IFREG;
1482 if (attr & FILE_ATTRIBUTE_READONLY)
1483 m |= 0444;
1484 else
1485 m |= 0666;
1486 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001487}
1488
1489static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001490attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001491{
Victor Stinner8c62be82010-05-06 00:08:46 +00001492 memset(result, 0, sizeof(*result));
1493 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1494 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001495 result->st_dev = info->dwVolumeSerialNumber;
1496 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001497 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1498 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1499 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001500 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001501 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001502 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1503 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001504 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001505 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001506 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001507 }
Zachary Ware63f277b2014-06-19 09:46:37 -05001508 result->st_file_attributes = info->dwFileAttributes;
Martin v. Löwis14694662006-02-03 12:54:16 +00001509
Victor Stinner8c62be82010-05-06 00:08:46 +00001510 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001511}
1512
Guido van Rossumd8faa362007-04-27 19:54:29 +00001513static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001515{
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 HANDLE hFindFile;
1517 WIN32_FIND_DATAA FileData;
1518 hFindFile = FindFirstFileA(pszFile, &FileData);
1519 if (hFindFile == INVALID_HANDLE_VALUE)
1520 return FALSE;
1521 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001523 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001524 info->dwFileAttributes = FileData.dwFileAttributes;
1525 info->ftCreationTime = FileData.ftCreationTime;
1526 info->ftLastAccessTime = FileData.ftLastAccessTime;
1527 info->ftLastWriteTime = FileData.ftLastWriteTime;
1528 info->nFileSizeHigh = FileData.nFileSizeHigh;
1529 info->nFileSizeLow = FileData.nFileSizeLow;
1530/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1532 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001533 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001534}
1535
1536static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001537attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001538{
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 HANDLE hFindFile;
1540 WIN32_FIND_DATAW FileData;
1541 hFindFile = FindFirstFileW(pszFile, &FileData);
1542 if (hFindFile == INVALID_HANDLE_VALUE)
1543 return FALSE;
1544 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001546 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001547 info->dwFileAttributes = FileData.dwFileAttributes;
1548 info->ftCreationTime = FileData.ftCreationTime;
1549 info->ftLastAccessTime = FileData.ftLastAccessTime;
1550 info->ftLastWriteTime = FileData.ftLastWriteTime;
1551 info->nFileSizeHigh = FileData.nFileSizeHigh;
1552 info->nFileSizeLow = FileData.nFileSizeLow;
1553/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001554 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1555 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001556 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001557}
1558
Brian Curtind25aef52011-06-13 15:16:04 -05001559/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001560static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001561static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1562 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563static int
Brian Curtind25aef52011-06-13 15:16:04 -05001564check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565{
Brian Curtind25aef52011-06-13 15:16:04 -05001566 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001567 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1568 DWORD);
1569
Brian Curtind25aef52011-06-13 15:16:04 -05001570 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001571 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001572 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001573 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001574 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1575 "GetFinalPathNameByHandleA");
1576 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1577 "GetFinalPathNameByHandleW");
1578 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1579 Py_GetFinalPathNameByHandleW;
1580 }
1581 return has_GetFinalPathNameByHandle;
1582}
1583
1584static BOOL
1585get_target_path(HANDLE hdl, wchar_t **target_path)
1586{
1587 int buf_size, result_length;
1588 wchar_t *buf;
1589
1590 /* We have a good handle to the target, use it to determine
1591 the target path name (then we'll call lstat on it). */
1592 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1593 VOLUME_NAME_DOS);
1594 if(!buf_size)
1595 return FALSE;
1596
Victor Stinnerb6404912013-07-07 16:21:41 +02001597 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001598 if (!buf) {
1599 SetLastError(ERROR_OUTOFMEMORY);
1600 return FALSE;
1601 }
1602
Brian Curtind25aef52011-06-13 15:16:04 -05001603 result_length = Py_GetFinalPathNameByHandleW(hdl,
1604 buf, buf_size, VOLUME_NAME_DOS);
1605
1606 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001607 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001608 return FALSE;
1609 }
1610
1611 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001612 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001613 return FALSE;
1614 }
1615
1616 buf[result_length] = 0;
1617
1618 *target_path = buf;
1619 return TRUE;
1620}
1621
1622static int
1623win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1624 BOOL traverse);
1625static int
1626win32_xstat_impl(const char *path, struct win32_stat *result,
1627 BOOL traverse)
1628{
Victor Stinner26de69d2011-06-17 15:15:38 +02001629 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001630 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001631 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001633 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001634 const char *dot;
1635
Brian Curtind25aef52011-06-13 15:16:04 -05001636 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001637 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1638 traverse reparse point. */
1639 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 }
1641
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642 hFile = CreateFileA(
1643 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001644 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645 0, /* share mode */
1646 NULL, /* security attributes */
1647 OPEN_EXISTING,
1648 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001649 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1650 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001651 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001652 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1653 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 NULL);
1655
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 /* Either the target doesn't exist, or we don't have access to
1658 get a handle to it. If the former, we need to return an error.
1659 If the latter, we can use attributes_from_dir. */
1660 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 return -1;
1662 /* Could not get attributes on open file. Fall back to
1663 reading the directory. */
1664 if (!attributes_from_dir(path, &info, &reparse_tag))
1665 /* Very strange. This should not fail now */
1666 return -1;
1667 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1668 if (traverse) {
1669 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001671 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 } else {
1675 if (!GetFileInformationByHandle(hFile, &info)) {
1676 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001677 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001678 }
1679 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001680 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1681 return -1;
1682
1683 /* Close the outer open file handle now that we're about to
1684 reopen it with different flags. */
1685 if (!CloseHandle(hFile))
1686 return -1;
1687
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001689 /* In order to call GetFinalPathNameByHandle we need to open
1690 the file without the reparse handling flag set. */
1691 hFile2 = CreateFileA(
1692 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1693 NULL, OPEN_EXISTING,
1694 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1695 NULL);
1696 if (hFile2 == INVALID_HANDLE_VALUE)
1697 return -1;
1698
1699 if (!get_target_path(hFile2, &target_path))
1700 return -1;
1701
1702 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001703 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 return code;
1705 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001706 } else
1707 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001708 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710
1711 /* Set S_IEXEC if it is an .exe, .bat, ... */
1712 dot = strrchr(path, '.');
1713 if (dot) {
1714 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1715 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1716 result->st_mode |= 0111;
1717 }
1718 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719}
1720
1721static int
Brian Curtind25aef52011-06-13 15:16:04 -05001722win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1723 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724{
1725 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001726 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001728 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001729 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001730 const wchar_t *dot;
1731
Brian Curtind25aef52011-06-13 15:16:04 -05001732 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001733 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1734 traverse reparse point. */
1735 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 }
1737
Brian Curtinf5e76d02010-11-24 13:14:05 +00001738 hFile = CreateFileW(
1739 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001740 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001741 0, /* share mode */
1742 NULL, /* security attributes */
1743 OPEN_EXISTING,
1744 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001745 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1746 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001747 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001748 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001749 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750 NULL);
1751
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001752 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001753 /* Either the target doesn't exist, or we don't have access to
1754 get a handle to it. If the former, we need to return an error.
1755 If the latter, we can use attributes_from_dir. */
1756 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 return -1;
1758 /* Could not get attributes on open file. Fall back to
1759 reading the directory. */
1760 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1761 /* Very strange. This should not fail now */
1762 return -1;
1763 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1764 if (traverse) {
1765 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001766 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001767 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001769 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770 } else {
1771 if (!GetFileInformationByHandle(hFile, &info)) {
1772 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001773 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001774 }
1775 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001776 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1777 return -1;
1778
1779 /* Close the outer open file handle now that we're about to
1780 reopen it with different flags. */
1781 if (!CloseHandle(hFile))
1782 return -1;
1783
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001785 /* In order to call GetFinalPathNameByHandle we need to open
1786 the file without the reparse handling flag set. */
1787 hFile2 = CreateFileW(
1788 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1789 NULL, OPEN_EXISTING,
1790 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1791 NULL);
1792 if (hFile2 == INVALID_HANDLE_VALUE)
1793 return -1;
1794
1795 if (!get_target_path(hFile2, &target_path))
1796 return -1;
1797
1798 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001799 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001800 return code;
1801 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001802 } else
1803 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001804 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001805 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001806
1807 /* Set S_IEXEC if it is an .exe, .bat, ... */
1808 dot = wcsrchr(path, '.');
1809 if (dot) {
1810 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1811 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1812 result->st_mode |= 0111;
1813 }
1814 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001815}
1816
1817static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001819{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001820 /* Protocol violation: we explicitly clear errno, instead of
1821 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001822 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001823 errno = 0;
1824 return code;
1825}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001826
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001827static int
1828win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1829{
1830 /* Protocol violation: we explicitly clear errno, instead of
1831 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001832 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 errno = 0;
1834 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001835}
Brian Curtind25aef52011-06-13 15:16:04 -05001836/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001837
1838 In Posix, stat automatically traverses symlinks and returns the stat
1839 structure for the target. In Windows, the equivalent GetFileAttributes by
1840 default does not traverse symlinks and instead returns attributes for
1841 the symlink.
1842
1843 Therefore, win32_lstat will get the attributes traditionally, and
1844 win32_stat will first explicitly resolve the symlink target and then will
1845 call win32_lstat on that result.
1846
Ezio Melotti4969f702011-03-15 05:59:46 +02001847 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001848
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001849static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001850win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001851{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001852 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001853}
1854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001856win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001857{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001858 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001859}
1860
1861static int
1862win32_stat(const char* path, struct win32_stat *result)
1863{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001865}
1866
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001867static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001868win32_stat_w(const wchar_t* path, struct win32_stat *result)
1869{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001870 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
1873static int
1874win32_fstat(int file_number, struct win32_stat *result)
1875{
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 BY_HANDLE_FILE_INFORMATION info;
1877 HANDLE h;
1878 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001879
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001880 if (!_PyVerify_fd(file_number))
1881 h = INVALID_HANDLE_VALUE;
1882 else
1883 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001884
Victor Stinner8c62be82010-05-06 00:08:46 +00001885 /* Protocol violation: we explicitly clear errno, instead of
1886 setting it to a POSIX error. Callers should use GetLastError. */
1887 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001888
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 if (h == INVALID_HANDLE_VALUE) {
1890 /* This is really a C library error (invalid file handle).
1891 We set the Win32 error to the closes one matching. */
1892 SetLastError(ERROR_INVALID_HANDLE);
1893 return -1;
1894 }
1895 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 type = GetFileType(h);
1898 if (type == FILE_TYPE_UNKNOWN) {
1899 DWORD error = GetLastError();
1900 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001901 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001902 }
1903 /* else: valid but unknown file */
1904 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 if (type != FILE_TYPE_DISK) {
1907 if (type == FILE_TYPE_CHAR)
1908 result->st_mode = _S_IFCHR;
1909 else if (type == FILE_TYPE_PIPE)
1910 result->st_mode = _S_IFIFO;
1911 return 0;
1912 }
1913
1914 if (!GetFileInformationByHandle(h, &info)) {
1915 return -1;
1916 }
1917
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001918 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1921 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001922}
1923
1924#endif /* MS_WINDOWS */
1925
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001926PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001927"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001928This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001929 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001930or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1931\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001932Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1933or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001934\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001935See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001936
1937static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 {"st_mode", "protection bits"},
1939 {"st_ino", "inode"},
1940 {"st_dev", "device"},
1941 {"st_nlink", "number of hard links"},
1942 {"st_uid", "user ID of owner"},
1943 {"st_gid", "group ID of owner"},
1944 {"st_size", "total size, in bytes"},
1945 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1946 {NULL, "integer time of last access"},
1947 {NULL, "integer time of last modification"},
1948 {NULL, "integer time of last change"},
1949 {"st_atime", "time of last access"},
1950 {"st_mtime", "time of last modification"},
1951 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001952 {"st_atime_ns", "time of last access in nanoseconds"},
1953 {"st_mtime_ns", "time of last modification in nanoseconds"},
1954 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001955#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001957#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001958#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001960#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001961#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001963#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001964#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001966#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001967#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001969#endif
1970#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001972#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001973#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1974 {"st_file_attributes", "Windows file attribute bits"},
1975#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977};
1978
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001980#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001981#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001982#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983#endif
1984
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001985#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1987#else
1988#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1989#endif
1990
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001991#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1993#else
1994#define ST_RDEV_IDX ST_BLOCKS_IDX
1995#endif
1996
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001997#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1998#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1999#else
2000#define ST_FLAGS_IDX ST_RDEV_IDX
2001#endif
2002
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002003#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002004#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002005#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002006#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002007#endif
2008
2009#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2010#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2011#else
2012#define ST_BIRTHTIME_IDX ST_GEN_IDX
2013#endif
2014
Zachary Ware63f277b2014-06-19 09:46:37 -05002015#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2016#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2017#else
2018#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2019#endif
2020
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002021static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 "stat_result", /* name */
2023 stat_result__doc__, /* doc */
2024 stat_result_fields,
2025 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002026};
2027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2030This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002031 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002032or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002033\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035
2036static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 {"f_bsize", },
2038 {"f_frsize", },
2039 {"f_blocks", },
2040 {"f_bfree", },
2041 {"f_bavail", },
2042 {"f_files", },
2043 {"f_ffree", },
2044 {"f_favail", },
2045 {"f_flag", },
2046 {"f_namemax",},
2047 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048};
2049
2050static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 "statvfs_result", /* name */
2052 statvfs_result__doc__, /* doc */
2053 statvfs_result_fields,
2054 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002055};
2056
Ross Lagerwall7807c352011-03-17 20:20:30 +02002057#if defined(HAVE_WAITID) && !defined(__APPLE__)
2058PyDoc_STRVAR(waitid_result__doc__,
2059"waitid_result: Result from waitid.\n\n\
2060This object may be accessed either as a tuple of\n\
2061 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2062or via the attributes si_pid, si_uid, and so on.\n\
2063\n\
2064See os.waitid for more information.");
2065
2066static PyStructSequence_Field waitid_result_fields[] = {
2067 {"si_pid", },
2068 {"si_uid", },
2069 {"si_signo", },
2070 {"si_status", },
2071 {"si_code", },
2072 {0}
2073};
2074
2075static PyStructSequence_Desc waitid_result_desc = {
2076 "waitid_result", /* name */
2077 waitid_result__doc__, /* doc */
2078 waitid_result_fields,
2079 5
2080};
2081static PyTypeObject WaitidResultType;
2082#endif
2083
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002084static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002085static PyTypeObject StatResultType;
2086static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002087#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002088static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002089#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002090static newfunc structseq_new;
2091
2092static PyObject *
2093statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2094{
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence *result;
2096 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002097
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 result = (PyStructSequence*)structseq_new(type, args, kwds);
2099 if (!result)
2100 return NULL;
2101 /* If we have been initialized from a tuple,
2102 st_?time might be set to None. Initialize it
2103 from the int slots. */
2104 for (i = 7; i <= 9; i++) {
2105 if (result->ob_item[i+3] == Py_None) {
2106 Py_DECREF(Py_None);
2107 Py_INCREF(result->ob_item[i]);
2108 result->ob_item[i+3] = result->ob_item[i];
2109 }
2110 }
2111 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002112}
2113
2114
2115
2116/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002117static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002118
2119PyDoc_STRVAR(stat_float_times__doc__,
2120"stat_float_times([newval]) -> oldval\n\n\
2121Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10002122\n\
2123If value is True, future calls to stat() return floats; if it is False,\n\
2124future calls return ints.\n\
2125If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002126
Larry Hastings2f936352014-08-05 14:04:04 +10002127/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002128static PyObject*
2129stat_float_times(PyObject* self, PyObject *args)
2130{
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 int newval = -1;
2132 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2133 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002134 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2135 "stat_float_times() is deprecated",
2136 1))
2137 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 if (newval == -1)
2139 /* Return old value */
2140 return PyBool_FromLong(_stat_float_times);
2141 _stat_float_times = newval;
2142 Py_INCREF(Py_None);
2143 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002144}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002145
Larry Hastings6fe20b32012-04-19 15:07:49 -07002146static PyObject *billion = NULL;
2147
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002148static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002149fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002150{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002151 PyObject *s = _PyLong_FromTime_t(sec);
2152 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2153 PyObject *s_in_ns = NULL;
2154 PyObject *ns_total = NULL;
2155 PyObject *float_s = NULL;
2156
2157 if (!(s && ns_fractional))
2158 goto exit;
2159
2160 s_in_ns = PyNumber_Multiply(s, billion);
2161 if (!s_in_ns)
2162 goto exit;
2163
2164 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2165 if (!ns_total)
2166 goto exit;
2167
Victor Stinner4195b5c2012-02-08 23:03:19 +01002168 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002169 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2170 if (!float_s)
2171 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002173 else {
2174 float_s = s;
2175 Py_INCREF(float_s);
2176 }
2177
2178 PyStructSequence_SET_ITEM(v, index, s);
2179 PyStructSequence_SET_ITEM(v, index+3, float_s);
2180 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2181 s = NULL;
2182 float_s = NULL;
2183 ns_total = NULL;
2184exit:
2185 Py_XDECREF(s);
2186 Py_XDECREF(ns_fractional);
2187 Py_XDECREF(s_in_ns);
2188 Py_XDECREF(ns_total);
2189 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002190}
2191
Tim Peters5aa91602002-01-30 05:46:57 +00002192/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002193 (used by posix_stat() and posix_fstat()) */
2194static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002195_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002196{
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 unsigned long ansec, mnsec, cnsec;
2198 PyObject *v = PyStructSequence_New(&StatResultType);
2199 if (v == NULL)
2200 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002201
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002203#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 PyStructSequence_SET_ITEM(v, 1,
2205 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002206#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002208#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002209#ifdef MS_WINDOWS
2210 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2211#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002212 PyStructSequence_SET_ITEM(v, 2,
2213 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002214#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002215 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002216#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002217 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002218#if defined(MS_WINDOWS)
2219 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2220 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2221#else
2222 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2223 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2224#endif
Fred Drake699f3522000-06-29 21:12:41 +00002225#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002226 PyStructSequence_SET_ITEM(v, 6,
2227 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002228#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002229 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002230#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002231
Martin v. Löwis14694662006-02-03 12:54:16 +00002232#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002233 ansec = st->st_atim.tv_nsec;
2234 mnsec = st->st_mtim.tv_nsec;
2235 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002236#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002237 ansec = st->st_atimespec.tv_nsec;
2238 mnsec = st->st_mtimespec.tv_nsec;
2239 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002240#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002241 ansec = st->st_atime_nsec;
2242 mnsec = st->st_mtime_nsec;
2243 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002244#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002245 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002246#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002247 fill_time(v, 7, st->st_atime, ansec);
2248 fill_time(v, 8, st->st_mtime, mnsec);
2249 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002250
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002251#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2253 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002254#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002255#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2257 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002258#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002259#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002260 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2261 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002262#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002263#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002264 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2265 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#endif
2267#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002269 PyObject *val;
2270 unsigned long bsec,bnsec;
2271 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002272#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002273 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002274#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002275 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002276#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002277 if (_stat_float_times) {
2278 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2279 } else {
2280 val = PyLong_FromLong((long)bsec);
2281 }
2282 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2283 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002285#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002286#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2288 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002289#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002290#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2291 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2292 PyLong_FromUnsignedLong(st->st_file_attributes));
2293#endif
Fred Drake699f3522000-06-29 21:12:41 +00002294
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 if (PyErr_Occurred()) {
2296 Py_DECREF(v);
2297 return NULL;
2298 }
Fred Drake699f3522000-06-29 21:12:41 +00002299
Victor Stinner8c62be82010-05-06 00:08:46 +00002300 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002301}
2302
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002303/* POSIX methods */
2304
Guido van Rossum94f6f721999-01-06 18:42:14 +00002305
2306static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002307posix_do_stat(char *function_name, path_t *path,
2308 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002309{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002310 STRUCT_STAT st;
2311 int result;
2312
2313#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2314 if (follow_symlinks_specified(function_name, follow_symlinks))
2315 return NULL;
2316#endif
2317
2318 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2319 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2320 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2321 return NULL;
2322
2323 Py_BEGIN_ALLOW_THREADS
2324 if (path->fd != -1)
2325 result = FSTAT(path->fd, &st);
2326 else
2327#ifdef MS_WINDOWS
2328 if (path->wide) {
2329 if (follow_symlinks)
2330 result = win32_stat_w(path->wide, &st);
2331 else
2332 result = win32_lstat_w(path->wide, &st);
2333 }
2334 else
2335#endif
2336#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2337 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2338 result = LSTAT(path->narrow, &st);
2339 else
2340#endif
2341#ifdef HAVE_FSTATAT
2342 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2343 result = fstatat(dir_fd, path->narrow, &st,
2344 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2345 else
2346#endif
2347 result = STAT(path->narrow, &st);
2348 Py_END_ALLOW_THREADS
2349
Victor Stinner292c8352012-10-30 02:17:38 +01002350 if (result != 0) {
2351 return path_error(path);
2352 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002353
2354 return _pystat_fromstructstat(&st);
2355}
2356
Larry Hastings2f936352014-08-05 14:04:04 +10002357/*[python input]
2358
2359for s in """
2360
2361FACCESSAT
2362FCHMODAT
2363FCHOWNAT
2364FSTATAT
2365LINKAT
2366MKDIRAT
2367MKFIFOAT
2368MKNODAT
2369OPENAT
2370READLINKAT
2371SYMLINKAT
2372UNLINKAT
2373
2374""".strip().split():
2375 s = s.strip()
2376 print("""
2377#ifdef HAVE_{s}
2378 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002379#else
Larry Hastings2f936352014-08-05 14:04:04 +10002380 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002381#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002382""".rstrip().format(s=s))
2383
2384for s in """
2385
2386FCHDIR
2387FCHMOD
2388FCHOWN
2389FDOPENDIR
2390FEXECVE
2391FPATHCONF
2392FSTATVFS
2393FTRUNCATE
2394
2395""".strip().split():
2396 s = s.strip()
2397 print("""
2398#ifdef HAVE_{s}
2399 #define PATH_HAVE_{s} 1
2400#else
2401 #define PATH_HAVE_{s} 0
2402#endif
2403
2404""".rstrip().format(s=s))
2405[python start generated code]*/
2406
2407#ifdef HAVE_FACCESSAT
2408 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2409#else
2410 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2411#endif
2412
2413#ifdef HAVE_FCHMODAT
2414 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2415#else
2416 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2417#endif
2418
2419#ifdef HAVE_FCHOWNAT
2420 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2421#else
2422 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2423#endif
2424
2425#ifdef HAVE_FSTATAT
2426 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2427#else
2428 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2429#endif
2430
2431#ifdef HAVE_LINKAT
2432 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2433#else
2434 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2435#endif
2436
2437#ifdef HAVE_MKDIRAT
2438 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2439#else
2440 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2441#endif
2442
2443#ifdef HAVE_MKFIFOAT
2444 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2445#else
2446 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2447#endif
2448
2449#ifdef HAVE_MKNODAT
2450 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2451#else
2452 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2453#endif
2454
2455#ifdef HAVE_OPENAT
2456 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2457#else
2458 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2459#endif
2460
2461#ifdef HAVE_READLINKAT
2462 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2463#else
2464 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2465#endif
2466
2467#ifdef HAVE_SYMLINKAT
2468 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2469#else
2470 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2471#endif
2472
2473#ifdef HAVE_UNLINKAT
2474 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2475#else
2476 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2477#endif
2478
2479#ifdef HAVE_FCHDIR
2480 #define PATH_HAVE_FCHDIR 1
2481#else
2482 #define PATH_HAVE_FCHDIR 0
2483#endif
2484
2485#ifdef HAVE_FCHMOD
2486 #define PATH_HAVE_FCHMOD 1
2487#else
2488 #define PATH_HAVE_FCHMOD 0
2489#endif
2490
2491#ifdef HAVE_FCHOWN
2492 #define PATH_HAVE_FCHOWN 1
2493#else
2494 #define PATH_HAVE_FCHOWN 0
2495#endif
2496
2497#ifdef HAVE_FDOPENDIR
2498 #define PATH_HAVE_FDOPENDIR 1
2499#else
2500 #define PATH_HAVE_FDOPENDIR 0
2501#endif
2502
2503#ifdef HAVE_FEXECVE
2504 #define PATH_HAVE_FEXECVE 1
2505#else
2506 #define PATH_HAVE_FEXECVE 0
2507#endif
2508
2509#ifdef HAVE_FPATHCONF
2510 #define PATH_HAVE_FPATHCONF 1
2511#else
2512 #define PATH_HAVE_FPATHCONF 0
2513#endif
2514
2515#ifdef HAVE_FSTATVFS
2516 #define PATH_HAVE_FSTATVFS 1
2517#else
2518 #define PATH_HAVE_FSTATVFS 0
2519#endif
2520
2521#ifdef HAVE_FTRUNCATE
2522 #define PATH_HAVE_FTRUNCATE 1
2523#else
2524 #define PATH_HAVE_FTRUNCATE 0
2525#endif
2526/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002527
2528
Larry Hastings61272b72014-01-07 12:41:53 -08002529/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002530
2531class path_t_converter(CConverter):
2532
2533 type = "path_t"
2534 impl_by_reference = True
2535 parse_by_reference = True
2536
2537 converter = 'path_converter'
2538
2539 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002540 # right now path_t doesn't support default values.
2541 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002542 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002543 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002544
Larry Hastings2f936352014-08-05 14:04:04 +10002545 if self.c_default not in (None, 'Py_None'):
2546 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002547
2548 self.nullable = nullable
2549 self.allow_fd = allow_fd
2550
Larry Hastings7726ac92014-01-31 22:03:12 -08002551 def pre_render(self):
2552 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002553 if isinstance(value, str):
2554 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002555 return str(int(bool(value)))
2556
2557 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002558 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002559 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002560 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002561 strify(self.nullable),
2562 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002563 )
2564
2565 def cleanup(self):
2566 return "path_cleanup(&" + self.name + ");\n"
2567
2568
2569class dir_fd_converter(CConverter):
2570 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002571
Larry Hastings2f936352014-08-05 14:04:04 +10002572 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002573 if self.default in (unspecified, None):
2574 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002575 if isinstance(requires, str):
2576 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2577 else:
2578 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002579
Larry Hastings2f936352014-08-05 14:04:04 +10002580class fildes_converter(CConverter):
2581 type = 'int'
2582 converter = 'fildes_converter'
2583
2584class uid_t_converter(CConverter):
2585 type = "uid_t"
2586 converter = '_Py_Uid_Converter'
2587
2588class gid_t_converter(CConverter):
2589 type = "gid_t"
2590 converter = '_Py_Gid_Converter'
2591
2592class FSConverter_converter(CConverter):
2593 type = 'PyObject *'
2594 converter = 'PyUnicode_FSConverter'
2595 def converter_init(self):
2596 if self.default is not unspecified:
2597 fail("FSConverter_converter does not support default values")
2598 self.c_default = 'NULL'
2599
2600 def cleanup(self):
2601 return "Py_XDECREF(" + self.name + ");\n"
2602
2603class pid_t_converter(CConverter):
2604 type = 'pid_t'
2605 format_unit = '" _Py_PARSE_PID "'
2606
2607class idtype_t_converter(int_converter):
2608 type = 'idtype_t'
2609
2610class id_t_converter(CConverter):
2611 type = 'id_t'
2612 format_unit = '" _Py_PARSE_PID "'
2613
2614class Py_intptr_t_converter(CConverter):
2615 type = 'Py_intptr_t'
2616 format_unit = '" _Py_PARSE_INTPTR "'
2617
2618class Py_off_t_converter(CConverter):
2619 type = 'Py_off_t'
2620 converter = 'Py_off_t_converter'
2621
2622class Py_off_t_return_converter(long_return_converter):
2623 type = 'Py_off_t'
2624 conversion_fn = 'PyLong_FromPy_off_t'
2625
2626class path_confname_converter(CConverter):
2627 type="int"
2628 converter="conv_path_confname"
2629
2630class confstr_confname_converter(path_confname_converter):
2631 converter='conv_confstr_confname'
2632
2633class sysconf_confname_converter(path_confname_converter):
2634 converter="conv_sysconf_confname"
2635
2636class sched_param_converter(CConverter):
2637 type = 'struct sched_param'
2638 converter = 'convert_sched_param'
2639 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002640
Larry Hastings61272b72014-01-07 12:41:53 -08002641[python start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002642/*[python end generated code: output=da39a3ee5e6b4b0d input=147ba8f52a05aca4]*/
Larry Hastings31826802013-10-19 00:09:25 -07002643
Larry Hastings61272b72014-01-07 12:41:53 -08002644/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002645
Larry Hastings2a727912014-01-16 11:32:01 -08002646os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002647
2648 path : path_t(allow_fd=True)
2649 Path to be examined; can be string, bytes, or open-file-descriptor int.
2650
2651 *
2652
Larry Hastings2f936352014-08-05 14:04:04 +10002653 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002654 If not None, it should be a file descriptor open to a directory,
2655 and path should be a relative string; path will then be relative to
2656 that directory.
2657
2658 follow_symlinks: bool = True
2659 If False, and the last element of the path is a symbolic link,
2660 stat will examine the symbolic link itself instead of the file
2661 the link points to.
2662
2663Perform a stat system call on the given path.
2664
2665dir_fd and follow_symlinks may not be implemented
2666 on your platform. If they are unavailable, using them will raise a
2667 NotImplementedError.
2668
2669It's an error to use dir_fd or follow_symlinks when specifying path as
2670 an open file descriptor.
2671
Larry Hastings61272b72014-01-07 12:41:53 -08002672[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002673
2674PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002675"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2676"--\n"
2677"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002678"Perform a stat system call on the given path.\n"
2679"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002680" path\n"
2681" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2682" dir_fd\n"
2683" If not None, it should be a file descriptor open to a directory,\n"
2684" and path should be a relative string; path will then be relative to\n"
2685" that directory.\n"
2686" follow_symlinks\n"
2687" If False, and the last element of the path is a symbolic link,\n"
2688" stat will examine the symbolic link itself instead of the file\n"
2689" the link points to.\n"
2690"\n"
2691"dir_fd and follow_symlinks may not be implemented\n"
2692" on your platform. If they are unavailable, using them will raise a\n"
2693" NotImplementedError.\n"
2694"\n"
2695"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2696" an open file descriptor.");
2697
2698#define OS_STAT_METHODDEF \
2699 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700
2701static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002702os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002703
2704static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002705os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002706{
Larry Hastings31826802013-10-19 00:09:25 -07002707 PyObject *return_value = NULL;
2708 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
Larry Hastings2f936352014-08-05 14:04:04 +10002709 path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002710 int dir_fd = DEFAULT_DIR_FD;
2711 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712
Larry Hastings31826802013-10-19 00:09:25 -07002713 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2714 "O&|$O&p:stat", _keywords,
Larry Hastings2f936352014-08-05 14:04:04 +10002715 path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
Larry Hastings31826802013-10-19 00:09:25 -07002716 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002717 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002718
2719exit:
2720 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002722
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723 return return_value;
2724}
2725
Larry Hastings31826802013-10-19 00:09:25 -07002726static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002727os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002728/*[clinic end generated code: output=0e9f9508fa0c0607 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002729{
2730 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2731}
2732
Larry Hastings2f936352014-08-05 14:04:04 +10002733
2734/*[clinic input]
2735os.lstat
2736
2737 path : path_t
2738
2739 *
2740
2741 dir_fd : dir_fd(requires='fstatat') = None
2742
2743Perform a stat system call on the given path, without following symbolic links.
2744
2745Like stat(), but do not follow symbolic links.
2746Equivalent to stat(path, follow_symlinks=False).
2747[clinic start generated code]*/
2748
2749PyDoc_STRVAR(os_lstat__doc__,
2750"lstat($module, /, path, *, dir_fd=None)\n"
2751"--\n"
2752"\n"
2753"Perform a stat system call on the given path, without following symbolic links.\n"
2754"\n"
2755"Like stat(), but do not follow symbolic links.\n"
2756"Equivalent to stat(path, follow_symlinks=False).");
2757
2758#define OS_LSTAT_METHODDEF \
2759 {"lstat", (PyCFunction)os_lstat, METH_VARARGS|METH_KEYWORDS, os_lstat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760
2761static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002762os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763
Larry Hastings2f936352014-08-05 14:04:04 +10002764static PyObject *
2765os_lstat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
2766{
2767 PyObject *return_value = NULL;
2768 static char *_keywords[] = {"path", "dir_fd", NULL};
2769 path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0);
2770 int dir_fd = DEFAULT_DIR_FD;
2771
2772 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2773 "O&|$O&:lstat", _keywords,
2774 path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd))
2775 goto exit;
2776 return_value = os_lstat_impl(module, &path, dir_fd);
2777
2778exit:
2779 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +10002781
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782 return return_value;
2783}
2784
Larry Hastings2f936352014-08-05 14:04:04 +10002785static PyObject *
2786os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
2787/*[clinic end generated code: output=85702247224a2b1c input=0b7474765927b925]*/
2788{
2789 int follow_symlinks = 0;
2790 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2791}
Larry Hastings31826802013-10-19 00:09:25 -07002792
Larry Hastings2f936352014-08-05 14:04:04 +10002793
Larry Hastings61272b72014-01-07 12:41:53 -08002794/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002795os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002796
2797 path: path_t(allow_fd=True)
2798 Path to be tested; can be string, bytes, or open-file-descriptor int.
2799
2800 mode: int
2801 Operating-system mode bitfield. Can be F_OK to test existence,
2802 or the inclusive-OR of R_OK, W_OK, and X_OK.
2803
2804 *
2805
Larry Hastings2f936352014-08-05 14:04:04 +10002806 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002807 If not None, it should be a file descriptor open to a directory,
2808 and path should be relative; path will then be relative to that
2809 directory.
2810
2811 effective_ids: bool = False
2812 If True, access will use the effective uid/gid instead of
2813 the real uid/gid.
2814
2815 follow_symlinks: bool = True
2816 If False, and the last element of the path is a symbolic link,
2817 access will examine the symbolic link itself instead of the file
2818 the link points to.
2819
2820Use the real uid/gid to test for access to a path.
2821
2822{parameters}
2823dir_fd, effective_ids, and follow_symlinks may not be implemented
2824 on your platform. If they are unavailable, using them will raise a
2825 NotImplementedError.
2826
2827Note that most operations will use the effective uid/gid, therefore this
2828 routine can be used in a suid/sgid environment to test if the invoking user
2829 has the specified access to the path.
2830
Larry Hastings61272b72014-01-07 12:41:53 -08002831[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002832
2833PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002834"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2835" follow_symlinks=True)\n"
2836"--\n"
2837"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002838"Use the real uid/gid to test for access to a path.\n"
2839"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002840" path\n"
2841" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2842" mode\n"
2843" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2844" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2845" dir_fd\n"
2846" If not None, it should be a file descriptor open to a directory,\n"
2847" and path should be relative; path will then be relative to that\n"
2848" directory.\n"
2849" effective_ids\n"
2850" If True, access will use the effective uid/gid instead of\n"
2851" the real uid/gid.\n"
2852" follow_symlinks\n"
2853" If False, and the last element of the path is a symbolic link,\n"
2854" access will examine the symbolic link itself instead of the file\n"
2855" the link points to.\n"
2856"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002857"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2858" on your platform. If they are unavailable, using them will raise a\n"
2859" NotImplementedError.\n"
2860"\n"
2861"Note that most operations will use the effective uid/gid, therefore this\n"
2862" routine can be used in a suid/sgid environment to test if the invoking user\n"
2863" has the specified access to the path.");
2864
2865#define OS_ACCESS_METHODDEF \
2866 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867
Larry Hastings2f936352014-08-05 14:04:04 +10002868static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002869os_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 -07002870
2871static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002872os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002873{
Larry Hastings31826802013-10-19 00:09:25 -07002874 PyObject *return_value = NULL;
2875 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
Larry Hastings2f936352014-08-05 14:04:04 +10002876 path_t path = PATH_T_INITIALIZE("access", "path", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878 int dir_fd = DEFAULT_DIR_FD;
2879 int effective_ids = 0;
2880 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10002881 int _return_value;
Larry Hastings31826802013-10-19 00:09:25 -07002882
2883 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2884 "O&i|$O&pp:access", _keywords,
Larry Hastings2f936352014-08-05 14:04:04 +10002885 path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
Larry Hastings31826802013-10-19 00:09:25 -07002886 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +10002887 _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
2888 if ((_return_value == -1) && PyErr_Occurred())
2889 goto exit;
2890 return_value = PyBool_FromLong((long)_return_value);
Larry Hastings31826802013-10-19 00:09:25 -07002891
2892exit:
2893 /* Cleanup for path */
2894 path_cleanup(&path);
2895
2896 return return_value;
2897}
2898
Larry Hastings2f936352014-08-05 14:04:04 +10002899static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002900os_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 +10002901/*[clinic end generated code: output=dfd404666906f012 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002902{
Larry Hastings2f936352014-08-05 14:04:04 +10002903 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002904
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002905#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002907#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002909#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911#ifndef HAVE_FACCESSAT
2912 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002913 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002914
2915 if (effective_ids) {
2916 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002917 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918 }
2919#endif
2920
2921#ifdef MS_WINDOWS
2922 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002923 if (path->wide != NULL)
2924 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002925 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002926 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002927 Py_END_ALLOW_THREADS
2928
2929 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002930 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931 * * we didn't get a -1, and
2932 * * write access wasn't requested,
2933 * * or the file isn't read-only,
2934 * * or it's a directory.
2935 * (Directories cannot be read-only on Windows.)
2936 */
Larry Hastings2f936352014-08-05 14:04:04 +10002937 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002938 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002939 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002940 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941#else
2942
2943 Py_BEGIN_ALLOW_THREADS
2944#ifdef HAVE_FACCESSAT
2945 if ((dir_fd != DEFAULT_DIR_FD) ||
2946 effective_ids ||
2947 !follow_symlinks) {
2948 int flags = 0;
2949 if (!follow_symlinks)
2950 flags |= AT_SYMLINK_NOFOLLOW;
2951 if (effective_ids)
2952 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002953 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002954 }
2955 else
2956#endif
Larry Hastings31826802013-10-19 00:09:25 -07002957 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002959 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960#endif
2961
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002963}
2964
Guido van Rossumd371ff11999-01-25 16:12:23 +00002965#ifndef F_OK
2966#define F_OK 0
2967#endif
2968#ifndef R_OK
2969#define R_OK 4
2970#endif
2971#ifndef W_OK
2972#define W_OK 2
2973#endif
2974#ifndef X_OK
2975#define X_OK 1
2976#endif
2977
Larry Hastings31826802013-10-19 00:09:25 -07002978
Guido van Rossumd371ff11999-01-25 16:12:23 +00002979#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002980/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002981os.ttyname -> DecodeFSDefault
2982
2983 fd: int
2984 Integer file descriptor handle.
2985
2986 /
2987
2988Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002989[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002990
2991PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002992"ttyname($module, fd, /)\n"
2993"--\n"
2994"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002995"Return the name of the terminal device connected to \'fd\'.\n"
2996"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002997" fd\n"
2998" Integer file descriptor handle.");
2999
3000#define OS_TTYNAME_METHODDEF \
3001 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
3002
3003static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08003004os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003005
3006static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08003007os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003008{
Larry Hastings31826802013-10-19 00:09:25 -07003009 PyObject *return_value = NULL;
3010 int fd;
3011 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003012
Larry Hastings31826802013-10-19 00:09:25 -07003013 if (!PyArg_ParseTuple(args,
3014 "i:ttyname",
3015 &fd))
3016 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08003017 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07003018 if (_return_value == NULL)
3019 goto exit;
3020 return_value = PyUnicode_DecodeFSDefault(_return_value);
3021
3022exit:
3023 return return_value;
3024}
3025
3026static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08003027os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08003028/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07003029{
3030 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003031
Larry Hastings31826802013-10-19 00:09:25 -07003032 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00003033 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07003034 posix_error();
3035 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003036}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003037#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003038
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003039#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003040/*[clinic input]
3041os.ctermid
3042
3043Return the name of the controlling terminal for this process.
3044[clinic start generated code]*/
3045
3046PyDoc_STRVAR(os_ctermid__doc__,
3047"ctermid($module, /)\n"
3048"--\n"
3049"\n"
3050"Return the name of the controlling terminal for this process.");
3051
3052#define OS_CTERMID_METHODDEF \
3053 {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003054
3055static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003056os_ctermid_impl(PyModuleDef *module);
3057
3058static PyObject *
3059os_ctermid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
3060{
3061 return os_ctermid_impl(module);
3062}
3063
3064static PyObject *
3065os_ctermid_impl(PyModuleDef *module)
3066/*[clinic end generated code: output=277bf7964ec2d782 input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003067{
Victor Stinner8c62be82010-05-06 00:08:46 +00003068 char *ret;
3069 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003070
Greg Wardb48bc172000-03-01 21:51:56 +00003071#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003072 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003073#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003074 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003075#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003076 if (ret == NULL)
3077 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003078 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003079}
Larry Hastings2f936352014-08-05 14:04:04 +10003080#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003081
Larry Hastings2f936352014-08-05 14:04:04 +10003082
3083/*[clinic input]
3084os.chdir
3085
3086 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3087
3088Change the current working directory to the specified path.
3089
3090path may always be specified as a string.
3091On some platforms, path may also be specified as an open file descriptor.
3092 If this functionality is unavailable, using it raises an exception.
3093[clinic start generated code]*/
3094
3095PyDoc_STRVAR(os_chdir__doc__,
3096"chdir($module, /, path)\n"
3097"--\n"
3098"\n"
3099"Change the current working directory to the specified path.\n"
3100"\n"
3101"path may always be specified as a string.\n"
3102"On some platforms, path may also be specified as an open file descriptor.\n"
3103" If this functionality is unavailable, using it raises an exception.");
3104
3105#define OS_CHDIR_METHODDEF \
3106 {"chdir", (PyCFunction)os_chdir, METH_VARARGS|METH_KEYWORDS, os_chdir__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003107
Barry Warsaw53699e91996-12-10 23:23:01 +00003108static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003109os_chdir_impl(PyModuleDef *module, path_t *path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110
Larry Hastings2f936352014-08-05 14:04:04 +10003111static PyObject *
3112os_chdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
3113{
3114 PyObject *return_value = NULL;
3115 static char *_keywords[] = {"path", NULL};
3116 path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR);
3117
3118 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3119 "O&:chdir", _keywords,
3120 path_converter, &path))
3121 goto exit;
3122 return_value = os_chdir_impl(module, &path);
3123
3124exit:
3125 /* Cleanup for path */
3126 path_cleanup(&path);
3127
3128 return return_value;
3129}
3130
3131static PyObject *
3132os_chdir_impl(PyModuleDef *module, path_t *path)
3133/*[clinic end generated code: output=cc07592dd23ca9e0 input=1a4a15b4d12cb15d]*/
3134{
3135 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136
3137 Py_BEGIN_ALLOW_THREADS
3138#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003139 if (path->wide)
3140 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141 else
Larry Hastings2f936352014-08-05 14:04:04 +10003142 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03003143 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003144#else
3145#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003146 if (path->fd != -1)
3147 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003148 else
3149#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003150 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003151#endif
3152 Py_END_ALLOW_THREADS
3153
3154 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003155 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156 }
3157
Larry Hastings2f936352014-08-05 14:04:04 +10003158 Py_RETURN_NONE;
3159}
3160
3161
3162#ifdef HAVE_FCHDIR
3163/*[clinic input]
3164os.fchdir
3165
3166 fd: fildes
3167
3168Change to the directory of the given file descriptor.
3169
3170fd must be opened on a directory, not a file.
3171Equivalent to os.chdir(fd).
3172
3173[clinic start generated code]*/
3174
3175PyDoc_STRVAR(os_fchdir__doc__,
3176"fchdir($module, /, fd)\n"
3177"--\n"
3178"\n"
3179"Change to the directory of the given file descriptor.\n"
3180"\n"
3181"fd must be opened on a directory, not a file.\n"
3182"Equivalent to os.chdir(fd).");
3183
3184#define OS_FCHDIR_METHODDEF \
3185 {"fchdir", (PyCFunction)os_fchdir, METH_VARARGS|METH_KEYWORDS, os_fchdir__doc__},
3186
3187static PyObject *
3188os_fchdir_impl(PyModuleDef *module, int fd);
3189
3190static PyObject *
3191os_fchdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
3192{
3193 PyObject *return_value = NULL;
3194 static char *_keywords[] = {"fd", NULL};
3195 int fd;
3196
3197 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3198 "O&:fchdir", _keywords,
3199 fildes_converter, &fd))
3200 goto exit;
3201 return_value = os_fchdir_impl(module, fd);
Georg Brandlf7875592012-06-24 13:58:31 +02003202
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003205}
3206
Fred Drake4d1e64b2002-04-15 19:40:07 +00003207static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003208os_fchdir_impl(PyModuleDef *module, int fd)
3209/*[clinic end generated code: output=9f6dbc89b2778834 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003210{
Larry Hastings2f936352014-08-05 14:04:04 +10003211 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003212}
3213#endif /* HAVE_FCHDIR */
3214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003215
Larry Hastings2f936352014-08-05 14:04:04 +10003216/*[clinic input]
3217os.chmod
3218
3219 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
3220 Path to be modified. May always be specified as a str or bytes.
3221 On some platforms, path may also be specified as an open file descriptor.
3222 If this functionality is unavailable, using it raises an exception.
3223
3224 mode: int
3225 Operating-system mode bitfield.
3226
3227 *
3228
3229 dir_fd : dir_fd(requires='fchmodat') = None
3230 If not None, it should be a file descriptor open to a directory,
3231 and path should be relative; path will then be relative to that
3232 directory.
3233
3234 follow_symlinks: bool = True
3235 If False, and the last element of the path is a symbolic link,
3236 chmod will modify the symbolic link itself instead of the file
3237 the link points to.
3238
3239Change the access permissions of a file.
3240
3241It is an error to use dir_fd or follow_symlinks when specifying path as
3242 an open file descriptor.
3243dir_fd and follow_symlinks may not be implemented on your platform.
3244 If they are unavailable, using them will raise a NotImplementedError.
3245
3246[clinic start generated code]*/
3247
3248PyDoc_STRVAR(os_chmod__doc__,
3249"chmod($module, /, path, mode, *, dir_fd=None, follow_symlinks=True)\n"
3250"--\n"
3251"\n"
3252"Change the access permissions of a file.\n"
3253"\n"
3254" path\n"
3255" Path to be modified. May always be specified as a str or bytes.\n"
3256" On some platforms, path may also be specified as an open file descriptor.\n"
3257" If this functionality is unavailable, using it raises an exception.\n"
3258" mode\n"
3259" Operating-system mode bitfield.\n"
3260" dir_fd\n"
3261" If not None, it should be a file descriptor open to a directory,\n"
3262" and path should be relative; path will then be relative to that\n"
3263" directory.\n"
3264" follow_symlinks\n"
3265" If False, and the last element of the path is a symbolic link,\n"
3266" chmod will modify the symbolic link itself instead of the file\n"
3267" the link points to.\n"
3268"\n"
3269"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
3270" an open file descriptor.\n"
3271"dir_fd and follow_symlinks may not be implemented on your platform.\n"
3272" If they are unavailable, using them will raise a NotImplementedError.");
3273
3274#define OS_CHMOD_METHODDEF \
3275 {"chmod", (PyCFunction)os_chmod, METH_VARARGS|METH_KEYWORDS, os_chmod__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276
Barry Warsaw53699e91996-12-10 23:23:01 +00003277static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003278os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks);
3279
3280static PyObject *
3281os_chmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003282{
Larry Hastings2f936352014-08-05 14:04:04 +10003283 PyObject *return_value = NULL;
3284 static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL};
3285 path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286 int mode;
3287 int dir_fd = DEFAULT_DIR_FD;
3288 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10003289
3290 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3291 "O&i|$O&p:chmod", _keywords,
3292 path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
3293 goto exit;
3294 return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks);
3295
3296exit:
3297 /* Cleanup for path */
3298 path_cleanup(&path);
3299
3300 return return_value;
3301}
3302
3303static PyObject *
3304os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks)
3305/*[clinic end generated code: output=1e9db031aea46422 input=7f1618e5e15cc196]*/
3306{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003307 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003308
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003309#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003312
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313#ifdef HAVE_FCHMODAT
3314 int fchmodat_nofollow_unsupported = 0;
3315#endif
3316
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3318 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003319 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003320#endif
3321
3322#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003324 if (path->wide)
3325 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003326 else
Larry Hastings2f936352014-08-05 14:04:04 +10003327 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01003328 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003329 result = 0;
3330 else {
3331 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 attr &= ~FILE_ATTRIBUTE_READONLY;
3333 else
3334 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10003335 if (path->wide)
3336 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 else
Larry Hastings2f936352014-08-05 14:04:04 +10003338 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003339 }
3340 Py_END_ALLOW_THREADS
3341
3342 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003343 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 }
3345#else /* MS_WINDOWS */
3346 Py_BEGIN_ALLOW_THREADS
3347#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003348 if (path->fd != -1)
3349 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350 else
3351#endif
3352#ifdef HAVE_LCHMOD
3353 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003354 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355 else
3356#endif
3357#ifdef HAVE_FCHMODAT
3358 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3359 /*
3360 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3361 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003362 * and then says it isn't implemented yet.
3363 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 *
3365 * Once it is supported, os.chmod will automatically
3366 * support dir_fd and follow_symlinks=False. (Hopefully.)
3367 * Until then, we need to be careful what exception we raise.
3368 */
Larry Hastings2f936352014-08-05 14:04:04 +10003369 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003370 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3371 /*
3372 * But wait! We can't throw the exception without allowing threads,
3373 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3374 */
3375 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003376 result &&
3377 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3378 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 }
3380 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003381#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003382 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 Py_END_ALLOW_THREADS
3384
3385 if (result) {
3386#ifdef HAVE_FCHMODAT
3387 if (fchmodat_nofollow_unsupported) {
3388 if (dir_fd != DEFAULT_DIR_FD)
3389 dir_fd_and_follow_symlinks_invalid("chmod",
3390 dir_fd, follow_symlinks);
3391 else
3392 follow_symlinks_specified("chmod", follow_symlinks);
3393 }
3394 else
3395#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003396 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003397 }
3398#endif
3399
Larry Hastings2f936352014-08-05 14:04:04 +10003400 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003401}
3402
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403
Christian Heimes4e30a842007-11-30 22:12:06 +00003404#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003405/*[clinic input]
3406os.fchmod
3407
3408 fd: int
3409 mode: int
3410
3411Change the access permissions of the file given by file descriptor fd.
3412
3413Equivalent to os.chmod(fd, mode).
3414[clinic start generated code]*/
3415
3416PyDoc_STRVAR(os_fchmod__doc__,
3417"fchmod($module, /, fd, mode)\n"
3418"--\n"
3419"\n"
3420"Change the access permissions of the file given by file descriptor fd.\n"
3421"\n"
3422"Equivalent to os.chmod(fd, mode).");
3423
3424#define OS_FCHMOD_METHODDEF \
3425 {"fchmod", (PyCFunction)os_fchmod, METH_VARARGS|METH_KEYWORDS, os_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00003426
3427static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003428os_fchmod_impl(PyModuleDef *module, int fd, int mode);
3429
3430static PyObject *
3431os_fchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00003432{
Larry Hastings2f936352014-08-05 14:04:04 +10003433 PyObject *return_value = NULL;
3434 static char *_keywords[] = {"fd", "mode", NULL};
3435 int fd;
3436 int mode;
3437
3438 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3439 "ii:fchmod", _keywords,
3440 &fd, &mode))
3441 goto exit;
3442 return_value = os_fchmod_impl(module, fd, mode);
3443
3444exit:
3445 return return_value;
3446}
3447
3448static PyObject *
3449os_fchmod_impl(PyModuleDef *module, int fd, int mode)
3450/*[clinic end generated code: output=3c19fbfd724a8e0f input=8ab11975ca01ee5b]*/
3451{
3452 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 Py_BEGIN_ALLOW_THREADS
3454 res = fchmod(fd, mode);
3455 Py_END_ALLOW_THREADS
3456 if (res < 0)
3457 return posix_error();
3458 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003459}
3460#endif /* HAVE_FCHMOD */
3461
Larry Hastings2f936352014-08-05 14:04:04 +10003462
Christian Heimes4e30a842007-11-30 22:12:06 +00003463#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003464/*[clinic input]
3465os.lchmod
3466
3467 path: path_t
3468 mode: int
3469
3470Change the access permissions of a file, without following symbolic links.
3471
3472If path is a symlink, this affects the link itself rather than the target.
3473Equivalent to chmod(path, mode, follow_symlinks=False)."
3474[clinic start generated code]*/
3475
3476PyDoc_STRVAR(os_lchmod__doc__,
3477"lchmod($module, /, path, mode)\n"
3478"--\n"
3479"\n"
3480"Change the access permissions of a file, without following symbolic links.\n"
3481"\n"
3482"If path is a symlink, this affects the link itself rather than the target.\n"
3483"Equivalent to chmod(path, mode, follow_symlinks=False).\"");
3484
3485#define OS_LCHMOD_METHODDEF \
3486 {"lchmod", (PyCFunction)os_lchmod, METH_VARARGS|METH_KEYWORDS, os_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00003487
3488static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003489os_lchmod_impl(PyModuleDef *module, path_t *path, int mode);
3490
3491static PyObject *
3492os_lchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00003493{
Larry Hastings2f936352014-08-05 14:04:04 +10003494 PyObject *return_value = NULL;
3495 static char *_keywords[] = {"path", "mode", NULL};
3496 path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0);
3497 int mode;
3498
3499 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3500 "O&i:lchmod", _keywords,
3501 path_converter, &path, &mode))
3502 goto exit;
3503 return_value = os_lchmod_impl(module, &path, mode);
3504
3505exit:
3506 /* Cleanup for path */
3507 path_cleanup(&path);
3508
3509 return return_value;
3510}
3511
3512static PyObject *
3513os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
3514/*[clinic end generated code: output=2849977d65f8c68c input=90c5663c7465d24f]*/
3515{
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003518 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003520 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003521 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003522 return NULL;
3523 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003525}
3526#endif /* HAVE_LCHMOD */
3527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Thomas Wouterscf297e42007-02-23 15:07:44 +00003529#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003530/*[clinic input]
3531os.chflags
3532
3533 path: path_t
3534 flags: unsigned_long(bitwise=True)
3535 follow_symlinks: bool=True
3536
3537Set file flags.
3538
3539If follow_symlinks is False, and the last element of the path is a symbolic
3540 link, chflags will change flags on the symbolic link itself instead of the
3541 file the link points to.
3542follow_symlinks may not be implemented on your platform. If it is
3543unavailable, using it will raise a NotImplementedError.
3544
3545[clinic start generated code]*/
3546
3547PyDoc_STRVAR(os_chflags__doc__,
3548"chflags($module, /, path, flags, follow_symlinks=True)\n"
3549"--\n"
3550"\n"
3551"Set file flags.\n"
3552"\n"
3553"If follow_symlinks is False, and the last element of the path is a symbolic\n"
3554" link, chflags will change flags on the symbolic link itself instead of the\n"
3555" file the link points to.\n"
3556"follow_symlinks may not be implemented on your platform. If it is\n"
3557"unavailable, using it will raise a NotImplementedError.");
3558
3559#define OS_CHFLAGS_METHODDEF \
3560 {"chflags", (PyCFunction)os_chflags, METH_VARARGS|METH_KEYWORDS, os_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00003561
3562static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003563os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks);
3564
3565static PyObject *
3566os_chflags(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003567{
Larry Hastings2f936352014-08-05 14:04:04 +10003568 PyObject *return_value = NULL;
3569 static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL};
3570 path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573
Larry Hastings2f936352014-08-05 14:04:04 +10003574 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3575 "O&k|p:chflags", _keywords,
3576 path_converter, &path, &flags, &follow_symlinks))
3577 goto exit;
3578 return_value = os_chflags_impl(module, &path, flags, follow_symlinks);
3579
3580exit:
3581 /* Cleanup for path */
3582 path_cleanup(&path);
3583
3584 return return_value;
3585}
3586
3587static PyObject *
3588os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks)
3589/*[clinic end generated code: output=2767927bf071e3cf input=0327e29feb876236]*/
3590{
3591 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592
3593#ifndef HAVE_LCHFLAGS
3594 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003595 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596#endif
3597
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599#ifdef HAVE_LCHFLAGS
3600 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003601 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 else
3603#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003604 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606
Larry Hastings2f936352014-08-05 14:04:04 +10003607 if (result)
3608 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609
Larry Hastings2f936352014-08-05 14:04:04 +10003610 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003611}
3612#endif /* HAVE_CHFLAGS */
3613
Larry Hastings2f936352014-08-05 14:04:04 +10003614
Thomas Wouterscf297e42007-02-23 15:07:44 +00003615#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003616/*[clinic input]
3617os.lchflags
3618
3619 path: path_t
3620 flags: unsigned_long(bitwise=True)
3621
3622Set file flags.
3623
3624This function will not follow symbolic links.
3625Equivalent to chflags(path, flags, follow_symlinks=False).
3626[clinic start generated code]*/
3627
3628PyDoc_STRVAR(os_lchflags__doc__,
3629"lchflags($module, /, path, flags)\n"
3630"--\n"
3631"\n"
3632"Set file flags.\n"
3633"\n"
3634"This function will not follow symbolic links.\n"
3635"Equivalent to chflags(path, flags, follow_symlinks=False).");
3636
3637#define OS_LCHFLAGS_METHODDEF \
3638 {"lchflags", (PyCFunction)os_lchflags, METH_VARARGS|METH_KEYWORDS, os_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00003639
3640static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003641os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags);
3642
3643static PyObject *
3644os_lchflags(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003645{
Larry Hastings2f936352014-08-05 14:04:04 +10003646 PyObject *return_value = NULL;
3647 static char *_keywords[] = {"path", "flags", NULL};
3648 path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 unsigned long flags;
Larry Hastings2f936352014-08-05 14:04:04 +10003650
3651 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3652 "O&k:lchflags", _keywords,
3653 path_converter, &path, &flags))
3654 goto exit;
3655 return_value = os_lchflags_impl(module, &path, flags);
3656
3657exit:
3658 /* Cleanup for path */
3659 path_cleanup(&path);
3660
3661 return return_value;
3662}
3663
3664static PyObject *
3665os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
3666/*[clinic end generated code: output=bb93b6b8a5e45aa7 input=f9f82ea8b585ca9d]*/
3667{
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003670 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003672 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003673 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003674 }
Victor Stinner292c8352012-10-30 02:17:38 +01003675 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003676}
3677#endif /* HAVE_LCHFLAGS */
3678
Larry Hastings2f936352014-08-05 14:04:04 +10003679
Martin v. Löwis244edc82001-10-04 22:44:26 +00003680#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003681/*[clinic input]
3682os.chroot
3683 path: path_t
3684
3685Change root directory to path.
3686
3687[clinic start generated code]*/
3688
3689PyDoc_STRVAR(os_chroot__doc__,
3690"chroot($module, /, path)\n"
3691"--\n"
3692"\n"
3693"Change root directory to path.");
3694
3695#define OS_CHROOT_METHODDEF \
3696 {"chroot", (PyCFunction)os_chroot, METH_VARARGS|METH_KEYWORDS, os_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00003697
3698static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003699os_chroot_impl(PyModuleDef *module, path_t *path);
3700
3701static PyObject *
3702os_chroot(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis244edc82001-10-04 22:44:26 +00003703{
Larry Hastings2f936352014-08-05 14:04:04 +10003704 PyObject *return_value = NULL;
3705 static char *_keywords[] = {"path", NULL};
3706 path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0);
3707
3708 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3709 "O&:chroot", _keywords,
3710 path_converter, &path))
3711 goto exit;
3712 return_value = os_chroot_impl(module, &path);
3713
3714exit:
3715 /* Cleanup for path */
3716 path_cleanup(&path);
3717
3718 return return_value;
Martin v. Löwis244edc82001-10-04 22:44:26 +00003719}
Larry Hastings2f936352014-08-05 14:04:04 +10003720
3721static PyObject *
3722os_chroot_impl(PyModuleDef *module, path_t *path)
3723/*[clinic end generated code: output=15b1256cbe4f24a1 input=14822965652c3dc3]*/
3724{
3725 int res;
3726 Py_BEGIN_ALLOW_THREADS
3727 res = chroot(path->narrow);
3728 Py_END_ALLOW_THREADS
3729 if (res < 0)
3730 return path_error(path);
3731 Py_RETURN_NONE;
3732}
3733#endif /* HAVE_CHROOT */
3734
Martin v. Löwis244edc82001-10-04 22:44:26 +00003735
Guido van Rossum21142a01999-01-08 21:05:37 +00003736#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003737/*[clinic input]
3738os.fsync
3739
3740 fd: fildes
3741
3742Force write of fd to disk.
3743[clinic start generated code]*/
3744
3745PyDoc_STRVAR(os_fsync__doc__,
3746"fsync($module, /, fd)\n"
3747"--\n"
3748"\n"
3749"Force write of fd to disk.");
3750
3751#define OS_FSYNC_METHODDEF \
3752 {"fsync", (PyCFunction)os_fsync, METH_VARARGS|METH_KEYWORDS, os_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00003753
3754static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003755os_fsync_impl(PyModuleDef *module, int fd);
3756
3757static PyObject *
3758os_fsync(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum21142a01999-01-08 21:05:37 +00003759{
Larry Hastings2f936352014-08-05 14:04:04 +10003760 PyObject *return_value = NULL;
3761 static char *_keywords[] = {"fd", NULL};
3762 int fd;
3763
3764 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3765 "O&:fsync", _keywords,
3766 fildes_converter, &fd))
3767 goto exit;
3768 return_value = os_fsync_impl(module, fd);
3769
3770exit:
3771 return return_value;
3772}
3773
3774static PyObject *
3775os_fsync_impl(PyModuleDef *module, int fd)
3776/*[clinic end generated code: output=59f32d3a0b360133 input=21c3645c056967f2]*/
3777{
3778 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003779}
3780#endif /* HAVE_FSYNC */
3781
Larry Hastings2f936352014-08-05 14:04:04 +10003782
Ross Lagerwall7807c352011-03-17 20:20:30 +02003783#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003784/*[clinic input]
3785os.sync
3786
3787Force write of everything to disk.
3788[clinic start generated code]*/
3789
3790PyDoc_STRVAR(os_sync__doc__,
3791"sync($module, /)\n"
3792"--\n"
3793"\n"
3794"Force write of everything to disk.");
3795
3796#define OS_SYNC_METHODDEF \
3797 {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02003798
3799static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003800os_sync_impl(PyModuleDef *module);
3801
3802static PyObject *
3803os_sync(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
3804{
3805 return os_sync_impl(module);
3806}
3807
3808static PyObject *
3809os_sync_impl(PyModuleDef *module)
3810/*[clinic end generated code: output=526c495683d0bb38 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003811{
3812 Py_BEGIN_ALLOW_THREADS
3813 sync();
3814 Py_END_ALLOW_THREADS
3815 Py_RETURN_NONE;
3816}
Larry Hastings2f936352014-08-05 14:04:04 +10003817#endif /* HAVE_SYNC */
3818
Ross Lagerwall7807c352011-03-17 20:20:30 +02003819
Guido van Rossum21142a01999-01-08 21:05:37 +00003820#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003821#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003822extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3823#endif
3824
Larry Hastings2f936352014-08-05 14:04:04 +10003825/*[clinic input]
3826os.fdatasync
3827
3828 fd: fildes
3829
3830Force write of fd to disk without forcing update of metadata.
3831[clinic start generated code]*/
3832
3833PyDoc_STRVAR(os_fdatasync__doc__,
3834"fdatasync($module, /, fd)\n"
3835"--\n"
3836"\n"
3837"Force write of fd to disk without forcing update of metadata.");
3838
3839#define OS_FDATASYNC_METHODDEF \
3840 {"fdatasync", (PyCFunction)os_fdatasync, METH_VARARGS|METH_KEYWORDS, os_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00003841
3842static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003843os_fdatasync_impl(PyModuleDef *module, int fd);
3844
3845static PyObject *
3846os_fdatasync(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum21142a01999-01-08 21:05:37 +00003847{
Larry Hastings2f936352014-08-05 14:04:04 +10003848 PyObject *return_value = NULL;
3849 static char *_keywords[] = {"fd", NULL};
3850 int fd;
3851
3852 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3853 "O&:fdatasync", _keywords,
3854 fildes_converter, &fd))
3855 goto exit;
3856 return_value = os_fdatasync_impl(module, fd);
3857
3858exit:
3859 return return_value;
3860}
3861
3862static PyObject *
3863os_fdatasync_impl(PyModuleDef *module, int fd)
3864/*[clinic end generated code: output=2335fdfd37c92180 input=bc74791ee54dd291]*/
3865{
3866 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003867}
3868#endif /* HAVE_FDATASYNC */
3869
3870
Fredrik Lundh10723342000-07-10 16:38:09 +00003871#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003872/*[clinic input]
3873os.chown
3874
3875 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3876 Path to be examined; can be string, bytes, or open-file-descriptor int.
3877
3878 uid: uid_t
3879
3880 gid: gid_t
3881
3882 *
3883
3884 dir_fd : dir_fd(requires='fchownat') = None
3885 If not None, it should be a file descriptor open to a directory,
3886 and path should be relative; path will then be relative to that
3887 directory.
3888
3889 follow_symlinks: bool = True
3890 If False, and the last element of the path is a symbolic link,
3891 stat will examine the symbolic link itself instead of the file
3892 the link points to.
3893
3894Change the owner and group id of path to the numeric uid and gid.\
3895
3896path may always be specified as a string.
3897On some platforms, path may also be specified as an open file descriptor.
3898 If this functionality is unavailable, using it raises an exception.
3899If dir_fd is not None, it should be a file descriptor open to a directory,
3900 and path should be relative; path will then be relative to that directory.
3901If follow_symlinks is False, and the last element of the path is a symbolic
3902 link, chown will modify the symbolic link itself instead of the file the
3903 link points to.
3904It is an error to use dir_fd or follow_symlinks when specifying path as
3905 an open file descriptor.
3906dir_fd and follow_symlinks may not be implemented on your platform.
3907 If they are unavailable, using them will raise a NotImplementedError.
3908
3909[clinic start generated code]*/
3910
3911PyDoc_STRVAR(os_chown__doc__,
3912"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n"
3913"--\n"
3914"\n"
3915"Change the owner and group id of path to the numeric uid and gid.\\\n"
3916"\n"
3917" path\n"
3918" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
3919" dir_fd\n"
3920" If not None, it should be a file descriptor open to a directory,\n"
3921" and path should be relative; path will then be relative to that\n"
3922" directory.\n"
3923" follow_symlinks\n"
3924" If False, and the last element of the path is a symbolic link,\n"
3925" stat will examine the symbolic link itself instead of the file\n"
3926" the link points to.\n"
3927"\n"
3928"path may always be specified as a string.\n"
3929"On some platforms, path may also be specified as an open file descriptor.\n"
3930" If this functionality is unavailable, using it raises an exception.\n"
3931"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
3932" and path should be relative; path will then be relative to that directory.\n"
3933"If follow_symlinks is False, and the last element of the path is a symbolic\n"
3934" link, chown will modify the symbolic link itself instead of the file the\n"
3935" link points to.\n"
3936"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
3937" an open file descriptor.\n"
3938"dir_fd and follow_symlinks may not be implemented on your platform.\n"
3939" If they are unavailable, using them will raise a NotImplementedError.");
3940
3941#define OS_CHOWN_METHODDEF \
3942 {"chown", (PyCFunction)os_chown, METH_VARARGS|METH_KEYWORDS, os_chown__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003943
Barry Warsaw53699e91996-12-10 23:23:01 +00003944static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003945os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks);
3946
3947static PyObject *
3948os_chown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003949{
Larry Hastings2f936352014-08-05 14:04:04 +10003950 PyObject *return_value = NULL;
3951 static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL};
3952 path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003953 uid_t uid;
3954 gid_t gid;
3955 int dir_fd = DEFAULT_DIR_FD;
3956 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003957
Larry Hastings2f936352014-08-05 14:04:04 +10003958 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3959 "O&O&O&|$O&p:chown", _keywords,
3960 path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
3961 goto exit;
3962 return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks);
3963
3964exit:
3965 /* Cleanup for path */
3966 path_cleanup(&path);
3967
3968 return return_value;
3969}
3970
3971static PyObject *
3972os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks)
3973/*[clinic end generated code: output=22f011e3b4f9ff49 input=a61cc35574814d5d]*/
3974{
3975 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976
3977#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3978 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003979 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003981 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3982 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003984
3985#ifdef __APPLE__
3986 /*
3987 * This is for Mac OS X 10.3, which doesn't have lchown.
3988 * (But we still have an lchown symbol because of weak-linking.)
3989 * It doesn't have fchownat either. So there's no possibility
3990 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003991 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992 if ((!follow_symlinks) && (lchown == NULL)) {
3993 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003994 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 }
3996#endif
3997
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10004000 if (path->fd != -1)
4001 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002 else
4003#endif
4004#ifdef HAVE_LCHOWN
4005 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004006 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 else
4008#endif
4009#ifdef HAVE_FCHOWNAT
4010 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004011 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
4013 else
4014#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004015 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004017
Larry Hastings2f936352014-08-05 14:04:04 +10004018 if (result)
4019 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004020
Larry Hastings2f936352014-08-05 14:04:04 +10004021 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004022}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004023#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004024
Larry Hastings2f936352014-08-05 14:04:04 +10004025
Christian Heimes4e30a842007-11-30 22:12:06 +00004026#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10004027/*[clinic input]
4028os.fchown
4029
4030 fd: int
4031 uid: uid_t
4032 gid: gid_t
4033
4034Change the owner and group id of the file specified by file descriptor.
4035
4036Equivalent to os.chown(fd, uid, gid).
4037
4038[clinic start generated code]*/
4039
4040PyDoc_STRVAR(os_fchown__doc__,
4041"fchown($module, /, fd, uid, gid)\n"
4042"--\n"
4043"\n"
4044"Change the owner and group id of the file specified by file descriptor.\n"
4045"\n"
4046"Equivalent to os.chown(fd, uid, gid).");
4047
4048#define OS_FCHOWN_METHODDEF \
4049 {"fchown", (PyCFunction)os_fchown, METH_VARARGS|METH_KEYWORDS, os_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00004050
4051static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004052os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid);
4053
4054static PyObject *
4055os_fchown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Christian Heimes4e30a842007-11-30 22:12:06 +00004056{
Larry Hastings2f936352014-08-05 14:04:04 +10004057 PyObject *return_value = NULL;
4058 static char *_keywords[] = {"fd", "uid", "gid", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00004059 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02004060 uid_t uid;
4061 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10004062
4063 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4064 "iO&O&:fchown", _keywords,
4065 &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid))
4066 goto exit;
4067 return_value = os_fchown_impl(module, fd, uid, gid);
4068
4069exit:
4070 return return_value;
4071}
4072
4073static PyObject *
4074os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
4075/*[clinic end generated code: output=687781cb7d8974d6 input=3af544ba1b13a0d7]*/
4076{
Victor Stinner8c62be82010-05-06 00:08:46 +00004077 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02004079 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 Py_END_ALLOW_THREADS
4081 if (res < 0)
4082 return posix_error();
4083 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00004084}
4085#endif /* HAVE_FCHOWN */
4086
Larry Hastings2f936352014-08-05 14:04:04 +10004087
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00004088#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10004089/*[clinic input]
4090os.lchown
4091
4092 path : path_t
4093 uid: uid_t
4094 gid: gid_t
4095
4096Change the owner and group id of path to the numeric uid and gid.
4097
4098This function will not follow symbolic links.
4099Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
4100[clinic start generated code]*/
4101
4102PyDoc_STRVAR(os_lchown__doc__,
4103"lchown($module, /, path, uid, gid)\n"
4104"--\n"
4105"\n"
4106"Change the owner and group id of path to the numeric uid and gid.\n"
4107"\n"
4108"This function will not follow symbolic links.\n"
4109"Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
4110
4111#define OS_LCHOWN_METHODDEF \
4112 {"lchown", (PyCFunction)os_lchown, METH_VARARGS|METH_KEYWORDS, os_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00004113
4114static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004115os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid);
4116
4117static PyObject *
4118os_lchown(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00004119{
Larry Hastings2f936352014-08-05 14:04:04 +10004120 PyObject *return_value = NULL;
4121 static char *_keywords[] = {"path", "uid", "gid", NULL};
4122 path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02004123 uid_t uid;
4124 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10004125
4126 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4127 "O&O&O&:lchown", _keywords,
4128 path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid))
4129 goto exit;
4130 return_value = os_lchown_impl(module, &path, uid, gid);
4131
4132exit:
4133 /* Cleanup for path */
4134 path_cleanup(&path);
4135
4136 return return_value;
4137}
4138
4139static PyObject *
4140os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
4141/*[clinic end generated code: output=bf25fdb0d25130e2 input=b1c6014d563a7161]*/
4142{
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004144 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004145 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01004147 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10004148 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01004149 }
Larry Hastings2f936352014-08-05 14:04:04 +10004150 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00004151}
4152#endif /* HAVE_LCHOWN */
4153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004154
Barry Warsaw53699e91996-12-10 23:23:01 +00004155static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004156posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004157{
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 char buf[1026];
4159 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004161#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 if (!use_bytes) {
4163 wchar_t wbuf[1026];
4164 wchar_t *wbuf2 = wbuf;
4165 PyObject *resobj;
4166 DWORD len;
4167 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01004168 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 /* If the buffer is large enough, len does not include the
4170 terminating \0. If the buffer is too small, len includes
4171 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01004172 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02004173 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 if (wbuf2)
4175 len = GetCurrentDirectoryW(len, wbuf2);
4176 }
4177 Py_END_ALLOW_THREADS
4178 if (!wbuf2) {
4179 PyErr_NoMemory();
4180 return NULL;
4181 }
4182 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004183 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02004184 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01004185 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00004186 }
4187 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01004188 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02004189 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 return resobj;
4191 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01004192
4193 if (win32_warn_bytes_api())
4194 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004195#endif
4196
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 Py_END_ALLOW_THREADS
4200 if (res == NULL)
4201 return posix_error();
4202 if (use_bytes)
4203 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00004204 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004205}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004206
Larry Hastings2f936352014-08-05 14:04:04 +10004207
4208/*[clinic input]
4209os.getcwd
4210
4211Return a unicode string representing the current working directory.
4212[clinic start generated code]*/
4213
4214PyDoc_STRVAR(os_getcwd__doc__,
4215"getcwd($module, /)\n"
4216"--\n"
4217"\n"
4218"Return a unicode string representing the current working directory.");
4219
4220#define OS_GETCWD_METHODDEF \
4221 {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__},
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004222
4223static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004224os_getcwd_impl(PyModuleDef *module);
4225
4226static PyObject *
4227os_getcwd(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
4228{
4229 return os_getcwd_impl(module);
4230}
4231
4232static PyObject *
4233os_getcwd_impl(PyModuleDef *module)
4234/*[clinic end generated code: output=d70b281db5c78ff7 input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004235{
4236 return posix_getcwd(0);
4237}
4238
Larry Hastings2f936352014-08-05 14:04:04 +10004239
4240/*[clinic input]
4241os.getcwdb
4242
4243Return a bytes string representing the current working directory.
4244[clinic start generated code]*/
4245
4246PyDoc_STRVAR(os_getcwdb__doc__,
4247"getcwdb($module, /)\n"
4248"--\n"
4249"\n"
4250"Return a bytes string representing the current working directory.");
4251
4252#define OS_GETCWDB_METHODDEF \
4253 {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__},
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004254
4255static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004256os_getcwdb_impl(PyModuleDef *module);
4257
4258static PyObject *
4259os_getcwdb(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
4260{
4261 return os_getcwdb_impl(module);
4262}
4263
4264static PyObject *
4265os_getcwdb_impl(PyModuleDef *module)
4266/*[clinic end generated code: output=75da47f2d75f9166 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004267{
4268 return posix_getcwd(1);
4269}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270
Larry Hastings2f936352014-08-05 14:04:04 +10004271
Larry Hastings9cf065c2012-06-22 16:30:09 -07004272#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
4273#define HAVE_LINK 1
4274#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Guido van Rossumb6775db1994-08-01 11:34:53 +00004276#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10004277/*[clinic input]
4278
4279os.link
4280
4281 src : path_t
4282 dst : path_t
4283 *
4284 src_dir_fd : dir_fd = None
4285 dst_dir_fd : dir_fd = None
4286 follow_symlinks: bool = True
4287
4288Create a hard link to a file.
4289
4290If either src_dir_fd or dst_dir_fd is not None, it should be a file
4291 descriptor open to a directory, and the respective path string (src or dst)
4292 should be relative; the path will then be relative to that directory.
4293If follow_symlinks is False, and the last element of src is a symbolic
4294 link, link will create a link to the symbolic link itself instead of the
4295 file the link points to.
4296src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
4297 platform. If they are unavailable, using them will raise a
4298 NotImplementedError.
4299[clinic start generated code]*/
4300
4301PyDoc_STRVAR(os_link__doc__,
4302"link($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None,\n"
4303" follow_symlinks=True)\n"
4304"--\n"
4305"\n"
4306"Create a hard link to a file.\n"
4307"\n"
4308"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
4309" descriptor open to a directory, and the respective path string (src or dst)\n"
4310" should be relative; the path will then be relative to that directory.\n"
4311"If follow_symlinks is False, and the last element of src is a symbolic\n"
4312" link, link will create a link to the symbolic link itself instead of the\n"
4313" file the link points to.\n"
4314"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n"
4315" platform. If they are unavailable, using them will raise a\n"
4316" NotImplementedError.");
4317
4318#define OS_LINK_METHODDEF \
4319 {"link", (PyCFunction)os_link, METH_VARARGS|METH_KEYWORDS, os_link__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Barry Warsaw53699e91996-12-10 23:23:01 +00004321static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004322os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks);
4323
4324static PyObject *
4325os_link(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004326{
Larry Hastings2f936352014-08-05 14:04:04 +10004327 PyObject *return_value = NULL;
4328 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL};
4329 path_t src = PATH_T_INITIALIZE("link", "src", 0, 0);
4330 path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331 int src_dir_fd = DEFAULT_DIR_FD;
4332 int dst_dir_fd = DEFAULT_DIR_FD;
4333 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +10004334
4335 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4336 "O&O&|$O&O&p:link", _keywords,
4337 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks))
4338 goto exit;
4339 return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks);
4340
4341exit:
4342 /* Cleanup for src */
4343 path_cleanup(&src);
4344 /* Cleanup for dst */
4345 path_cleanup(&dst);
4346
4347 return return_value;
4348}
4349
4350static PyObject *
4351os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks)
4352/*[clinic end generated code: output=53477662fe02e183 input=b0095ebbcbaa7e04]*/
4353{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354#ifdef MS_WINDOWS
4355 BOOL result;
4356#else
4357 int result;
4358#endif
4359
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360#ifndef HAVE_LINKAT
4361 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
4362 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004363 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364 }
4365#endif
4366
Larry Hastings2f936352014-08-05 14:04:04 +10004367 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 PyErr_SetString(PyExc_NotImplementedError,
4369 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10004370 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004371 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004372
Brian Curtin1b9df392010-11-24 20:24:31 +00004373#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004375 if (src->wide)
4376 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 else
Larry Hastings2f936352014-08-05 14:04:04 +10004378 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00004380
Larry Hastings2f936352014-08-05 14:04:04 +10004381 if (!result)
4382 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383#else
4384 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07004385#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 if ((src_dir_fd != DEFAULT_DIR_FD) ||
4387 (dst_dir_fd != DEFAULT_DIR_FD) ||
4388 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004389 result = linkat(src_dir_fd, src->narrow,
4390 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
4392 else
4393#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004394 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004395 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00004396
Larry Hastings2f936352014-08-05 14:04:04 +10004397 if (result)
4398 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399#endif
4400
Larry Hastings2f936352014-08-05 14:04:04 +10004401 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00004402}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403#endif
4404
Brian Curtin1b9df392010-11-24 20:24:31 +00004405
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004406#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00004407static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004408_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00004409{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410 PyObject *v;
4411 HANDLE hFindFile = INVALID_HANDLE_VALUE;
4412 BOOL result;
4413 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01004414 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415 char *bufptr = namebuf;
4416 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01004417 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004418 PyObject *po = NULL;
4419 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420
Gregory P. Smith40a21602013-03-20 20:52:50 -07004421 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004424
Gregory P. Smith40a21602013-03-20 20:52:50 -07004425 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004426 po_wchars = L".";
4427 len = 1;
4428 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004429 po_wchars = path->wide;
4430 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004431 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02004433 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 if (!wnamebuf) {
4435 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004436 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004437 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00004438 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004440 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01004441 if (wch != SEP && wch != ALTSEP && wch != L':')
4442 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 wcscpy(wnamebuf + len, L"*.*");
4444 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445 if ((list = PyList_New(0)) == NULL) {
4446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004448 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004450 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004451 if (hFindFile == INVALID_HANDLE_VALUE) {
4452 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004453 if (error == ERROR_FILE_NOT_FOUND)
4454 goto exit;
4455 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004456 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004458 }
4459 do {
4460 /* Skip over . and .. */
4461 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4462 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463 v = PyUnicode_FromWideChar(wFileData.cFileName,
4464 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00004465 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466 Py_DECREF(list);
4467 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004468 break;
4469 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004470 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472 Py_DECREF(list);
4473 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004474 break;
4475 }
4476 Py_DECREF(v);
4477 }
4478 Py_BEGIN_ALLOW_THREADS
4479 result = FindNextFileW(hFindFile, &wFileData);
4480 Py_END_ALLOW_THREADS
4481 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4482 it got to the end of the directory. */
4483 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004485 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 }
4488 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00004489
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004491 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07004492 strcpy(namebuf, path->narrow);
4493 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 if (len > 0) {
4495 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01004496 if (ch != '\\' && ch != '/' && ch != ':')
4497 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 strcpy(namebuf + len, "*.*");
4499 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00004500
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00004502 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004503
Antoine Pitroub73caab2010-08-09 23:39:31 +00004504 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004505 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004506 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 if (hFindFile == INVALID_HANDLE_VALUE) {
4508 int error = GetLastError();
4509 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 goto exit;
4511 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004512 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 }
4515 do {
4516 /* Skip over . and .. */
4517 if (strcmp(FileData.cFileName, ".") != 0 &&
4518 strcmp(FileData.cFileName, "..") != 0) {
4519 v = PyBytes_FromString(FileData.cFileName);
4520 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521 Py_DECREF(list);
4522 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 break;
4524 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004526 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 Py_DECREF(list);
4528 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004529 break;
4530 }
4531 Py_DECREF(v);
4532 }
4533 Py_BEGIN_ALLOW_THREADS
4534 result = FindNextFile(hFindFile, &FileData);
4535 Py_END_ALLOW_THREADS
4536 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4537 it got to the end of the directory. */
4538 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004540 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004542 }
4543 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004544
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545exit:
4546 if (hFindFile != INVALID_HANDLE_VALUE) {
4547 if (FindClose(hFindFile) == FALSE) {
4548 if (list != NULL) {
4549 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004550 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551 }
4552 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004553 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004554 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004555
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004557} /* end of _listdir_windows_no_opendir */
4558
4559#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4560
4561static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004562_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004563{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004564 PyObject *v;
4565 DIR *dirp = NULL;
4566 struct dirent *ep;
4567 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004568#ifdef HAVE_FDOPENDIR
4569 int fd = -1;
4570#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004571
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004573#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004574 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004576 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004577 if (fd == -1)
4578 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579
Larry Hastingsfdaea062012-06-25 04:42:23 -07004580 return_str = 1;
4581
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582 Py_BEGIN_ALLOW_THREADS
4583 dirp = fdopendir(fd);
4584 Py_END_ALLOW_THREADS
4585 }
4586 else
4587#endif
4588 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07004589 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004590 if (path->narrow) {
4591 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004592 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07004593 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07004594 }
4595 else {
4596 name = ".";
4597 return_str = 1;
4598 }
4599
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600 Py_BEGIN_ALLOW_THREADS
4601 dirp = opendir(name);
4602 Py_END_ALLOW_THREADS
4603 }
4604
4605 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004606 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004607#ifdef HAVE_FDOPENDIR
4608 if (fd != -1) {
4609 Py_BEGIN_ALLOW_THREADS
4610 close(fd);
4611 Py_END_ALLOW_THREADS
4612 }
4613#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614 goto exit;
4615 }
4616 if ((list = PyList_New(0)) == NULL) {
4617 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004618 }
4619 for (;;) {
4620 errno = 0;
4621 Py_BEGIN_ALLOW_THREADS
4622 ep = readdir(dirp);
4623 Py_END_ALLOW_THREADS
4624 if (ep == NULL) {
4625 if (errno == 0) {
4626 break;
4627 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004629 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004631 }
4632 }
4633 if (ep->d_name[0] == '.' &&
4634 (NAMLEN(ep) == 1 ||
4635 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4636 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004637 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004638 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4639 else
4640 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004643 break;
4644 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004646 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004648 break;
4649 }
4650 Py_DECREF(v);
4651 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653exit:
4654 if (dirp != NULL) {
4655 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004656#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657 if (fd > -1)
4658 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004659#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004660 closedir(dirp);
4661 Py_END_ALLOW_THREADS
4662 }
4663
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004665} /* end of _posix_listdir */
4666#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004667
Larry Hastings2f936352014-08-05 14:04:04 +10004668
4669/*[clinic input]
4670os.listdir
4671
4672 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4673
4674Return a list containing the names of the files in the directory.
4675
4676path can be specified as either str or bytes. If path is bytes,
4677 the filenames returned will also be bytes; in all other circumstances
4678 the filenames returned will be str.
4679If path is None, uses the path='.'.
4680On some platforms, path may also be specified as an open file descriptor;\
4681 the file descriptor must refer to a directory.
4682 If this functionality is unavailable, using it raises NotImplementedError.
4683
4684The list is in arbitrary order. It does not include the special
4685entries '.' and '..' even if they are present in the directory.
4686
4687
4688[clinic start generated code]*/
4689
4690PyDoc_STRVAR(os_listdir__doc__,
4691"listdir($module, /, path=None)\n"
4692"--\n"
4693"\n"
4694"Return a list containing the names of the files in the directory.\n"
4695"\n"
4696"path can be specified as either str or bytes. If path is bytes,\n"
4697" the filenames returned will also be bytes; in all other circumstances\n"
4698" the filenames returned will be str.\n"
4699"If path is None, uses the path=\'.\'.\n"
4700"On some platforms, path may also be specified as an open file descriptor;\\\n"
4701" the file descriptor must refer to a directory.\n"
4702" If this functionality is unavailable, using it raises NotImplementedError.\n"
4703"\n"
4704"The list is in arbitrary order. It does not include the special\n"
4705"entries \'.\' and \'..\' even if they are present in the directory.");
4706
4707#define OS_LISTDIR_METHODDEF \
4708 {"listdir", (PyCFunction)os_listdir, METH_VARARGS|METH_KEYWORDS, os_listdir__doc__},
4709
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004710static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004711os_listdir_impl(PyModuleDef *module, path_t *path);
4712
4713static PyObject *
4714os_listdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004715{
Larry Hastings2f936352014-08-05 14:04:04 +10004716 PyObject *return_value = NULL;
4717 static char *_keywords[] = {"path", NULL};
4718 path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004719
Larry Hastings2f936352014-08-05 14:04:04 +10004720 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4721 "|O&:listdir", _keywords,
4722 path_converter, &path))
4723 goto exit;
4724 return_value = os_listdir_impl(module, &path);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004725
Larry Hastings2f936352014-08-05 14:04:04 +10004726exit:
4727 /* Cleanup for path */
Gregory P. Smith40a21602013-03-20 20:52:50 -07004728 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +10004729
Gregory P. Smith40a21602013-03-20 20:52:50 -07004730 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004731}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004732
Larry Hastings2f936352014-08-05 14:04:04 +10004733static PyObject *
4734os_listdir_impl(PyModuleDef *module, path_t *path)
4735/*[clinic end generated code: output=e159bd9be6909018 input=09e300416e3cd729]*/
4736{
4737#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4738 return _listdir_windows_no_opendir(path, NULL);
4739#else
4740 return _posix_listdir(path, NULL);
4741#endif
4742}
4743
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004744#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004745/* A helper function for abspath on win32 */
Larry Hastings2f936352014-08-05 14:04:04 +10004746/* AC 3.5: probably just convert to using path converter */
Mark Hammondef8b6542001-05-13 08:04:26 +00004747static PyObject *
4748posix__getfullpathname(PyObject *self, PyObject *args)
4749{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004750 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01004751 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00004752 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004753 PyObject *po;
4754
4755 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
4756 {
4757 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01004758 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004759 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00004760 DWORD result;
4761 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004762
4763 wpath = PyUnicode_AsUnicode(po);
4764 if (wpath == NULL)
4765 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02004767 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00004768 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02004769 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02004770 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00004771 if (!woutbufp)
4772 return PyErr_NoMemory();
4773 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
4774 }
4775 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004776 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00004777 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02004778 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02004780 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 return v;
4782 }
4783 /* Drop the argument parsing error as narrow strings
4784 are also valid. */
4785 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02004786
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004787 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
4788 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004790 if (win32_warn_bytes_api())
4791 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02004792 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 outbuf, &temp)) {
4794 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 return NULL;
4796 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
4798 return PyUnicode_Decode(outbuf, strlen(outbuf),
4799 Py_FileSystemDefaultEncoding, NULL);
4800 }
4801 return PyBytes_FromString(outbuf);
Larry Hastings2f936352014-08-05 14:04:04 +10004802}
Brian Curtind40e6f72010-07-08 21:39:08 +00004803
Brian Curtind25aef52011-06-13 15:16:04 -05004804
Larry Hastings2f936352014-08-05 14:04:04 +10004805/*[clinic input]
4806os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004807
Larry Hastings2f936352014-08-05 14:04:04 +10004808 path: unicode
4809 /
4810
4811A helper function for samepath on windows.
4812[clinic start generated code]*/
4813
4814PyDoc_STRVAR(os__getfinalpathname__doc__,
4815"_getfinalpathname($module, path, /)\n"
4816"--\n"
4817"\n"
4818"A helper function for samepath on windows.");
4819
4820#define OS__GETFINALPATHNAME_METHODDEF \
4821 {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_VARARGS, os__getfinalpathname__doc__},
4822
Brian Curtind40e6f72010-07-08 21:39:08 +00004823static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004824os__getfinalpathname_impl(PyModuleDef *module, PyObject *path);
4825
4826static PyObject *
4827os__getfinalpathname(PyModuleDef *module, PyObject *args)
4828{
4829 PyObject *return_value = NULL;
4830 PyObject *path;
4831
4832 if (!PyArg_ParseTuple(args,
4833 "U:_getfinalpathname",
4834 &path))
4835 goto exit;
4836 return_value = os__getfinalpathname_impl(module, path);
4837
4838exit:
4839 return return_value;
4840}
4841
4842static PyObject *
4843os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
4844/*[clinic end generated code: output=4563c6eacf1b0881 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004845{
4846 HANDLE hFile;
4847 int buf_size;
4848 wchar_t *target_path;
4849 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004850 PyObject *result;
4851 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004852
Larry Hastings2f936352014-08-05 14:04:04 +10004853 path_wchar = PyUnicode_AsUnicode(path);
4854 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004855 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00004856
4857 if(!check_GetFinalPathNameByHandle()) {
4858 /* If the OS doesn't have GetFinalPathNameByHandle, return a
4859 NotImplementedError. */
4860 return PyErr_Format(PyExc_NotImplementedError,
4861 "GetFinalPathNameByHandle not available on this platform");
4862 }
4863
4864 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10004865 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00004866 0, /* desired access */
4867 0, /* share mode */
4868 NULL, /* security attributes */
4869 OPEN_EXISTING,
4870 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4871 FILE_FLAG_BACKUP_SEMANTICS,
4872 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004873
Victor Stinnereb5657a2011-09-30 01:44:27 +02004874 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10004875 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004876
4877 /* We have a good handle to the target, use it to determine the
4878 target path name. */
4879 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
4880
4881 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10004882 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004883
Victor Stinnerb6404912013-07-07 16:21:41 +02004884 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00004885 if(!target_path)
4886 return PyErr_NoMemory();
4887
4888 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
4889 buf_size, VOLUME_NAME_DOS);
4890 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10004891 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004892
4893 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10004894 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004895
4896 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004897 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004898 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004899 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004900}
Brian Curtin62857742010-09-06 17:07:27 +00004901
Brian Curtin95d028f2011-06-09 09:10:38 -05004902PyDoc_STRVAR(posix__isdir__doc__,
4903"Return true if the pathname refers to an existing directory.");
4904
Larry Hastings2f936352014-08-05 14:04:04 +10004905/* AC 3.5: convert using path converter */
Brian Curtin9c669cc2011-06-08 18:17:18 -05004906static PyObject *
4907posix__isdir(PyObject *self, PyObject *args)
4908{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004909 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004910 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004911 DWORD attributes;
4912
4913 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004914 wchar_t *wpath = PyUnicode_AsUnicode(po);
4915 if (wpath == NULL)
4916 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004917
4918 attributes = GetFileAttributesW(wpath);
4919 if (attributes == INVALID_FILE_ATTRIBUTES)
4920 Py_RETURN_FALSE;
4921 goto check;
4922 }
4923 /* Drop the argument parsing error as narrow strings
4924 are also valid. */
4925 PyErr_Clear();
4926
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004927 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004928 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004929 if (win32_warn_bytes_api())
4930 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004931 attributes = GetFileAttributesA(path);
4932 if (attributes == INVALID_FILE_ATTRIBUTES)
4933 Py_RETURN_FALSE;
4934
4935check:
4936 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4937 Py_RETURN_TRUE;
4938 else
4939 Py_RETURN_FALSE;
4940}
Tim Golden6b528062013-08-01 12:44:00 +01004941
Tim Golden6b528062013-08-01 12:44:00 +01004942
Larry Hastings2f936352014-08-05 14:04:04 +10004943/*[clinic input]
4944os._getvolumepathname
4945
4946 path: unicode
4947
4948A helper function for ismount on Win32.
4949[clinic start generated code]*/
4950
4951PyDoc_STRVAR(os__getvolumepathname__doc__,
4952"_getvolumepathname($module, /, path)\n"
4953"--\n"
4954"\n"
4955"A helper function for ismount on Win32.");
4956
4957#define OS__GETVOLUMEPATHNAME_METHODDEF \
4958 {"_getvolumepathname", (PyCFunction)os__getvolumepathname, METH_VARARGS|METH_KEYWORDS, os__getvolumepathname__doc__},
4959
Tim Golden6b528062013-08-01 12:44:00 +01004960static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004961os__getvolumepathname_impl(PyModuleDef *module, PyObject *path);
4962
4963static PyObject *
4964os__getvolumepathname(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Tim Golden6b528062013-08-01 12:44:00 +01004965{
Larry Hastings2f936352014-08-05 14:04:04 +10004966 PyObject *return_value = NULL;
4967 static char *_keywords[] = {"path", NULL};
4968 PyObject *path;
4969
4970 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4971 "U:_getvolumepathname", _keywords,
4972 &path))
4973 goto exit;
4974 return_value = os__getvolumepathname_impl(module, path);
4975
4976exit:
4977 return return_value;
4978}
4979
4980static PyObject *
4981os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
4982/*[clinic end generated code: output=ac0833b6d6da7657 input=7eacadc40acbda6b]*/
4983{
4984 PyObject *result;
4985 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004986 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004987 BOOL ret;
4988
Larry Hastings2f936352014-08-05 14:04:04 +10004989 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
4990 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01004991 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004992 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004993
4994 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004995 buflen = Py_MAX(buflen, MAX_PATH);
4996
4997 if (buflen > DWORD_MAX) {
4998 PyErr_SetString(PyExc_OverflowError, "path too long");
4999 return NULL;
5000 }
5001
5002 mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
Tim Golden6b528062013-08-01 12:44:00 +01005003 if (mountpath == NULL)
5004 return PyErr_NoMemory();
5005
5006 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005007 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01005008 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01005009 Py_END_ALLOW_THREADS
5010
5011 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10005012 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01005013 goto exit;
5014 }
5015 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
5016
5017exit:
5018 PyMem_Free(mountpath);
5019 return result;
5020}
Tim Golden6b528062013-08-01 12:44:00 +01005021
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005022#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00005023
Larry Hastings2f936352014-08-05 14:04:04 +10005024
5025/*[clinic input]
5026os.mkdir
5027
5028 path : path_t
5029
5030 mode: int = 0o777
5031
5032 *
5033
5034 dir_fd : dir_fd(requires='mkdirat') = None
5035
5036# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
5037
5038Create a directory.
5039
5040If dir_fd is not None, it should be a file descriptor open to a directory,
5041 and path should be relative; path will then be relative to that directory.
5042dir_fd may not be implemented on your platform.
5043 If it is unavailable, using it will raise a NotImplementedError.
5044
5045The mode argument is ignored on Windows.
5046[clinic start generated code]*/
5047
5048PyDoc_STRVAR(os_mkdir__doc__,
5049"mkdir($module, /, path, mode=511, *, dir_fd=None)\n"
5050"--\n"
5051"\n"
5052"Create a directory.\n"
5053"\n"
5054"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5055" and path should be relative; path will then be relative to that directory.\n"
5056"dir_fd may not be implemented on your platform.\n"
5057" If it is unavailable, using it will raise a NotImplementedError.\n"
5058"\n"
5059"The mode argument is ignored on Windows.");
5060
5061#define OS_MKDIR_METHODDEF \
5062 {"mkdir", (PyCFunction)os_mkdir, METH_VARARGS|METH_KEYWORDS, os_mkdir__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005063
Barry Warsaw53699e91996-12-10 23:23:01 +00005064static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005065os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005066
Larry Hastings2f936352014-08-05 14:04:04 +10005067static PyObject *
5068os_mkdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5069{
5070 PyObject *return_value = NULL;
5071 static char *_keywords[] = {"path", "mode", "dir_fd", NULL};
5072 path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0);
5073 int mode = 511;
5074 int dir_fd = DEFAULT_DIR_FD;
5075
5076 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5077 "O&|i$O&:mkdir", _keywords,
5078 path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd))
5079 goto exit;
5080 return_value = os_mkdir_impl(module, &path, mode, dir_fd);
5081
5082exit:
5083 /* Cleanup for path */
5084 path_cleanup(&path);
5085
5086 return return_value;
5087}
5088
5089static PyObject *
5090os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
5091/*[clinic end generated code: output=55c6ef2bc1b207e6 input=e965f68377e9b1ce]*/
5092{
5093 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005094
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005095#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005097 if (path->wide)
5098 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005099 else
Larry Hastings2f936352014-08-05 14:04:04 +10005100 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005102
Larry Hastings2f936352014-08-05 14:04:04 +10005103 if (!result)
5104 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005105#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107#if HAVE_MKDIRAT
5108 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10005109 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005110 else
5111#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00005112#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10005113 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005114#else
Larry Hastings2f936352014-08-05 14:04:04 +10005115 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005116#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005118 if (result < 0)
5119 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005120#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005121 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005122}
5123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005124
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005125/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
5126#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00005127#include <sys/resource.h>
5128#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00005129
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005130
5131#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10005132/*[clinic input]
5133os.nice
5134
5135 increment: int
5136 /
5137
5138Add increment to the priority of process and return the new priority.
5139[clinic start generated code]*/
5140
5141PyDoc_STRVAR(os_nice__doc__,
5142"nice($module, increment, /)\n"
5143"--\n"
5144"\n"
5145"Add increment to the priority of process and return the new priority.");
5146
5147#define OS_NICE_METHODDEF \
5148 {"nice", (PyCFunction)os_nice, METH_VARARGS, os_nice__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005149
Barry Warsaw53699e91996-12-10 23:23:01 +00005150static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005151os_nice_impl(PyModuleDef *module, int increment);
Guido van Rossum775f4da1993-01-09 17:18:52 +00005152
Larry Hastings2f936352014-08-05 14:04:04 +10005153static PyObject *
5154os_nice(PyModuleDef *module, PyObject *args)
5155{
5156 PyObject *return_value = NULL;
5157 int increment;
5158
5159 if (!PyArg_ParseTuple(args,
5160 "i:nice",
5161 &increment))
5162 goto exit;
5163 return_value = os_nice_impl(module, increment);
5164
5165exit:
5166 return return_value;
5167}
5168
5169static PyObject *
5170os_nice_impl(PyModuleDef *module, int increment)
5171/*[clinic end generated code: output=c360dc2a3bd8e3d0 input=864be2d402a21da2]*/
5172{
5173 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00005174
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 /* There are two flavours of 'nice': one that returns the new
5176 priority (as required by almost all standards out there) and the
5177 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
5178 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00005179
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 If we are of the nice family that returns the new priority, we
5181 need to clear errno before the call, and check if errno is filled
5182 before calling posix_error() on a returnvalue of -1, because the
5183 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00005184
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 errno = 0;
5186 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00005187#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 if (value == 0)
5189 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00005190#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 if (value == -1 && errno != 0)
5192 /* either nice() or getpriority() returned an error */
5193 return posix_error();
5194 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00005195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005196#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005197
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005198
5199#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10005200/*[clinic input]
5201os.getpriority
5202
5203 which: int
5204 who: int
5205
5206Return program scheduling priority.
5207[clinic start generated code]*/
5208
5209PyDoc_STRVAR(os_getpriority__doc__,
5210"getpriority($module, /, which, who)\n"
5211"--\n"
5212"\n"
5213"Return program scheduling priority.");
5214
5215#define OS_GETPRIORITY_METHODDEF \
5216 {"getpriority", (PyCFunction)os_getpriority, METH_VARARGS|METH_KEYWORDS, os_getpriority__doc__},
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005217
5218static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005219os_getpriority_impl(PyModuleDef *module, int which, int who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005220
Larry Hastings2f936352014-08-05 14:04:04 +10005221static PyObject *
5222os_getpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5223{
5224 PyObject *return_value = NULL;
5225 static char *_keywords[] = {"which", "who", NULL};
5226 int which;
5227 int who;
5228
5229 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5230 "ii:getpriority", _keywords,
5231 &which, &who))
5232 goto exit;
5233 return_value = os_getpriority_impl(module, which, who);
5234
5235exit:
5236 return return_value;
5237}
5238
5239static PyObject *
5240os_getpriority_impl(PyModuleDef *module, int which, int who)
5241/*[clinic end generated code: output=81639cf765f05dae input=9be615d40e2544ef]*/
5242{
5243 int retval;
5244
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005245 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005246 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005247 if (errno != 0)
5248 return posix_error();
5249 return PyLong_FromLong((long)retval);
5250}
5251#endif /* HAVE_GETPRIORITY */
5252
5253
5254#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10005255/*[clinic input]
5256os.setpriority
5257
5258 which: int
5259 who: int
5260 priority: int
5261
5262Set program scheduling priority.
5263[clinic start generated code]*/
5264
5265PyDoc_STRVAR(os_setpriority__doc__,
5266"setpriority($module, /, which, who, priority)\n"
5267"--\n"
5268"\n"
5269"Set program scheduling priority.");
5270
5271#define OS_SETPRIORITY_METHODDEF \
5272 {"setpriority", (PyCFunction)os_setpriority, METH_VARARGS|METH_KEYWORDS, os_setpriority__doc__},
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005273
5274static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005275os_setpriority_impl(PyModuleDef *module, int which, int who, int priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005276
Larry Hastings2f936352014-08-05 14:04:04 +10005277static PyObject *
5278os_setpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5279{
5280 PyObject *return_value = NULL;
5281 static char *_keywords[] = {"which", "who", "priority", NULL};
5282 int which;
5283 int who;
5284 int priority;
5285
5286 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5287 "iii:setpriority", _keywords,
5288 &which, &who, &priority))
5289 goto exit;
5290 return_value = os_setpriority_impl(module, which, who, priority);
5291
5292exit:
5293 return return_value;
5294}
5295
5296static PyObject *
5297os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
5298/*[clinic end generated code: output=ddad62651fb2120c input=710ccbf65b9dc513]*/
5299{
5300 int retval;
5301
5302 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00005303 if (retval == -1)
5304 return posix_error();
5305 Py_RETURN_NONE;
5306}
5307#endif /* HAVE_SETPRIORITY */
5308
5309
Barry Warsaw53699e91996-12-10 23:23:01 +00005310static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005311internal_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 +00005312{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005313 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005314 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005315
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005316#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005318 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005319#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005320 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005321#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005322
Larry Hastings9cf065c2012-06-22 16:30:09 -07005323 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
5324 (dst_dir_fd != DEFAULT_DIR_FD);
5325#ifndef HAVE_RENAMEAT
5326 if (dir_fd_specified) {
5327 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10005328 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005329 }
5330#endif
5331
Larry Hastings2f936352014-08-05 14:04:04 +10005332 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005333 PyErr_Format(PyExc_ValueError,
5334 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10005335 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005336 }
5337
5338#ifdef MS_WINDOWS
5339 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005340 if (src->wide)
5341 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005342 else
Larry Hastings2f936352014-08-05 14:04:04 +10005343 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005344 Py_END_ALLOW_THREADS
5345
Larry Hastings2f936352014-08-05 14:04:04 +10005346 if (!result)
5347 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005348
5349#else
5350 Py_BEGIN_ALLOW_THREADS
5351#ifdef HAVE_RENAMEAT
5352 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10005353 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005354 else
5355#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005356 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005357 Py_END_ALLOW_THREADS
5358
Larry Hastings2f936352014-08-05 14:04:04 +10005359 if (result)
5360 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005361#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005362 Py_RETURN_NONE;
5363}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005364
Larry Hastings2f936352014-08-05 14:04:04 +10005365
5366/*[clinic input]
5367os.rename
5368
5369 src : path_t
5370 dst : path_t
5371 *
5372 src_dir_fd : dir_fd = None
5373 dst_dir_fd : dir_fd = None
5374
5375Rename a file or directory.
5376
5377If either src_dir_fd or dst_dir_fd is not None, it should be a file
5378 descriptor open to a directory, and the respective path string (src or dst)
5379 should be relative; the path will then be relative to that directory.
5380src_dir_fd and dst_dir_fd, may not be implemented on your platform.
5381 If they are unavailable, using them will raise a NotImplementedError.
5382[clinic start generated code]*/
5383
5384PyDoc_STRVAR(os_rename__doc__,
5385"rename($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n"
5386"--\n"
5387"\n"
5388"Rename a file or directory.\n"
5389"\n"
5390"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
5391" descriptor open to a directory, and the respective path string (src or dst)\n"
5392" should be relative; the path will then be relative to that directory.\n"
5393"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
5394" If they are unavailable, using them will raise a NotImplementedError.");
5395
5396#define OS_RENAME_METHODDEF \
5397 {"rename", (PyCFunction)os_rename, METH_VARARGS|METH_KEYWORDS, os_rename__doc__},
5398
5399static PyObject *
5400os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd);
5401
5402static PyObject *
5403os_rename(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5404{
5405 PyObject *return_value = NULL;
5406 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
5407 path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0);
5408 path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0);
5409 int src_dir_fd = DEFAULT_DIR_FD;
5410 int dst_dir_fd = DEFAULT_DIR_FD;
5411
5412 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5413 "O&O&|$O&O&:rename", _keywords,
5414 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd))
5415 goto exit;
5416 return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd);
5417
Larry Hastings9cf065c2012-06-22 16:30:09 -07005418exit:
Larry Hastings2f936352014-08-05 14:04:04 +10005419 /* Cleanup for src */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005420 path_cleanup(&src);
Larry Hastings2f936352014-08-05 14:04:04 +10005421 /* Cleanup for dst */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005422 path_cleanup(&dst);
Larry Hastings2f936352014-08-05 14:04:04 +10005423
Larry Hastings9cf065c2012-06-22 16:30:09 -07005424 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005425}
5426
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005427static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005428os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
5429/*[clinic end generated code: output=c936bdc81f460a1e input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005430{
Larry Hastings2f936352014-08-05 14:04:04 +10005431 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005432}
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434
5435/*[clinic input]
5436os.replace = os.rename
5437
5438Rename a file or directory, overwriting the destination.
5439
5440If either src_dir_fd or dst_dir_fd is not None, it should be a file
5441 descriptor open to a directory, and the respective path string (src or dst)
5442 should be relative; the path will then be relative to that directory.
5443src_dir_fd and dst_dir_fd, may not be implemented on your platform.
5444 If they are unavailable, using them will raise a NotImplementedError."
5445[clinic start generated code]*/
5446
5447PyDoc_STRVAR(os_replace__doc__,
5448"replace($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n"
5449"--\n"
5450"\n"
5451"Rename a file or directory, overwriting the destination.\n"
5452"\n"
5453"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
5454" descriptor open to a directory, and the respective path string (src or dst)\n"
5455" should be relative; the path will then be relative to that directory.\n"
5456"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
5457" If they are unavailable, using them will raise a NotImplementedError.\"");
5458
5459#define OS_REPLACE_METHODDEF \
5460 {"replace", (PyCFunction)os_replace, METH_VARARGS|METH_KEYWORDS, os_replace__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01005461
5462static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005463os_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 +00005464
Barry Warsaw53699e91996-12-10 23:23:01 +00005465static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005466os_replace(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005467{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005468 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005469 static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
5470 path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0);
5471 path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0);
5472 int src_dir_fd = DEFAULT_DIR_FD;
5473 int dst_dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005474
Larry Hastings2f936352014-08-05 14:04:04 +10005475 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5476 "O&O&|$O&O&:replace", _keywords,
5477 path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd))
5478 goto exit;
5479 return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd);
5480
5481exit:
5482 /* Cleanup for src */
5483 path_cleanup(&src);
5484 /* Cleanup for dst */
5485 path_cleanup(&dst);
5486
5487 return return_value;
5488}
5489
5490static PyObject *
5491os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
5492/*[clinic end generated code: output=224e4710d290d171 input=25515dfb107c8421]*/
5493{
5494 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
5495}
5496
5497
5498/*[clinic input]
5499os.rmdir
5500
5501 path: path_t
5502 *
5503 dir_fd: dir_fd(requires='unlinkat') = None
5504
5505Remove a directory.
5506
5507If dir_fd is not None, it should be a file descriptor open to a directory,
5508 and path should be relative; path will then be relative to that directory.
5509dir_fd may not be implemented on your platform.
5510 If it is unavailable, using it will raise a NotImplementedError.
5511[clinic start generated code]*/
5512
5513PyDoc_STRVAR(os_rmdir__doc__,
5514"rmdir($module, /, path, *, dir_fd=None)\n"
5515"--\n"
5516"\n"
5517"Remove a directory.\n"
5518"\n"
5519"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5520" and path should be relative; path will then be relative to that directory.\n"
5521"dir_fd may not be implemented on your platform.\n"
5522" If it is unavailable, using it will raise a NotImplementedError.");
5523
5524#define OS_RMDIR_METHODDEF \
5525 {"rmdir", (PyCFunction)os_rmdir, METH_VARARGS|METH_KEYWORDS, os_rmdir__doc__},
5526
5527static PyObject *
5528os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd);
5529
5530static PyObject *
5531os_rmdir(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5532{
5533 PyObject *return_value = NULL;
5534 static char *_keywords[] = {"path", "dir_fd", NULL};
5535 path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0);
5536 int dir_fd = DEFAULT_DIR_FD;
5537
5538 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5539 "O&|$O&:rmdir", _keywords,
5540 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5541 goto exit;
5542 return_value = os_rmdir_impl(module, &path, dir_fd);
5543
5544exit:
5545 /* Cleanup for path */
5546 path_cleanup(&path);
5547
5548 return return_value;
5549}
5550
5551static PyObject *
5552os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
5553/*[clinic end generated code: output=70b9fdbe3bee0591 input=38c8b375ca34a7e2]*/
5554{
5555 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005556
5557 Py_BEGIN_ALLOW_THREADS
5558#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10005559 if (path->wide)
5560 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005561 else
Larry Hastings2f936352014-08-05 14:04:04 +10005562 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005563 result = !result; /* Windows, success=1, UNIX, success=0 */
5564#else
5565#ifdef HAVE_UNLINKAT
5566 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10005567 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005568 else
5569#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005570 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005571#endif
5572 Py_END_ALLOW_THREADS
5573
Larry Hastings2f936352014-08-05 14:04:04 +10005574 if (result)
5575 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005576
Larry Hastings2f936352014-08-05 14:04:04 +10005577 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005578}
5579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005580
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005581#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10005582#ifdef MS_WINDOWS
5583/*[clinic input]
5584os.system -> long
5585
5586 command: Py_UNICODE
5587
5588Execute the command in a subshell.
5589[clinic start generated code]*/
5590
5591PyDoc_STRVAR(os_system__doc__,
5592"system($module, /, command)\n"
5593"--\n"
5594"\n"
5595"Execute the command in a subshell.");
5596
5597#define OS_SYSTEM_METHODDEF \
5598 {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__},
5599
5600static long
5601os_system_impl(PyModuleDef *module, Py_UNICODE *command);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005602
Barry Warsaw53699e91996-12-10 23:23:01 +00005603static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005604os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005605{
Larry Hastings2f936352014-08-05 14:04:04 +10005606 PyObject *return_value = NULL;
5607 static char *_keywords[] = {"command", NULL};
5608 Py_UNICODE *command;
5609 long _return_value;
Victor Stinnercfa72782010-04-16 11:45:13 +00005610
Larry Hastings2f936352014-08-05 14:04:04 +10005611 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5612 "u:system", _keywords,
5613 &command))
5614 goto exit;
5615 _return_value = os_system_impl(module, command);
5616 if ((_return_value == -1) && PyErr_Occurred())
5617 goto exit;
5618 return_value = PyLong_FromLong(_return_value);
Victor Stinnercfa72782010-04-16 11:45:13 +00005619
Larry Hastings2f936352014-08-05 14:04:04 +10005620exit:
5621 return return_value;
5622}
5623
5624static long
5625os_system_impl(PyModuleDef *module, Py_UNICODE *command)
5626/*[clinic end generated code: output=29fe699c0b2e9d38 input=303f5ce97df606b0]*/
5627{
5628 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005630 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00005631 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005632 return result;
5633}
5634#else /* MS_WINDOWS */
5635/*[clinic input]
5636os.system -> long
5637
5638 command: FSConverter
5639
5640Execute the command in a subshell.
5641[clinic start generated code]*/
5642
5643PyDoc_STRVAR(os_system__doc__,
5644"system($module, /, command)\n"
5645"--\n"
5646"\n"
5647"Execute the command in a subshell.");
5648
5649#define OS_SYSTEM_METHODDEF \
5650 {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__},
5651
5652static long
5653os_system_impl(PyModuleDef *module, PyObject *command);
5654
5655static PyObject *
5656os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5657{
5658 PyObject *return_value = NULL;
5659 static char *_keywords[] = {"command", NULL};
5660 PyObject *command = NULL;
5661 long _return_value;
5662
5663 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5664 "O&:system", _keywords,
5665 PyUnicode_FSConverter, &command))
5666 goto exit;
5667 _return_value = os_system_impl(module, command);
5668 if ((_return_value == -1) && PyErr_Occurred())
5669 goto exit;
5670 return_value = PyLong_FromLong(_return_value);
5671
5672exit:
5673 /* Cleanup for command */
5674 Py_XDECREF(command);
5675
5676 return return_value;
5677}
5678
5679static long
5680os_system_impl(PyModuleDef *module, PyObject *command)
5681/*[clinic end generated code: output=5be9f3c40ead3bad input=86a58554ba6094af]*/
5682{
5683 long result;
5684 char *bytes = PyBytes_AsString(command);
5685 Py_BEGIN_ALLOW_THREADS
5686 result = system(bytes);
5687 Py_END_ALLOW_THREADS
5688 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005689}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005690#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005691#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005693
Larry Hastings2f936352014-08-05 14:04:04 +10005694/*[clinic input]
5695os.umask
5696
5697 mask: int
5698 /
5699
5700Set the current numeric umask and return the previous umask.
5701[clinic start generated code]*/
5702
5703PyDoc_STRVAR(os_umask__doc__,
5704"umask($module, mask, /)\n"
5705"--\n"
5706"\n"
5707"Set the current numeric umask and return the previous umask.");
5708
5709#define OS_UMASK_METHODDEF \
5710 {"umask", (PyCFunction)os_umask, METH_VARARGS, os_umask__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005711
Barry Warsaw53699e91996-12-10 23:23:01 +00005712static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005713os_umask_impl(PyModuleDef *module, int mask);
5714
5715static PyObject *
5716os_umask(PyModuleDef *module, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005717{
Larry Hastings2f936352014-08-05 14:04:04 +10005718 PyObject *return_value = NULL;
5719 int mask;
5720
5721 if (!PyArg_ParseTuple(args,
5722 "i:umask",
5723 &mask))
5724 goto exit;
5725 return_value = os_umask_impl(module, mask);
5726
5727exit:
5728 return return_value;
5729}
5730
5731static PyObject *
5732os_umask_impl(PyModuleDef *module, int mask)
5733/*[clinic end generated code: output=90048b39d2d4a961 input=ab6bfd9b24d8a7e8]*/
5734{
5735 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 if (i < 0)
5737 return posix_error();
5738 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005739}
5740
Brian Curtind40e6f72010-07-08 21:39:08 +00005741#ifdef MS_WINDOWS
5742
5743/* override the default DeleteFileW behavior so that directory
5744symlinks can be removed with this function, the same as with
5745Unix symlinks */
5746BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
5747{
5748 WIN32_FILE_ATTRIBUTE_DATA info;
5749 WIN32_FIND_DATAW find_data;
5750 HANDLE find_data_handle;
5751 int is_directory = 0;
5752 int is_link = 0;
5753
5754 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
5755 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005756
Brian Curtind40e6f72010-07-08 21:39:08 +00005757 /* Get WIN32_FIND_DATA structure for the path to determine if
5758 it is a symlink */
5759 if(is_directory &&
5760 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
5761 find_data_handle = FindFirstFileW(lpFileName, &find_data);
5762
5763 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01005764 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
5765 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
5766 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
5767 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00005768 FindClose(find_data_handle);
5769 }
5770 }
5771 }
5772
5773 if (is_directory && is_link)
5774 return RemoveDirectoryW(lpFileName);
5775
5776 return DeleteFileW(lpFileName);
5777}
5778#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005780
Larry Hastings2f936352014-08-05 14:04:04 +10005781/*[clinic input]
5782os.unlink
5783
5784 path: path_t
5785 *
5786 dir_fd: dir_fd(requires='unlinkat')=None
5787
5788Remove a file (same as remove()).
5789
5790If dir_fd is not None, it should be a file descriptor open to a directory,
5791 and path should be relative; path will then be relative to that directory.
5792dir_fd may not be implemented on your platform.
5793 If it is unavailable, using it will raise a NotImplementedError.
5794
5795[clinic start generated code]*/
5796
5797PyDoc_STRVAR(os_unlink__doc__,
5798"unlink($module, /, path, *, dir_fd=None)\n"
5799"--\n"
5800"\n"
5801"Remove a file (same as remove()).\n"
5802"\n"
5803"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5804" and path should be relative; path will then be relative to that directory.\n"
5805"dir_fd may not be implemented on your platform.\n"
5806" If it is unavailable, using it will raise a NotImplementedError.");
5807
5808#define OS_UNLINK_METHODDEF \
5809 {"unlink", (PyCFunction)os_unlink, METH_VARARGS|METH_KEYWORDS, os_unlink__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005810
Barry Warsaw53699e91996-12-10 23:23:01 +00005811static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005812os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005813
Larry Hastings2f936352014-08-05 14:04:04 +10005814static PyObject *
5815os_unlink(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5816{
5817 PyObject *return_value = NULL;
5818 static char *_keywords[] = {"path", "dir_fd", NULL};
5819 path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0);
5820 int dir_fd = DEFAULT_DIR_FD;
5821
5822 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5823 "O&|$O&:unlink", _keywords,
5824 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5825 goto exit;
5826 return_value = os_unlink_impl(module, &path, dir_fd);
5827
5828exit:
5829 /* Cleanup for path */
5830 path_cleanup(&path);
5831
5832 return return_value;
5833}
5834
5835static PyObject *
5836os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
5837/*[clinic end generated code: output=59a6e66d67ff2e75 input=d7bcde2b1b2a2552]*/
5838{
5839 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005840
5841 Py_BEGIN_ALLOW_THREADS
5842#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10005843 if (path->wide)
5844 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07005845 else
Larry Hastings2f936352014-08-05 14:04:04 +10005846 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005847 result = !result; /* Windows, success=1, UNIX, success=0 */
5848#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005849#ifdef HAVE_UNLINKAT
5850 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10005851 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005852 else
5853#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10005854 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005855#endif
5856 Py_END_ALLOW_THREADS
5857
Larry Hastings2f936352014-08-05 14:04:04 +10005858 if (result)
5859 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005860
Larry Hastings2f936352014-08-05 14:04:04 +10005861 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005862}
5863
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005864
Larry Hastings2f936352014-08-05 14:04:04 +10005865/*[clinic input]
5866os.remove = os.unlink
5867
5868Remove a file (same as unlink()).
5869
5870If dir_fd is not None, it should be a file descriptor open to a directory,
5871 and path should be relative; path will then be relative to that directory.
5872dir_fd may not be implemented on your platform.
5873 If it is unavailable, using it will raise a NotImplementedError.
5874[clinic start generated code]*/
5875
5876PyDoc_STRVAR(os_remove__doc__,
5877"remove($module, /, path, *, dir_fd=None)\n"
5878"--\n"
5879"\n"
5880"Remove a file (same as unlink()).\n"
5881"\n"
5882"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
5883" and path should be relative; path will then be relative to that directory.\n"
5884"dir_fd may not be implemented on your platform.\n"
5885" If it is unavailable, using it will raise a NotImplementedError.");
5886
5887#define OS_REMOVE_METHODDEF \
5888 {"remove", (PyCFunction)os_remove, METH_VARARGS|METH_KEYWORDS, os_remove__doc__},
5889
5890static PyObject *
5891os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd);
5892
5893static PyObject *
5894os_remove(PyModuleDef *module, PyObject *args, PyObject *kwargs)
5895{
5896 PyObject *return_value = NULL;
5897 static char *_keywords[] = {"path", "dir_fd", NULL};
5898 path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0);
5899 int dir_fd = DEFAULT_DIR_FD;
5900
5901 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
5902 "O&|$O&:remove", _keywords,
5903 path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd))
5904 goto exit;
5905 return_value = os_remove_impl(module, &path, dir_fd);
5906
5907exit:
5908 /* Cleanup for path */
5909 path_cleanup(&path);
5910
5911 return return_value;
5912}
5913
5914static PyObject *
5915os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
5916/*[clinic end generated code: output=cb170cf1e195b8ed input=e05c5ab55cd30983]*/
5917{
5918 return os_unlink_impl(module, path, dir_fd);
5919}
5920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005921
Larry Hastings605a62d2012-06-24 04:33:36 -07005922static PyStructSequence_Field uname_result_fields[] = {
5923 {"sysname", "operating system name"},
5924 {"nodename", "name of machine on network (implementation-defined)"},
5925 {"release", "operating system release"},
5926 {"version", "operating system version"},
5927 {"machine", "hardware identifier"},
5928 {NULL}
5929};
5930
5931PyDoc_STRVAR(uname_result__doc__,
5932"uname_result: Result from os.uname().\n\n\
5933This object may be accessed either as a tuple of\n\
5934 (sysname, nodename, release, version, machine),\n\
5935or via the attributes sysname, nodename, release, version, and machine.\n\
5936\n\
5937See os.uname for more information.");
5938
5939static PyStructSequence_Desc uname_result_desc = {
5940 "uname_result", /* name */
5941 uname_result__doc__, /* doc */
5942 uname_result_fields,
5943 5
5944};
5945
5946static PyTypeObject UnameResultType;
5947
5948
5949#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10005950/*[clinic input]
5951os.uname
5952
5953Return an object identifying the current operating system.
5954
5955The object behaves like a named tuple with the following fields:
5956 (sysname, nodename, release, version, machine)
5957
5958[clinic start generated code]*/
5959
5960PyDoc_STRVAR(os_uname__doc__,
5961"uname($module, /)\n"
5962"--\n"
5963"\n"
5964"Return an object identifying the current operating system.\n"
5965"\n"
5966"The object behaves like a named tuple with the following fields:\n"
5967" (sysname, nodename, release, version, machine)");
5968
5969#define OS_UNAME_METHODDEF \
5970 {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__},
5971
Barry Warsaw53699e91996-12-10 23:23:01 +00005972static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10005973os_uname_impl(PyModuleDef *module);
5974
5975static PyObject *
5976os_uname(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
5977{
5978 return os_uname_impl(module);
5979}
5980
5981static PyObject *
5982os_uname_impl(PyModuleDef *module)
5983/*[clinic end generated code: output=459a86521ff5041c input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005984{
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 struct utsname u;
5986 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07005987 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00005988
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 Py_BEGIN_ALLOW_THREADS
5990 res = uname(&u);
5991 Py_END_ALLOW_THREADS
5992 if (res < 0)
5993 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005994
5995 value = PyStructSequence_New(&UnameResultType);
5996 if (value == NULL)
5997 return NULL;
5998
5999#define SET(i, field) \
6000 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02006001 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07006002 if (!o) { \
6003 Py_DECREF(value); \
6004 return NULL; \
6005 } \
6006 PyStructSequence_SET_ITEM(value, i, o); \
6007 } \
6008
6009 SET(0, u.sysname);
6010 SET(1, u.nodename);
6011 SET(2, u.release);
6012 SET(3, u.version);
6013 SET(4, u.machine);
6014
6015#undef SET
6016
6017 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00006018}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006019#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00006020
Larry Hastings9e3e70b2011-09-08 19:29:07 -07006021
Larry Hastings9cf065c2012-06-22 16:30:09 -07006022
6023typedef struct {
6024 int now;
6025 time_t atime_s;
6026 long atime_ns;
6027 time_t mtime_s;
6028 long mtime_ns;
6029} utime_t;
6030
6031/*
Victor Stinner484df002014-10-09 13:52:31 +02006032 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07006033 * they also intentionally leak the declaration of a pointer named "time"
6034 */
6035#define UTIME_TO_TIMESPEC \
6036 struct timespec ts[2]; \
6037 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02006038 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006039 time = NULL; \
6040 else { \
Victor Stinner484df002014-10-09 13:52:31 +02006041 ts[0].tv_sec = ut->atime_s; \
6042 ts[0].tv_nsec = ut->atime_ns; \
6043 ts[1].tv_sec = ut->mtime_s; \
6044 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006045 time = ts; \
6046 } \
6047
6048#define UTIME_TO_TIMEVAL \
6049 struct timeval tv[2]; \
6050 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02006051 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006052 time = NULL; \
6053 else { \
Victor Stinner484df002014-10-09 13:52:31 +02006054 tv[0].tv_sec = ut->atime_s; \
6055 tv[0].tv_usec = ut->atime_ns / 1000; \
6056 tv[1].tv_sec = ut->mtime_s; \
6057 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006058 time = tv; \
6059 } \
6060
6061#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02006062 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006063 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02006064 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006065 time = NULL; \
6066 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02006067 u.actime = ut->atime_s; \
6068 u.modtime = ut->mtime_s; \
6069 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006070 }
6071
6072#define UTIME_TO_TIME_T \
6073 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02006074 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02006075 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006076 time = NULL; \
6077 else { \
Victor Stinner484df002014-10-09 13:52:31 +02006078 timet[0] = ut->atime_s; \
6079 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02006080 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07006081 } \
6082
6083
6084#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
6085
6086#if UTIME_HAVE_DIR_FD
6087
6088static int
Victor Stinner484df002014-10-09 13:52:31 +02006089utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006090{
6091#ifdef HAVE_UTIMENSAT
6092 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
6093 UTIME_TO_TIMESPEC;
6094 return utimensat(dir_fd, path, time, flags);
6095#elif defined(HAVE_FUTIMESAT)
6096 UTIME_TO_TIMEVAL;
6097 /*
6098 * follow_symlinks will never be false here;
6099 * we only allow !follow_symlinks and dir_fd together
6100 * if we have utimensat()
6101 */
6102 assert(follow_symlinks);
6103 return futimesat(dir_fd, path, time);
6104#endif
6105}
6106
Larry Hastings2f936352014-08-05 14:04:04 +10006107 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
6108#else
6109 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07006110#endif
6111
6112#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
6113
6114#if UTIME_HAVE_FD
6115
6116static int
Victor Stinner484df002014-10-09 13:52:31 +02006117utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006118{
6119#ifdef HAVE_FUTIMENS
6120 UTIME_TO_TIMESPEC;
6121 return futimens(fd, time);
6122#else
6123 UTIME_TO_TIMEVAL;
6124 return futimes(fd, time);
6125#endif
6126}
6127
Larry Hastings2f936352014-08-05 14:04:04 +10006128 #define PATH_UTIME_HAVE_FD 1
6129#else
6130 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07006131#endif
6132
6133
6134#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
6135 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
6136
6137#if UTIME_HAVE_NOFOLLOW_SYMLINKS
6138
6139static int
Victor Stinner484df002014-10-09 13:52:31 +02006140utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006141{
6142#ifdef HAVE_UTIMENSAT
6143 UTIME_TO_TIMESPEC;
6144 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
6145#else
6146 UTIME_TO_TIMEVAL;
6147 return lutimes(path, time);
6148#endif
6149}
6150
6151#endif
6152
6153#ifndef MS_WINDOWS
6154
6155static int
Victor Stinner484df002014-10-09 13:52:31 +02006156utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006157{
6158#ifdef HAVE_UTIMENSAT
6159 UTIME_TO_TIMESPEC;
6160 return utimensat(DEFAULT_DIR_FD, path, time, 0);
6161#elif defined(HAVE_UTIMES)
6162 UTIME_TO_TIMEVAL;
6163 return utimes(path, time);
6164#elif defined(HAVE_UTIME_H)
6165 UTIME_TO_UTIMBUF;
6166 return utime(path, time);
6167#else
6168 UTIME_TO_TIME_T;
6169 return utime(path, time);
6170#endif
6171}
6172
6173#endif
6174
Larry Hastings76ad59b2012-05-03 00:30:07 -07006175static int
6176split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
6177{
6178 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04006179 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006180 divmod = PyNumber_Divmod(py_long, billion);
6181 if (!divmod)
6182 goto exit;
6183 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
6184 if ((*s == -1) && PyErr_Occurred())
6185 goto exit;
6186 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04006187 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07006188 goto exit;
6189
6190 result = 1;
6191exit:
6192 Py_XDECREF(divmod);
6193 return result;
6194}
6195
Larry Hastings2f936352014-08-05 14:04:04 +10006196
6197/*[clinic input]
6198os.utime
6199
6200 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
6201 times: object = NULL
6202 *
6203 ns: object = NULL
6204 dir_fd: dir_fd(requires='futimensat') = None
6205 follow_symlinks: bool=True
6206
6207# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
6208
6209Set the access and modified time of path.
6210
6211path may always be specified as a string.
6212On some platforms, path may also be specified as an open file descriptor.
6213 If this functionality is unavailable, using it raises an exception.
6214
6215If times is not None, it must be a tuple (atime, mtime);
6216 atime and mtime should be expressed as float seconds since the epoch.
6217If ns is not None, it must be a tuple (atime_ns, mtime_ns);
6218 atime_ns and mtime_ns should be expressed as integer nanoseconds
6219 since the epoch.
6220If both times and ns are None, utime uses the current time.
6221Specifying tuples for both times and ns is an error.
6222
6223If dir_fd is not None, it should be a file descriptor open to a directory,
6224 and path should be relative; path will then be relative to that directory.
6225If follow_symlinks is False, and the last element of the path is a symbolic
6226 link, utime will modify the symbolic link itself instead of the file the
6227 link points to.
6228It is an error to use dir_fd or follow_symlinks when specifying path
6229 as an open file descriptor.
6230dir_fd and follow_symlinks may not be available on your platform.
6231 If they are unavailable, using them will raise a NotImplementedError.
6232
6233[clinic start generated code]*/
6234
6235PyDoc_STRVAR(os_utime__doc__,
6236"utime($module, /, path, times=None, *, ns=None, dir_fd=None,\n"
6237" follow_symlinks=True)\n"
6238"--\n"
6239"\n"
6240"Set the access and modified time of path.\n"
6241"\n"
6242"path may always be specified as a string.\n"
6243"On some platforms, path may also be specified as an open file descriptor.\n"
6244" If this functionality is unavailable, using it raises an exception.\n"
6245"\n"
6246"If times is not None, it must be a tuple (atime, mtime);\n"
6247" atime and mtime should be expressed as float seconds since the epoch.\n"
6248"If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n"
6249" atime_ns and mtime_ns should be expressed as integer nanoseconds\n"
6250" since the epoch.\n"
6251"If both times and ns are None, utime uses the current time.\n"
6252"Specifying tuples for both times and ns is an error.\n"
6253"\n"
6254"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
6255" and path should be relative; path will then be relative to that directory.\n"
6256"If follow_symlinks is False, and the last element of the path is a symbolic\n"
6257" link, utime will modify the symbolic link itself instead of the file the\n"
6258" link points to.\n"
6259"It is an error to use dir_fd or follow_symlinks when specifying path\n"
6260" as an open file descriptor.\n"
6261"dir_fd and follow_symlinks may not be available on your platform.\n"
6262" If they are unavailable, using them will raise a NotImplementedError.");
6263
6264#define OS_UTIME_METHODDEF \
6265 {"utime", (PyCFunction)os_utime, METH_VARARGS|METH_KEYWORDS, os_utime__doc__},
6266
Larry Hastings9cf065c2012-06-22 16:30:09 -07006267static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006268os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks);
6269
6270static PyObject *
6271os_utime(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07006272{
Larry Hastings2f936352014-08-05 14:04:04 +10006273 PyObject *return_value = NULL;
6274 static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL};
6275 path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD);
Larry Hastings76ad59b2012-05-03 00:30:07 -07006276 PyObject *times = NULL;
6277 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006278 int dir_fd = DEFAULT_DIR_FD;
6279 int follow_symlinks = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006280
Larry Hastings2f936352014-08-05 14:04:04 +10006281 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6282 "O&|O$OO&p:utime", _keywords,
6283 path_converter, &path, &times, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
6284 goto exit;
6285 return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks);
Larry Hastings76ad59b2012-05-03 00:30:07 -07006286
Larry Hastings2f936352014-08-05 14:04:04 +10006287exit:
6288 /* Cleanup for path */
6289 path_cleanup(&path);
6290
6291 return return_value;
6292}
6293
6294static PyObject *
6295os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks)
6296/*[clinic end generated code: output=891489c35cc68c5d input=1f18c17d5941aa82]*/
6297{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006298#ifdef MS_WINDOWS
6299 HANDLE hFile;
6300 FILETIME atime, mtime;
6301#else
6302 int result;
6303#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07006304
Larry Hastings9cf065c2012-06-22 16:30:09 -07006305 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006306 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006307
Christian Heimesb3c87242013-08-01 00:08:16 +02006308 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07006309
Larry Hastings9cf065c2012-06-22 16:30:09 -07006310 if (times && (times != Py_None) && ns) {
6311 PyErr_SetString(PyExc_ValueError,
6312 "utime: you may specify either 'times'"
6313 " or 'ns' but not both");
6314 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006315 }
6316
6317 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02006318 time_t a_sec, m_sec;
6319 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006320 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006321 PyErr_SetString(PyExc_TypeError,
6322 "utime: 'times' must be either"
6323 " a tuple of two ints or None");
6324 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006325 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006326 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006327 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01006328 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006329 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01006330 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006331 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006332 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02006333 utime.atime_s = a_sec;
6334 utime.atime_ns = a_nsec;
6335 utime.mtime_s = m_sec;
6336 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006337 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006338 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07006339 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006340 PyErr_SetString(PyExc_TypeError,
6341 "utime: 'ns' must be a tuple of two ints");
6342 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006343 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006344 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006345 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07006346 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006347 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07006348 &utime.mtime_s, &utime.mtime_ns)) {
6349 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006350 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006351 }
6352 else {
6353 /* times and ns are both None/unspecified. use "now". */
6354 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006355 }
6356
Larry Hastings9cf065c2012-06-22 16:30:09 -07006357#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
6358 if (follow_symlinks_specified("utime", follow_symlinks))
6359 goto exit;
6360#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04006361
Larry Hastings2f936352014-08-05 14:04:04 +10006362 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
6363 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
6364 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07006365 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07006366
Larry Hastings9cf065c2012-06-22 16:30:09 -07006367#if !defined(HAVE_UTIMENSAT)
6368 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02006369 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006370 "utime: cannot use dir_fd and follow_symlinks "
6371 "together on this platform");
6372 goto exit;
6373 }
6374#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07006375
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006376#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006377 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10006378 if (path->wide)
6379 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 NULL, OPEN_EXISTING,
6381 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006382 else
Larry Hastings2f936352014-08-05 14:04:04 +10006383 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 NULL, OPEN_EXISTING,
6385 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006386 Py_END_ALLOW_THREADS
6387 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10006388 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006389 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07006390 }
6391
Larry Hastings9cf065c2012-06-22 16:30:09 -07006392 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01006393 GetSystemTimeAsFileTime(&mtime);
6394 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006397 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
6398 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 }
6400 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
6401 /* Avoid putting the file name into the error here,
6402 as that may confuse the user into believing that
6403 something is wrong with the file, when it also
6404 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01006405 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006406 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006408#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07006409 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00006410
Larry Hastings9cf065c2012-06-22 16:30:09 -07006411#if UTIME_HAVE_NOFOLLOW_SYMLINKS
6412 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10006413 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006414 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07006415#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07006416
6417#if UTIME_HAVE_DIR_FD
6418 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10006419 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006420 else
6421#endif
6422
6423#if UTIME_HAVE_FD
Larry Hastings2f936352014-08-05 14:04:04 +10006424 if (path->fd != -1)
6425 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006426 else
6427#endif
6428
Larry Hastings2f936352014-08-05 14:04:04 +10006429 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006430
6431 Py_END_ALLOW_THREADS
6432
6433 if (result < 0) {
6434 /* see previous comment about not putting filename in error here */
6435 return_value = posix_error();
6436 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07006438
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006439#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07006440
6441 Py_INCREF(Py_None);
6442 return_value = Py_None;
6443
6444exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07006445#ifdef MS_WINDOWS
6446 if (hFile != INVALID_HANDLE_VALUE)
6447 CloseHandle(hFile);
6448#endif
6449 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006450}
6451
Guido van Rossum3b066191991-06-04 19:40:25 +00006452/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006453
Larry Hastings2f936352014-08-05 14:04:04 +10006454
6455/*[clinic input]
6456os._exit
6457
6458 status: int
6459
6460Exit to the system with specified status, without normal exit processing.
6461[clinic start generated code]*/
6462
6463PyDoc_STRVAR(os__exit__doc__,
6464"_exit($module, /, status)\n"
6465"--\n"
6466"\n"
6467"Exit to the system with specified status, without normal exit processing.");
6468
6469#define OS__EXIT_METHODDEF \
6470 {"_exit", (PyCFunction)os__exit, METH_VARARGS|METH_KEYWORDS, os__exit__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Barry Warsaw53699e91996-12-10 23:23:01 +00006472static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006473os__exit_impl(PyModuleDef *module, int status);
6474
6475static PyObject *
6476os__exit(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006477{
Larry Hastings2f936352014-08-05 14:04:04 +10006478 PyObject *return_value = NULL;
6479 static char *_keywords[] = {"status", NULL};
6480 int status;
6481
6482 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6483 "i:_exit", _keywords,
6484 &status))
6485 goto exit;
6486 return_value = os__exit_impl(module, status);
6487
6488exit:
6489 return return_value;
6490}
6491
6492static PyObject *
6493os__exit_impl(PyModuleDef *module, int status)
6494/*[clinic end generated code: output=4f9858c4cc2dcb89 input=5e6d57556b0c4a62]*/
6495{
6496 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006498}
6499
Martin v. Löwis114619e2002-10-07 06:44:21 +00006500#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
6501static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00006502free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00006503{
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 Py_ssize_t i;
6505 for (i = 0; i < count; i++)
6506 PyMem_Free(array[i]);
6507 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006508}
Martin v. Löwis011e8422009-05-05 04:43:17 +00006509
Antoine Pitrou69f71142009-05-24 21:25:49 +00006510static
Martin v. Löwis011e8422009-05-05 04:43:17 +00006511int fsconvert_strdup(PyObject *o, char**out)
6512{
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 PyObject *bytes;
6514 Py_ssize_t size;
6515 if (!PyUnicode_FSConverter(o, &bytes))
6516 return 0;
6517 size = PyBytes_GET_SIZE(bytes);
6518 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01006519 if (!*out) {
6520 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01006522 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 memcpy(*out, PyBytes_AsString(bytes), size+1);
6524 Py_DECREF(bytes);
6525 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006526}
Martin v. Löwis114619e2002-10-07 06:44:21 +00006527#endif
6528
Ross Lagerwall7807c352011-03-17 20:20:30 +02006529#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00006530static char**
6531parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
6532{
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 char **envlist;
6534 Py_ssize_t i, pos, envc;
6535 PyObject *keys=NULL, *vals=NULL;
6536 PyObject *key, *val, *key2, *val2;
6537 char *p, *k, *v;
6538 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006539
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 i = PyMapping_Size(env);
6541 if (i < 0)
6542 return NULL;
6543 envlist = PyMem_NEW(char *, i + 1);
6544 if (envlist == NULL) {
6545 PyErr_NoMemory();
6546 return NULL;
6547 }
6548 envc = 0;
6549 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01006550 if (!keys)
6551 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01006553 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 goto error;
6555 if (!PyList_Check(keys) || !PyList_Check(vals)) {
6556 PyErr_Format(PyExc_TypeError,
6557 "env.keys() or env.values() is not a list");
6558 goto error;
6559 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00006560
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 for (pos = 0; pos < i; pos++) {
6562 key = PyList_GetItem(keys, pos);
6563 val = PyList_GetItem(vals, pos);
6564 if (!key || !val)
6565 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 if (PyUnicode_FSConverter(key, &key2) == 0)
6568 goto error;
6569 if (PyUnicode_FSConverter(val, &val2) == 0) {
6570 Py_DECREF(key2);
6571 goto error;
6572 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00006573
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 k = PyBytes_AsString(key2);
6575 v = PyBytes_AsString(val2);
6576 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 p = PyMem_NEW(char, len);
6579 if (p == NULL) {
6580 PyErr_NoMemory();
6581 Py_DECREF(key2);
6582 Py_DECREF(val2);
6583 goto error;
6584 }
6585 PyOS_snprintf(p, len, "%s=%s", k, v);
6586 envlist[envc++] = p;
6587 Py_DECREF(key2);
6588 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 }
6590 Py_DECREF(vals);
6591 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00006592
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 envlist[envc] = 0;
6594 *envc_ptr = envc;
6595 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006596
6597error:
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 Py_XDECREF(keys);
6599 Py_XDECREF(vals);
6600 while (--envc >= 0)
6601 PyMem_DEL(envlist[envc]);
6602 PyMem_DEL(envlist);
6603 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00006604}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006605
Ross Lagerwall7807c352011-03-17 20:20:30 +02006606static char**
6607parse_arglist(PyObject* argv, Py_ssize_t *argc)
6608{
6609 int i;
6610 char **argvlist = PyMem_NEW(char *, *argc+1);
6611 if (argvlist == NULL) {
6612 PyErr_NoMemory();
6613 return NULL;
6614 }
6615 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006616 PyObject* item = PySequence_ITEM(argv, i);
6617 if (item == NULL)
6618 goto fail;
6619 if (!fsconvert_strdup(item, &argvlist[i])) {
6620 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006621 goto fail;
6622 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006623 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006624 }
6625 argvlist[*argc] = NULL;
6626 return argvlist;
6627fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006628 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006629 free_string_array(argvlist, *argc);
6630 return NULL;
6631}
6632#endif
6633
Larry Hastings2f936352014-08-05 14:04:04 +10006634
Ross Lagerwall7807c352011-03-17 20:20:30 +02006635#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.execv
6638
6639 path: FSConverter
6640 Path of executable file.
6641 argv: object
6642 Tuple or list of strings.
6643 /
6644
6645Execute an executable path with arguments, replacing current process.
6646[clinic start generated code]*/
6647
6648PyDoc_STRVAR(os_execv__doc__,
6649"execv($module, path, argv, /)\n"
6650"--\n"
6651"\n"
6652"Execute an executable path with arguments, replacing current process.\n"
6653"\n"
6654" path\n"
6655" Path of executable file.\n"
6656" argv\n"
6657" Tuple or list of strings.");
6658
6659#define OS_EXECV_METHODDEF \
6660 {"execv", (PyCFunction)os_execv, METH_VARARGS, os_execv__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02006661
6662static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006663os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv);
6664
6665static PyObject *
6666os_execv(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +02006667{
Larry Hastings2f936352014-08-05 14:04:04 +10006668 PyObject *return_value = NULL;
6669 PyObject *path = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006670 PyObject *argv;
Larry Hastings2f936352014-08-05 14:04:04 +10006671
6672 if (!PyArg_ParseTuple(args,
6673 "O&O:execv",
6674 PyUnicode_FSConverter, &path, &argv))
6675 goto exit;
6676 return_value = os_execv_impl(module, path, argv);
6677
6678exit:
6679 /* Cleanup for path */
6680 Py_XDECREF(path);
6681
6682 return return_value;
6683}
6684
6685static PyObject *
6686os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
6687/*[clinic end generated code: output=b0f5f2caa6097edc input=96041559925e5229]*/
6688{
6689 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006690 char **argvlist;
6691 Py_ssize_t argc;
6692
6693 /* execv has two arguments: (path, argv), where
6694 argv is a list or tuple of strings. */
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006697 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
6698 PyErr_SetString(PyExc_TypeError,
6699 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02006700 return NULL;
6701 }
6702 argc = PySequence_Size(argv);
6703 if (argc < 1) {
6704 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02006705 return NULL;
6706 }
6707
6708 argvlist = parse_arglist(argv, &argc);
6709 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02006710 return NULL;
6711 }
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006714
6715 /* If we get here it's definitely an error */
6716
6717 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006718 return posix_error();
6719}
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721
6722/*[clinic input]
6723os.execve
6724
6725 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
6726 Path of executable file.
6727 argv: object
6728 Tuple or list of strings.
6729 env: object
6730 Dictionary of strings mapping to strings.
6731
6732Execute an executable path with arguments, replacing current process.
6733[clinic start generated code]*/
6734
6735PyDoc_STRVAR(os_execve__doc__,
6736"execve($module, /, path, argv, env)\n"
6737"--\n"
6738"\n"
6739"Execute an executable path with arguments, replacing current process.\n"
6740"\n"
6741" path\n"
6742" Path of executable file.\n"
6743" argv\n"
6744" Tuple or list of strings.\n"
6745" env\n"
6746" Dictionary of strings mapping to strings.");
6747
6748#define OS_EXECVE_METHODDEF \
6749 {"execve", (PyCFunction)os_execve, METH_VARARGS|METH_KEYWORDS, os_execve__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006750
Barry Warsaw53699e91996-12-10 23:23:01 +00006751static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006752os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env);
6753
6754static PyObject *
6755os_execve(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006756{
Larry Hastings2f936352014-08-05 14:04:04 +10006757 PyObject *return_value = NULL;
6758 static char *_keywords[] = {"path", "argv", "env", NULL};
6759 path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE);
6760 PyObject *argv;
6761 PyObject *env;
6762
6763 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
6764 "O&OO:execve", _keywords,
6765 path_converter, &path, &argv, &env))
6766 goto exit;
6767 return_value = os_execve_impl(module, &path, argv, env);
6768
6769exit:
6770 /* Cleanup for path */
6771 path_cleanup(&path);
6772
6773 return return_value;
6774}
6775
6776static PyObject *
6777os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env)
6778/*[clinic end generated code: output=fb283760f5d15ab7 input=626804fa092606d9]*/
6779{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006780 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006782 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 /* execve has three arguments: (path, argv, env), where
6785 argv is a list or tuple of strings and env is a dictionary
6786 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006787
Ross Lagerwall7807c352011-03-17 20:20:30 +02006788 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006790 "execve: argv must be a tuple or list");
6791 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02006793 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 if (!PyMapping_Check(env)) {
6795 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006796 "execve: environment must be a mapping object");
6797 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006799
Ross Lagerwall7807c352011-03-17 20:20:30 +02006800 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07006802 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00006804
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 envlist = parse_envlist(env, &envc);
6806 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02006807 goto fail;
6808
Larry Hastings9cf065c2012-06-22 16:30:09 -07006809#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10006810 if (path->fd > -1)
6811 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006812 else
6813#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006814 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006815
6816 /* If we get here it's definitely an error */
6817
Larry Hastings2f936352014-08-05 14:04:04 +10006818 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006819
6820 while (--envc >= 0)
6821 PyMem_DEL(envlist[envc]);
6822 PyMem_DEL(envlist);
6823 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07006824 if (argvlist)
6825 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02006826 return NULL;
6827}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006828#endif /* HAVE_EXECV */
6829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006830
Guido van Rossuma1065681999-01-25 23:20:23 +00006831#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10006832/*[clinic input]
6833os.spawnv
6834
6835 mode: int
6836 Mode of process creation.
6837 path: FSConverter
6838 Path of executable file.
6839 argv: object
6840 Tuple or list of strings.
6841 /
6842
6843Execute the program specified by path in a new process.
6844[clinic start generated code]*/
6845
6846PyDoc_STRVAR(os_spawnv__doc__,
6847"spawnv($module, mode, path, argv, /)\n"
6848"--\n"
6849"\n"
6850"Execute the program specified by path in a new process.\n"
6851"\n"
6852" mode\n"
6853" Mode of process creation.\n"
6854" path\n"
6855" Path of executable file.\n"
6856" argv\n"
6857" Tuple or list of strings.");
6858
6859#define OS_SPAWNV_METHODDEF \
6860 {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006861
6862static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006863os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv);
6864
6865static PyObject *
6866os_spawnv(PyModuleDef *module, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00006867{
Larry Hastings2f936352014-08-05 14:04:04 +10006868 PyObject *return_value = NULL;
6869 int mode;
6870 PyObject *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 PyObject *argv;
Larry Hastings2f936352014-08-05 14:04:04 +10006872
6873 if (!PyArg_ParseTuple(args,
6874 "iO&O:spawnv",
6875 &mode, PyUnicode_FSConverter, &path, &argv))
6876 goto exit;
6877 return_value = os_spawnv_impl(module, mode, path, argv);
6878
6879exit:
6880 /* Cleanup for path */
6881 Py_XDECREF(path);
6882
6883 return return_value;
6884}
6885
6886static PyObject *
6887os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
6888/*[clinic end generated code: output=dfee6be062e780e3 input=042c91dfc1e6debc]*/
6889{
6890 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006892 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 Py_ssize_t argc;
6894 Py_intptr_t spawnval;
6895 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006896
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 /* spawnv has three arguments: (mode, path, argv), where
6898 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006899
Larry Hastings2f936352014-08-05 14:04:04 +10006900 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 if (PyList_Check(argv)) {
6902 argc = PyList_Size(argv);
6903 getitem = PyList_GetItem;
6904 }
6905 else if (PyTuple_Check(argv)) {
6906 argc = PyTuple_Size(argv);
6907 getitem = PyTuple_GetItem;
6908 }
6909 else {
6910 PyErr_SetString(PyExc_TypeError,
6911 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 return NULL;
6913 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006914
Victor Stinner8c62be82010-05-06 00:08:46 +00006915 argvlist = PyMem_NEW(char *, argc+1);
6916 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 return PyErr_NoMemory();
6918 }
6919 for (i = 0; i < argc; i++) {
6920 if (!fsconvert_strdup((*getitem)(argv, i),
6921 &argvlist[i])) {
6922 free_string_array(argvlist, i);
6923 PyErr_SetString(
6924 PyExc_TypeError,
6925 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 return NULL;
6927 }
6928 }
6929 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006930
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 if (mode == _OLD_P_OVERLAY)
6932 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00006933
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10006935 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006937
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006939
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 if (spawnval == -1)
6941 return posix_error();
6942 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006943 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006944}
6945
6946
Larry Hastings2f936352014-08-05 14:04:04 +10006947/*[clinic input]
6948os.spawnve
6949
6950 mode: int
6951 Mode of process creation.
6952 path: FSConverter
6953 Path of executable file.
6954 argv: object
6955 Tuple or list of strings.
6956 env: object
6957 Dictionary of strings mapping to strings.
6958 /
6959
6960Execute the program specified by path in a new process.
6961[clinic start generated code]*/
6962
6963PyDoc_STRVAR(os_spawnve__doc__,
6964"spawnve($module, mode, path, argv, env, /)\n"
6965"--\n"
6966"\n"
6967"Execute the program specified by path in a new process.\n"
6968"\n"
6969" mode\n"
6970" Mode of process creation.\n"
6971" path\n"
6972" Path of executable file.\n"
6973" argv\n"
6974" Tuple or list of strings.\n"
6975" env\n"
6976" Dictionary of strings mapping to strings.");
6977
6978#define OS_SPAWNVE_METHODDEF \
6979 {"spawnve", (PyCFunction)os_spawnve, METH_VARARGS, os_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006980
6981static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006982os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env);
6983
6984static PyObject *
6985os_spawnve(PyModuleDef *module, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00006986{
Larry Hastings2f936352014-08-05 14:04:04 +10006987 PyObject *return_value = NULL;
6988 int mode;
6989 PyObject *path = NULL;
6990 PyObject *argv;
6991 PyObject *env;
6992
6993 if (!PyArg_ParseTuple(args,
6994 "iO&OO:spawnve",
6995 &mode, PyUnicode_FSConverter, &path, &argv, &env))
6996 goto exit;
6997 return_value = os_spawnve_impl(module, mode, path, argv, env);
6998
6999exit:
7000 /* Cleanup for path */
7001 Py_XDECREF(path);
7002
7003 return return_value;
7004}
7005
7006static PyObject *
7007os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env)
7008/*[clinic end generated code: output=6f7df38473f63c7c input=02362fd937963f8f]*/
7009{
7010 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 char **argvlist;
7012 char **envlist;
7013 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00007014 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 Py_intptr_t spawnval;
7016 PyObject *(*getitem)(PyObject *, Py_ssize_t);
7017 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00007018
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 /* spawnve has four arguments: (mode, path, argv, env), where
7020 argv is a list or tuple of strings and env is a dictionary
7021 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00007022
Larry Hastings2f936352014-08-05 14:04:04 +10007023 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 if (PyList_Check(argv)) {
7025 argc = PyList_Size(argv);
7026 getitem = PyList_GetItem;
7027 }
7028 else if (PyTuple_Check(argv)) {
7029 argc = PyTuple_Size(argv);
7030 getitem = PyTuple_GetItem;
7031 }
7032 else {
7033 PyErr_SetString(PyExc_TypeError,
7034 "spawnve() arg 2 must be a tuple or list");
7035 goto fail_0;
7036 }
7037 if (!PyMapping_Check(env)) {
7038 PyErr_SetString(PyExc_TypeError,
7039 "spawnve() arg 3 must be a mapping object");
7040 goto fail_0;
7041 }
Guido van Rossuma1065681999-01-25 23:20:23 +00007042
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 argvlist = PyMem_NEW(char *, argc+1);
7044 if (argvlist == NULL) {
7045 PyErr_NoMemory();
7046 goto fail_0;
7047 }
7048 for (i = 0; i < argc; i++) {
7049 if (!fsconvert_strdup((*getitem)(argv, i),
7050 &argvlist[i]))
7051 {
7052 lastarg = i;
7053 goto fail_1;
7054 }
7055 }
7056 lastarg = argc;
7057 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00007058
Victor Stinner8c62be82010-05-06 00:08:46 +00007059 envlist = parse_envlist(env, &envc);
7060 if (envlist == NULL)
7061 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00007062
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 if (mode == _OLD_P_OVERLAY)
7064 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00007065
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007067 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007068 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00007069
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 if (spawnval == -1)
7071 (void) posix_error();
7072 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007073 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00007074
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 while (--envc >= 0)
7076 PyMem_DEL(envlist[envc]);
7077 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00007078 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00007080 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00007082}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007083
Guido van Rossuma1065681999-01-25 23:20:23 +00007084#endif /* HAVE_SPAWNV */
7085
7086
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007087#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10007088/*[clinic input]
7089os.fork1
7090
7091Fork a child process with a single multiplexed (i.e., not bound) thread.
7092
7093Return 0 to child process and PID of child to parent process.
7094[clinic start generated code]*/
7095
7096PyDoc_STRVAR(os_fork1__doc__,
7097"fork1($module, /)\n"
7098"--\n"
7099"\n"
7100"Fork a child process with a single multiplexed (i.e., not bound) thread.\n"
7101"\n"
7102"Return 0 to child process and PID of child to parent process.");
7103
7104#define OS_FORK1_METHODDEF \
7105 {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007106
7107static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007108os_fork1_impl(PyModuleDef *module);
7109
7110static PyObject *
7111os_fork1(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7112{
7113 return os_fork1_impl(module);
7114}
7115
7116static PyObject *
7117os_fork1_impl(PyModuleDef *module)
7118/*[clinic end generated code: output=fa04088d6bc02efa input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007119{
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 pid_t pid;
7121 int result = 0;
7122 _PyImport_AcquireLock();
7123 pid = fork1();
7124 if (pid == 0) {
7125 /* child: this clobbers and resets the import lock. */
7126 PyOS_AfterFork();
7127 } else {
7128 /* parent: release the import lock. */
7129 result = _PyImport_ReleaseLock();
7130 }
7131 if (pid == -1)
7132 return posix_error();
7133 if (result < 0) {
7134 /* Don't clobber the OSError if the fork failed. */
7135 PyErr_SetString(PyExc_RuntimeError,
7136 "not holding the import lock");
7137 return NULL;
7138 }
7139 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007140}
Larry Hastings2f936352014-08-05 14:04:04 +10007141#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007142
7143
Guido van Rossumad0ee831995-03-01 10:34:45 +00007144#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10007145/*[clinic input]
7146os.fork
7147
7148Fork a child process.
7149
7150Return 0 to child process and PID of child to parent process.
7151[clinic start generated code]*/
7152
7153PyDoc_STRVAR(os_fork__doc__,
7154"fork($module, /)\n"
7155"--\n"
7156"\n"
7157"Fork a child process.\n"
7158"\n"
7159"Return 0 to child process and PID of child to parent process.");
7160
7161#define OS_FORK_METHODDEF \
7162 {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007163
Barry Warsaw53699e91996-12-10 23:23:01 +00007164static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007165os_fork_impl(PyModuleDef *module);
7166
7167static PyObject *
7168os_fork(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7169{
7170 return os_fork_impl(module);
7171}
7172
7173static PyObject *
7174os_fork_impl(PyModuleDef *module)
7175/*[clinic end generated code: output=b3c8e6bdc11eedc6 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007176{
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 pid_t pid;
7178 int result = 0;
7179 _PyImport_AcquireLock();
7180 pid = fork();
7181 if (pid == 0) {
7182 /* child: this clobbers and resets the import lock. */
7183 PyOS_AfterFork();
7184 } else {
7185 /* parent: release the import lock. */
7186 result = _PyImport_ReleaseLock();
7187 }
7188 if (pid == -1)
7189 return posix_error();
7190 if (result < 0) {
7191 /* Don't clobber the OSError if the fork failed. */
7192 PyErr_SetString(PyExc_RuntimeError,
7193 "not holding the import lock");
7194 return NULL;
7195 }
7196 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00007197}
Larry Hastings2f936352014-08-05 14:04:04 +10007198#endif /* HAVE_FORK */
7199
Guido van Rossum85e3b011991-06-03 12:42:10 +00007200
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007201#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007202#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10007203/*[clinic input]
7204os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007205
Larry Hastings2f936352014-08-05 14:04:04 +10007206 policy: int
7207
7208Get the maximum scheduling priority for policy.
7209[clinic start generated code]*/
7210
7211PyDoc_STRVAR(os_sched_get_priority_max__doc__,
7212"sched_get_priority_max($module, /, policy)\n"
7213"--\n"
7214"\n"
7215"Get the maximum scheduling priority for policy.");
7216
7217#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \
7218 {"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 -05007219
7220static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007221os_sched_get_priority_max_impl(PyModuleDef *module, int policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007222
Larry Hastings2f936352014-08-05 14:04:04 +10007223static PyObject *
7224os_sched_get_priority_max(PyModuleDef *module, PyObject *args, PyObject *kwargs)
7225{
7226 PyObject *return_value = NULL;
7227 static char *_keywords[] = {"policy", NULL};
7228 int policy;
7229
7230 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7231 "i:sched_get_priority_max", _keywords,
7232 &policy))
7233 goto exit;
7234 return_value = os_sched_get_priority_max_impl(module, policy);
7235
7236exit:
7237 return return_value;
7238}
7239
7240static PyObject *
7241os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
7242/*[clinic end generated code: output=a580a52f25238c1f input=2097b7998eca6874]*/
7243{
7244 int max;
7245
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007246 max = sched_get_priority_max(policy);
7247 if (max < 0)
7248 return posix_error();
7249 return PyLong_FromLong(max);
7250}
7251
Larry Hastings2f936352014-08-05 14:04:04 +10007252
7253/*[clinic input]
7254os.sched_get_priority_min
7255
7256 policy: int
7257
7258Get the minimum scheduling priority for policy.
7259[clinic start generated code]*/
7260
7261PyDoc_STRVAR(os_sched_get_priority_min__doc__,
7262"sched_get_priority_min($module, /, policy)\n"
7263"--\n"
7264"\n"
7265"Get the minimum scheduling priority for policy.");
7266
7267#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \
7268 {"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 -05007269
7270static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007271os_sched_get_priority_min_impl(PyModuleDef *module, int policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007272
Larry Hastings2f936352014-08-05 14:04:04 +10007273static PyObject *
7274os_sched_get_priority_min(PyModuleDef *module, PyObject *args, PyObject *kwargs)
7275{
7276 PyObject *return_value = NULL;
7277 static char *_keywords[] = {"policy", NULL};
7278 int policy;
7279
7280 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7281 "i:sched_get_priority_min", _keywords,
7282 &policy))
7283 goto exit;
7284 return_value = os_sched_get_priority_min_impl(module, policy);
7285
7286exit:
7287 return return_value;
7288}
7289
7290static PyObject *
7291os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
7292/*[clinic end generated code: output=bad8ba10e7d0e977 input=21bc8fa0d70983bf]*/
7293{
7294 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007295 if (min < 0)
7296 return posix_error();
7297 return PyLong_FromLong(min);
7298}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02007299#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
7300
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007301
Larry Hastings2f936352014-08-05 14:04:04 +10007302#ifdef HAVE_SCHED_SETSCHEDULER
7303/*[clinic input]
7304os.sched_getscheduler
7305 pid: pid_t
7306 /
7307
7308Get the scheduling policy for the process identifiedy by pid.
7309
7310Passing 0 for pid returns the scheduling policy for the calling process.
7311[clinic start generated code]*/
7312
7313PyDoc_STRVAR(os_sched_getscheduler__doc__,
7314"sched_getscheduler($module, pid, /)\n"
7315"--\n"
7316"\n"
7317"Get the scheduling policy for the process identifiedy by pid.\n"
7318"\n"
7319"Passing 0 for pid returns the scheduling policy for the calling process.");
7320
7321#define OS_SCHED_GETSCHEDULER_METHODDEF \
7322 {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_VARARGS, os_sched_getscheduler__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007323
7324static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007325os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid);
7326
7327static PyObject *
7328os_sched_getscheduler(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007329{
Larry Hastings2f936352014-08-05 14:04:04 +10007330 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007331 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007332
7333 if (!PyArg_ParseTuple(args,
7334 "" _Py_PARSE_PID ":sched_getscheduler",
7335 &pid))
7336 goto exit;
7337 return_value = os_sched_getscheduler_impl(module, pid);
7338
7339exit:
7340 return return_value;
7341}
7342
7343static PyObject *
7344os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
7345/*[clinic end generated code: output=e0d6244207b1d828 input=5f14cfd1f189e1a0]*/
7346{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007347 int policy;
7348
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007349 policy = sched_getscheduler(pid);
7350 if (policy < 0)
7351 return posix_error();
7352 return PyLong_FromLong(policy);
7353}
Larry Hastings2f936352014-08-05 14:04:04 +10007354#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007355
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007356
7357#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10007358/*[clinic input]
7359class os.sched_param "PyObject *" "&SchedParamType"
7360
7361@classmethod
7362os.sched_param.__new__
7363
7364 sched_priority: object
7365 A scheduling parameter.
7366
7367Current has only one field: sched_priority");
7368[clinic start generated code]*/
7369
7370PyDoc_STRVAR(os_sched_param__doc__,
7371"sched_param(sched_priority)\n"
7372"--\n"
7373"\n"
7374"Current has only one field: sched_priority\");\n"
7375"\n"
7376" sched_priority\n"
7377" A scheduling parameter.");
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007378
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007379static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007380os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007381
Larry Hastings2f936352014-08-05 14:04:04 +10007382static PyObject *
7383os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs)
7384{
7385 PyObject *return_value = NULL;
7386 static char *_keywords[] = {"sched_priority", NULL};
7387 PyObject *sched_priority;
7388
7389 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7390 "O:sched_param", _keywords,
7391 &sched_priority))
7392 goto exit;
7393 return_value = os_sched_param_impl(type, sched_priority);
7394
7395exit:
7396 return return_value;
7397}
7398
7399static PyObject *
7400os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
7401/*[clinic end generated code: output=d3791e345f7fe573 input=73a4c22f7071fc62]*/
7402{
7403 PyObject *res;
7404
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007405 res = PyStructSequence_New(type);
7406 if (!res)
7407 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007408 Py_INCREF(sched_priority);
7409 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007410 return res;
7411}
7412
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007413
7414static PyStructSequence_Field sched_param_fields[] = {
7415 {"sched_priority", "the scheduling priority"},
7416 {0}
7417};
7418
7419static PyStructSequence_Desc sched_param_desc = {
7420 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10007421 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007422 sched_param_fields,
7423 1
7424};
7425
7426static int
7427convert_sched_param(PyObject *param, struct sched_param *res)
7428{
7429 long priority;
7430
7431 if (Py_TYPE(param) != &SchedParamType) {
7432 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
7433 return 0;
7434 }
7435 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
7436 if (priority == -1 && PyErr_Occurred())
7437 return 0;
7438 if (priority > INT_MAX || priority < INT_MIN) {
7439 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
7440 return 0;
7441 }
7442 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
7443 return 1;
7444}
Larry Hastings2f936352014-08-05 14:04:04 +10007445#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007446
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007447
7448#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10007449/*[clinic input]
7450os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007451
Larry Hastings2f936352014-08-05 14:04:04 +10007452 pid: pid_t
7453 policy: int
7454 param: sched_param
7455 /
7456
7457Set the scheduling policy for the process identified by pid.
7458
7459If pid is 0, the calling process is changed.
7460param is an instance of sched_param.
7461[clinic start generated code]*/
7462
7463PyDoc_STRVAR(os_sched_setscheduler__doc__,
7464"sched_setscheduler($module, pid, policy, param, /)\n"
7465"--\n"
7466"\n"
7467"Set the scheduling policy for the process identified by pid.\n"
7468"\n"
7469"If pid is 0, the calling process is changed.\n"
7470"param is an instance of sched_param.");
7471
7472#define OS_SCHED_SETSCHEDULER_METHODDEF \
7473 {"sched_setscheduler", (PyCFunction)os_sched_setscheduler, METH_VARARGS, os_sched_setscheduler__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007474
7475static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007476os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param);
7477
7478static PyObject *
7479os_sched_setscheduler(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007480{
Larry Hastings2f936352014-08-05 14:04:04 +10007481 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007482 pid_t pid;
7483 int policy;
7484 struct sched_param param;
7485
Larry Hastings2f936352014-08-05 14:04:04 +10007486 if (!PyArg_ParseTuple(args,
7487 "" _Py_PARSE_PID "iO&:sched_setscheduler",
7488 &pid, &policy, convert_sched_param, &param))
7489 goto exit;
7490 return_value = os_sched_setscheduler_impl(module, pid, policy, &param);
Jesus Cea9c822272011-09-10 01:40:52 +02007491
Larry Hastings2f936352014-08-05 14:04:04 +10007492exit:
7493 return return_value;
7494}
7495
7496static PyObject *
7497os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param)
7498/*[clinic end generated code: output=36abdb73f81c224f input=c581f9469a5327dd]*/
7499{
Jesus Cea9c822272011-09-10 01:40:52 +02007500 /*
Jesus Cea54b01492011-09-10 01:53:19 +02007501 ** sched_setscheduler() returns 0 in Linux, but the previous
7502 ** scheduling policy under Solaris/Illumos, and others.
7503 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02007504 */
Larry Hastings2f936352014-08-05 14:04:04 +10007505 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007506 return posix_error();
7507 Py_RETURN_NONE;
7508}
Larry Hastings2f936352014-08-05 14:04:04 +10007509#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007510
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007511
7512#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10007513/*[clinic input]
7514os.sched_getparam
7515 pid: pid_t
7516 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007517
Larry Hastings2f936352014-08-05 14:04:04 +10007518Returns scheduling parameters for the process identified by pid.
7519
7520If pid is 0, returns parameters for the calling process.
7521Return value is an instance of sched_param.
7522[clinic start generated code]*/
7523
7524PyDoc_STRVAR(os_sched_getparam__doc__,
7525"sched_getparam($module, pid, /)\n"
7526"--\n"
7527"\n"
7528"Returns scheduling parameters for the process identified by pid.\n"
7529"\n"
7530"If pid is 0, returns parameters for the calling process.\n"
7531"Return value is an instance of sched_param.");
7532
7533#define OS_SCHED_GETPARAM_METHODDEF \
7534 {"sched_getparam", (PyCFunction)os_sched_getparam, METH_VARARGS, os_sched_getparam__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007535
7536static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007537os_sched_getparam_impl(PyModuleDef *module, pid_t pid);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007538
Larry Hastings2f936352014-08-05 14:04:04 +10007539static PyObject *
7540os_sched_getparam(PyModuleDef *module, PyObject *args)
7541{
7542 PyObject *return_value = NULL;
7543 pid_t pid;
7544
7545 if (!PyArg_ParseTuple(args,
7546 "" _Py_PARSE_PID ":sched_getparam",
7547 &pid))
7548 goto exit;
7549 return_value = os_sched_getparam_impl(module, pid);
7550
7551exit:
7552 return return_value;
7553}
7554
7555static PyObject *
7556os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
7557/*[clinic end generated code: output=b33acc8db004a8c9 input=18a1ef9c2efae296]*/
7558{
7559 struct sched_param param;
7560 PyObject *result;
7561 PyObject *priority;
7562
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007563 if (sched_getparam(pid, &param))
7564 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007565 result = PyStructSequence_New(&SchedParamType);
7566 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007567 return NULL;
7568 priority = PyLong_FromLong(param.sched_priority);
7569 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10007570 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007571 return NULL;
7572 }
Larry Hastings2f936352014-08-05 14:04:04 +10007573 PyStructSequence_SET_ITEM(result, 0, priority);
7574 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007575}
7576
Larry Hastings2f936352014-08-05 14:04:04 +10007577
7578/*[clinic input]
7579os.sched_setparam
7580 pid: pid_t
7581 param: sched_param
7582 /
7583
7584Set scheduling parameters for the process identified by pid.
7585
7586If pid is 0, sets parameters for the calling process.
7587param should be an instance of sched_param.
7588[clinic start generated code]*/
7589
7590PyDoc_STRVAR(os_sched_setparam__doc__,
7591"sched_setparam($module, pid, param, /)\n"
7592"--\n"
7593"\n"
7594"Set scheduling parameters for the process identified by pid.\n"
7595"\n"
7596"If pid is 0, sets parameters for the calling process.\n"
7597"param should be an instance of sched_param.");
7598
7599#define OS_SCHED_SETPARAM_METHODDEF \
7600 {"sched_setparam", (PyCFunction)os_sched_setparam, METH_VARARGS, os_sched_setparam__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007601
7602static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007603os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param);
7604
7605static PyObject *
7606os_sched_setparam(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007607{
Larry Hastings2f936352014-08-05 14:04:04 +10007608 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007609 pid_t pid;
7610 struct sched_param param;
7611
Larry Hastings2f936352014-08-05 14:04:04 +10007612 if (!PyArg_ParseTuple(args,
7613 "" _Py_PARSE_PID "O&:sched_setparam",
7614 &pid, convert_sched_param, &param))
7615 goto exit;
7616 return_value = os_sched_setparam_impl(module, pid, &param);
7617
7618exit:
7619 return return_value;
7620}
7621
7622static PyObject *
7623os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param)
7624/*[clinic end generated code: output=488bdf5bcbe0d4e8 input=6b8d6dfcecdc21bd]*/
7625{
7626 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007627 return posix_error();
7628 Py_RETURN_NONE;
7629}
Larry Hastings2f936352014-08-05 14:04:04 +10007630#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007631
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007632
7633#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10007634/*[clinic input]
7635os.sched_rr_get_interval -> double
7636 pid: pid_t
7637 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007638
Larry Hastings2f936352014-08-05 14:04:04 +10007639Return the round-robin quantum for the process identified by pid, in seconds.
7640
7641Value returned is a float.
7642[clinic start generated code]*/
7643
7644PyDoc_STRVAR(os_sched_rr_get_interval__doc__,
7645"sched_rr_get_interval($module, pid, /)\n"
7646"--\n"
7647"\n"
7648"Return the round-robin quantum for the process identified by pid, in seconds.\n"
7649"\n"
7650"Value returned is a float.");
7651
7652#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \
7653 {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_VARARGS, os_sched_rr_get_interval__doc__},
7654
7655static double
7656os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007657
7658static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007659os_sched_rr_get_interval(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007660{
Larry Hastings2f936352014-08-05 14:04:04 +10007661 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007662 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007663 double _return_value;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007664
Larry Hastings2f936352014-08-05 14:04:04 +10007665 if (!PyArg_ParseTuple(args,
7666 "" _Py_PARSE_PID ":sched_rr_get_interval",
7667 &pid))
7668 goto exit;
7669 _return_value = os_sched_rr_get_interval_impl(module, pid);
7670 if ((_return_value == -1.0) && PyErr_Occurred())
7671 goto exit;
7672 return_value = PyFloat_FromDouble(_return_value);
7673
7674exit:
7675 return return_value;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007676}
7677
Larry Hastings2f936352014-08-05 14:04:04 +10007678static double
7679os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
7680/*[clinic end generated code: output=5b3b8d1f27fb2c0a input=2a973da15cca6fae]*/
7681{
7682 struct timespec interval;
7683 if (sched_rr_get_interval(pid, &interval)) {
7684 posix_error();
7685 return -1.0;
7686 }
7687 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
7688}
7689#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007690
Larry Hastings2f936352014-08-05 14:04:04 +10007691
7692/*[clinic input]
7693os.sched_yield
7694
7695Voluntarily relinquish the CPU.
7696[clinic start generated code]*/
7697
7698PyDoc_STRVAR(os_sched_yield__doc__,
7699"sched_yield($module, /)\n"
7700"--\n"
7701"\n"
7702"Voluntarily relinquish the CPU.");
7703
7704#define OS_SCHED_YIELD_METHODDEF \
7705 {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007706
7707static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007708os_sched_yield_impl(PyModuleDef *module);
7709
7710static PyObject *
7711os_sched_yield(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
7712{
7713 return os_sched_yield_impl(module);
7714}
7715
7716static PyObject *
7717os_sched_yield_impl(PyModuleDef *module)
7718/*[clinic end generated code: output=9d2e5f29f1370324 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007719{
7720 if (sched_yield())
7721 return posix_error();
7722 Py_RETURN_NONE;
7723}
7724
Benjamin Peterson2740af82011-08-02 17:41:34 -05007725#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02007726/* The minimum number of CPUs allocated in a cpu_set_t */
7727static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007728
Larry Hastings2f936352014-08-05 14:04:04 +10007729/*[clinic input]
7730os.sched_setaffinity
7731 pid: pid_t
7732 mask : object
7733 /
7734
7735Set the CPU affinity of the process identified by pid to mask.
7736
7737mask should be an iterable of integers identifying CPUs.
7738[clinic start generated code]*/
7739
7740PyDoc_STRVAR(os_sched_setaffinity__doc__,
7741"sched_setaffinity($module, pid, mask, /)\n"
7742"--\n"
7743"\n"
7744"Set the CPU affinity of the process identified by pid to mask.\n"
7745"\n"
7746"mask should be an iterable of integers identifying CPUs.");
7747
7748#define OS_SCHED_SETAFFINITY_METHODDEF \
7749 {"sched_setaffinity", (PyCFunction)os_sched_setaffinity, METH_VARARGS, os_sched_setaffinity__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007750
7751static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007752os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask);
7753
7754static PyObject *
7755os_sched_setaffinity(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007756{
Larry Hastings2f936352014-08-05 14:04:04 +10007757 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007758 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007759 PyObject *mask;
7760
7761 if (!PyArg_ParseTuple(args,
7762 "" _Py_PARSE_PID "O:sched_setaffinity",
7763 &pid, &mask))
7764 goto exit;
7765 return_value = os_sched_setaffinity_impl(module, pid, mask);
7766
7767exit:
7768 return return_value;
7769}
7770
7771static PyObject *
7772os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
7773/*[clinic end generated code: output=5199929738130196 input=a0791a597c7085ba]*/
7774{
Antoine Pitrou84869872012-08-04 16:16:35 +02007775 int ncpus;
7776 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007777 cpu_set_t *cpu_set = NULL;
7778 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007779
Larry Hastings2f936352014-08-05 14:04:04 +10007780 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02007781 if (iterator == NULL)
7782 return NULL;
7783
7784 ncpus = NCPUS_START;
7785 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10007786 cpu_set = CPU_ALLOC(ncpus);
7787 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007788 PyErr_NoMemory();
7789 goto error;
7790 }
Larry Hastings2f936352014-08-05 14:04:04 +10007791 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007792
7793 while ((item = PyIter_Next(iterator))) {
7794 long cpu;
7795 if (!PyLong_Check(item)) {
7796 PyErr_Format(PyExc_TypeError,
7797 "expected an iterator of ints, "
7798 "but iterator yielded %R",
7799 Py_TYPE(item));
7800 Py_DECREF(item);
7801 goto error;
7802 }
7803 cpu = PyLong_AsLong(item);
7804 Py_DECREF(item);
7805 if (cpu < 0) {
7806 if (!PyErr_Occurred())
7807 PyErr_SetString(PyExc_ValueError, "negative CPU number");
7808 goto error;
7809 }
7810 if (cpu > INT_MAX - 1) {
7811 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7812 goto error;
7813 }
7814 if (cpu >= ncpus) {
7815 /* Grow CPU mask to fit the CPU number */
7816 int newncpus = ncpus;
7817 cpu_set_t *newmask;
7818 size_t newsetsize;
7819 while (newncpus <= cpu) {
7820 if (newncpus > INT_MAX / 2)
7821 newncpus = cpu + 1;
7822 else
7823 newncpus = newncpus * 2;
7824 }
7825 newmask = CPU_ALLOC(newncpus);
7826 if (newmask == NULL) {
7827 PyErr_NoMemory();
7828 goto error;
7829 }
7830 newsetsize = CPU_ALLOC_SIZE(newncpus);
7831 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007832 memcpy(newmask, cpu_set, setsize);
7833 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007834 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007835 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007836 ncpus = newncpus;
7837 }
Larry Hastings2f936352014-08-05 14:04:04 +10007838 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007839 }
7840 Py_CLEAR(iterator);
7841
Larry Hastings2f936352014-08-05 14:04:04 +10007842 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007843 posix_error();
7844 goto error;
7845 }
Larry Hastings2f936352014-08-05 14:04:04 +10007846 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007847 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007848
7849error:
Larry Hastings2f936352014-08-05 14:04:04 +10007850 if (cpu_set)
7851 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007852 Py_XDECREF(iterator);
7853 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007854}
7855
Larry Hastings2f936352014-08-05 14:04:04 +10007856
7857/*[clinic input]
7858os.sched_getaffinity
7859 pid: pid_t
7860 /
7861
7862Return the affinity of the process identified by pid.
7863
7864The affinity is returned as a set of CPU identifiers.
7865[clinic start generated code]*/
7866
7867PyDoc_STRVAR(os_sched_getaffinity__doc__,
7868"sched_getaffinity($module, pid, /)\n"
7869"--\n"
7870"\n"
7871"Return the affinity of the process identified by pid.\n"
7872"\n"
7873"The affinity is returned as a set of CPU identifiers.");
7874
7875#define OS_SCHED_GETAFFINITY_METHODDEF \
7876 {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_VARARGS, os_sched_getaffinity__doc__},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007877
7878static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007879os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid);
7880
7881static PyObject *
7882os_sched_getaffinity(PyModuleDef *module, PyObject *args)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007883{
Larry Hastings2f936352014-08-05 14:04:04 +10007884 PyObject *return_value = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007885 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +10007886
7887 if (!PyArg_ParseTuple(args,
7888 "" _Py_PARSE_PID ":sched_getaffinity",
7889 &pid))
7890 goto exit;
7891 return_value = os_sched_getaffinity_impl(module, pid);
7892
7893exit:
7894 return return_value;
7895}
7896
7897static PyObject *
7898os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
7899/*[clinic end generated code: output=7b273b0fca9830f0 input=eaf161936874b8a1]*/
7900{
Antoine Pitrou84869872012-08-04 16:16:35 +02007901 int cpu, ncpus, count;
7902 size_t setsize;
7903 cpu_set_t *mask = NULL;
7904 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007905
Antoine Pitrou84869872012-08-04 16:16:35 +02007906 ncpus = NCPUS_START;
7907 while (1) {
7908 setsize = CPU_ALLOC_SIZE(ncpus);
7909 mask = CPU_ALLOC(ncpus);
7910 if (mask == NULL)
7911 return PyErr_NoMemory();
7912 if (sched_getaffinity(pid, setsize, mask) == 0)
7913 break;
7914 CPU_FREE(mask);
7915 if (errno != EINVAL)
7916 return posix_error();
7917 if (ncpus > INT_MAX / 2) {
7918 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7919 "a large enough CPU set");
7920 return NULL;
7921 }
7922 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007923 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007924
7925 res = PySet_New(NULL);
7926 if (res == NULL)
7927 goto error;
7928 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7929 if (CPU_ISSET_S(cpu, setsize, mask)) {
7930 PyObject *cpu_num = PyLong_FromLong(cpu);
7931 --count;
7932 if (cpu_num == NULL)
7933 goto error;
7934 if (PySet_Add(res, cpu_num)) {
7935 Py_DECREF(cpu_num);
7936 goto error;
7937 }
7938 Py_DECREF(cpu_num);
7939 }
7940 }
7941 CPU_FREE(mask);
7942 return res;
7943
7944error:
7945 if (mask)
7946 CPU_FREE(mask);
7947 Py_XDECREF(res);
7948 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007949}
7950
Benjamin Peterson2740af82011-08-02 17:41:34 -05007951#endif /* HAVE_SCHED_SETAFFINITY */
7952
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007953#endif /* HAVE_SCHED_H */
7954
Larry Hastings2f936352014-08-05 14:04:04 +10007955#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF
7956#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF
7957#endif /* OS_SCHED_GET_PRIORITY_MAX_METHODDEF */
7958
7959#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF
7960#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF
7961#endif /* OS_SCHED_GET_PRIORITY_MIN_METHODDEF */
7962
7963#ifndef OS_SCHED_GETSCHEDULER_METHODDEF
7964#define OS_SCHED_GETSCHEDULER_METHODDEF
7965#endif /* OS_SCHED_GETSCHEDULER_METHODDEF */
7966
7967#ifndef OS_SCHED_SETSCHEDULER_METHODDEF
7968#define OS_SCHED_SETSCHEDULER_METHODDEF
7969#endif /* OS_SCHED_SETSCHEDULER_METHODDEF */
7970
7971#ifndef OS_SCHED_GETPARAM_METHODDEF
7972#define OS_SCHED_GETPARAM_METHODDEF
7973#endif /* OS_SCHED_GETPARAM_METHODDEF */
7974
7975#ifndef OS_SCHED_SETPARAM_METHODDEF
7976#define OS_SCHED_SETPARAM_METHODDEF
7977#endif /* OS_SCHED_SETPARAM_METHODDEF */
7978
7979#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF
7980#define OS_SCHED_RR_GET_INTERVAL_METHODDEF
7981#endif /* OS_SCHED_RR_GET_INTERVAL_METHODDEF */
7982
7983#ifndef OS_SCHED_YIELD_METHODDEF
7984#define OS_SCHED_YIELD_METHODDEF
7985#endif /* OS_SCHED_YIELD_METHODDEF */
7986
7987#ifndef OS_SCHED_SETAFFINITY_METHODDEF
7988#define OS_SCHED_SETAFFINITY_METHODDEF
7989#endif /* OS_SCHED_SETAFFINITY_METHODDEF */
7990
7991#ifndef OS_SCHED_GETAFFINITY_METHODDEF
7992#define OS_SCHED_GETAFFINITY_METHODDEF
7993#endif /* OS_SCHED_GETAFFINITY_METHODDEF */
7994
7995
Neal Norwitzb59798b2003-03-21 01:43:31 +00007996/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007997/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
7998#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00007999#define DEV_PTY_FILE "/dev/ptc"
8000#define HAVE_DEV_PTMX
8001#else
8002#define DEV_PTY_FILE "/dev/ptmx"
8003#endif
8004
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008005#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00008006#ifdef HAVE_PTY_H
8007#include <pty.h>
8008#else
8009#ifdef HAVE_LIBUTIL_H
8010#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00008011#else
8012#ifdef HAVE_UTIL_H
8013#include <util.h>
8014#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008015#endif /* HAVE_LIBUTIL_H */
8016#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00008017#ifdef HAVE_STROPTS_H
8018#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008019#endif
8020#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008021
Larry Hastings2f936352014-08-05 14:04:04 +10008022
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008023#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10008024/*[clinic input]
8025os.openpty
8026
8027Open a pseudo-terminal.
8028
8029Return a tuple of (master_fd, slave_fd) containing open file descriptors
8030for both the master and slave ends.
8031[clinic start generated code]*/
8032
8033PyDoc_STRVAR(os_openpty__doc__,
8034"openpty($module, /)\n"
8035"--\n"
8036"\n"
8037"Open a pseudo-terminal.\n"
8038"\n"
8039"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n"
8040"for both the master and slave ends.");
8041
8042#define OS_OPENPTY_METHODDEF \
8043 {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008044
8045static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008046os_openpty_impl(PyModuleDef *module);
8047
8048static PyObject *
8049os_openpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8050{
8051 return os_openpty_impl(module);
8052}
8053
8054static PyObject *
8055os_openpty_impl(PyModuleDef *module)
8056/*[clinic end generated code: output=b12d3c1735468464 input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00008057{
Victor Stinnerdaf45552013-08-28 00:53:59 +02008058 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00008059#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00008061#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008062#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00008063 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008064#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008066#endif
8067#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00008068
Thomas Wouters70c21a12000-07-14 14:28:33 +00008069#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008071 goto posix_error;
8072
8073 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
8074 goto error;
8075 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
8076 goto error;
8077
Neal Norwitzb59798b2003-03-21 01:43:31 +00008078#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
8080 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008081 goto posix_error;
8082 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
8083 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00008084
Victor Stinnerdaf45552013-08-28 00:53:59 +02008085 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008087 goto posix_error;
8088
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008089#else
Victor Stinner000de532013-11-25 23:19:58 +01008090 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008092 goto posix_error;
8093
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008095
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 /* change permission of slave */
8097 if (grantpt(master_fd) < 0) {
8098 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008099 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008101
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 /* unlock slave */
8103 if (unlockpt(master_fd) < 0) {
8104 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008105 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008107
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008109
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 slave_name = ptsname(master_fd); /* get name of slave */
8111 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008112 goto posix_error;
8113
8114 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008116 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01008117
8118 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
8119 goto posix_error;
8120
Neal Norwitzb59798b2003-03-21 01:43:31 +00008121#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
8123 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00008124#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00008126#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008127#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00008128#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00008129
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00008131
Victor Stinnerdaf45552013-08-28 00:53:59 +02008132posix_error:
8133 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02008134#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02008135error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02008136#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02008137 if (master_fd != -1)
8138 close(master_fd);
8139 if (slave_fd != -1)
8140 close(slave_fd);
8141 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00008142}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008143#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008144
Larry Hastings2f936352014-08-05 14:04:04 +10008145
Fred Drake8cef4cf2000-06-28 16:40:38 +00008146#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10008147/*[clinic input]
8148os.forkpty
8149
8150Fork a new process with a new pseudo-terminal as controlling tty.
8151
8152Returns a tuple of (pid, master_fd).
8153Like fork(), return pid of 0 to the child process,
8154and pid of child to the parent process.
8155To both, return fd of newly opened pseudo-terminal.
8156[clinic start generated code]*/
8157
8158PyDoc_STRVAR(os_forkpty__doc__,
8159"forkpty($module, /)\n"
8160"--\n"
8161"\n"
8162"Fork a new process with a new pseudo-terminal as controlling tty.\n"
8163"\n"
8164"Returns a tuple of (pid, master_fd).\n"
8165"Like fork(), return pid of 0 to the child process,\n"
8166"and pid of child to the parent process.\n"
8167"To both, return fd of newly opened pseudo-terminal.");
8168
8169#define OS_FORKPTY_METHODDEF \
8170 {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008171
8172static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008173os_forkpty_impl(PyModuleDef *module);
8174
8175static PyObject *
8176os_forkpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8177{
8178 return os_forkpty_impl(module);
8179}
8180
8181static PyObject *
8182os_forkpty_impl(PyModuleDef *module)
8183/*[clinic end generated code: output=d4f82958d2ed5cad input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00008184{
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 int master_fd = -1, result = 0;
8186 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00008187
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 _PyImport_AcquireLock();
8189 pid = forkpty(&master_fd, NULL, NULL, NULL);
8190 if (pid == 0) {
8191 /* child: this clobbers and resets the import lock. */
8192 PyOS_AfterFork();
8193 } else {
8194 /* parent: release the import lock. */
8195 result = _PyImport_ReleaseLock();
8196 }
8197 if (pid == -1)
8198 return posix_error();
8199 if (result < 0) {
8200 /* Don't clobber the OSError if the fork failed. */
8201 PyErr_SetString(PyExc_RuntimeError,
8202 "not holding the import lock");
8203 return NULL;
8204 }
8205 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00008206}
Larry Hastings2f936352014-08-05 14:04:04 +10008207#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008208
Ross Lagerwall7807c352011-03-17 20:20:30 +02008209
Guido van Rossumad0ee831995-03-01 10:34:45 +00008210#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10008211/*[clinic input]
8212os.getegid
8213
8214Return the current process's effective group id.
8215[clinic start generated code]*/
8216
8217PyDoc_STRVAR(os_getegid__doc__,
8218"getegid($module, /)\n"
8219"--\n"
8220"\n"
8221"Return the current process\'s effective group id.");
8222
8223#define OS_GETEGID_METHODDEF \
8224 {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008225
Barry Warsaw53699e91996-12-10 23:23:01 +00008226static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008227os_getegid_impl(PyModuleDef *module);
8228
8229static PyObject *
8230os_getegid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8231{
8232 return os_getegid_impl(module);
8233}
8234
8235static PyObject *
8236os_getegid_impl(PyModuleDef *module)
8237/*[clinic end generated code: output=fd12c346fa41cccb input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008238{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008239 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008240}
Larry Hastings2f936352014-08-05 14:04:04 +10008241#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008243
Guido van Rossumad0ee831995-03-01 10:34:45 +00008244#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008245/*[clinic input]
8246os.geteuid
8247
8248Return the current process's effective user id.
8249[clinic start generated code]*/
8250
8251PyDoc_STRVAR(os_geteuid__doc__,
8252"geteuid($module, /)\n"
8253"--\n"
8254"\n"
8255"Return the current process\'s effective user id.");
8256
8257#define OS_GETEUID_METHODDEF \
8258 {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008259
Barry Warsaw53699e91996-12-10 23:23:01 +00008260static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008261os_geteuid_impl(PyModuleDef *module);
8262
8263static PyObject *
8264os_geteuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8265{
8266 return os_geteuid_impl(module);
8267}
8268
8269static PyObject *
8270os_geteuid_impl(PyModuleDef *module)
8271/*[clinic end generated code: output=03d98e07f4bc03d4 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008272{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008273 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008274}
Larry Hastings2f936352014-08-05 14:04:04 +10008275#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008277
Guido van Rossumad0ee831995-03-01 10:34:45 +00008278#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008279/*[clinic input]
8280os.getgid
8281
8282Return the current process's group id.
8283[clinic start generated code]*/
8284
8285PyDoc_STRVAR(os_getgid__doc__,
8286"getgid($module, /)\n"
8287"--\n"
8288"\n"
8289"Return the current process\'s group id.");
8290
8291#define OS_GETGID_METHODDEF \
8292 {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008293
Barry Warsaw53699e91996-12-10 23:23:01 +00008294static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008295os_getgid_impl(PyModuleDef *module);
8296
8297static PyObject *
8298os_getgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8299{
8300 return os_getgid_impl(module);
8301}
8302
8303static PyObject *
8304os_getgid_impl(PyModuleDef *module)
8305/*[clinic end generated code: output=07b0356121b8098d input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008306{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008307 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008308}
Larry Hastings2f936352014-08-05 14:04:04 +10008309#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008311
Larry Hastings2f936352014-08-05 14:04:04 +10008312/*[clinic input]
8313os.getpid
8314
8315Return the current process id.
8316[clinic start generated code]*/
8317
8318PyDoc_STRVAR(os_getpid__doc__,
8319"getpid($module, /)\n"
8320"--\n"
8321"\n"
8322"Return the current process id.");
8323
8324#define OS_GETPID_METHODDEF \
8325 {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008326
Barry Warsaw53699e91996-12-10 23:23:01 +00008327static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008328os_getpid_impl(PyModuleDef *module);
8329
8330static PyObject *
8331os_getpid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8332{
8333 return os_getpid_impl(module);
8334}
8335
8336static PyObject *
8337os_getpid_impl(PyModuleDef *module)
8338/*[clinic end generated code: output=d63a01a3cebc573d input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00008339{
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00008341}
8342
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008343#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10008344
8345/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008346PyDoc_STRVAR(posix_getgrouplist__doc__,
8347"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
8348Returns a list of groups to which a user belongs.\n\n\
8349 user: username to lookup\n\
8350 group: base group id of the user");
8351
8352static PyObject *
8353posix_getgrouplist(PyObject *self, PyObject *args)
8354{
8355#ifdef NGROUPS_MAX
8356#define MAX_GROUPS NGROUPS_MAX
8357#else
8358 /* defined to be 16 on Solaris7, so this should be a small number */
8359#define MAX_GROUPS 64
8360#endif
8361
8362 const char *user;
8363 int i, ngroups;
8364 PyObject *list;
8365#ifdef __APPLE__
8366 int *groups, basegid;
8367#else
8368 gid_t *groups, basegid;
8369#endif
8370 ngroups = MAX_GROUPS;
8371
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008372#ifdef __APPLE__
8373 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008374 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008375#else
8376 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
8377 _Py_Gid_Converter, &basegid))
8378 return NULL;
8379#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008380
8381#ifdef __APPLE__
8382 groups = PyMem_Malloc(ngroups * sizeof(int));
8383#else
8384 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
8385#endif
8386 if (groups == NULL)
8387 return PyErr_NoMemory();
8388
8389 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
8390 PyMem_Del(groups);
8391 return posix_error();
8392 }
8393
8394 list = PyList_New(ngroups);
8395 if (list == NULL) {
8396 PyMem_Del(groups);
8397 return NULL;
8398 }
8399
8400 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008401#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008402 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008403#else
8404 PyObject *o = _PyLong_FromGid(groups[i]);
8405#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02008406 if (o == NULL) {
8407 Py_DECREF(list);
8408 PyMem_Del(groups);
8409 return NULL;
8410 }
8411 PyList_SET_ITEM(list, i, o);
8412 }
8413
8414 PyMem_Del(groups);
8415
8416 return list;
8417}
Larry Hastings2f936352014-08-05 14:04:04 +10008418#endif /* HAVE_GETGROUPLIST */
8419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008420
Fred Drakec9680921999-12-13 16:37:25 +00008421#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008422/*[clinic input]
8423os.getgroups
8424
8425Return list of supplemental group IDs for the process.
8426[clinic start generated code]*/
8427
8428PyDoc_STRVAR(os_getgroups__doc__,
8429"getgroups($module, /)\n"
8430"--\n"
8431"\n"
8432"Return list of supplemental group IDs for the process.");
8433
8434#define OS_GETGROUPS_METHODDEF \
8435 {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008436
8437static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008438os_getgroups_impl(PyModuleDef *module);
8439
8440static PyObject *
8441os_getgroups(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8442{
8443 return os_getgroups_impl(module);
8444}
8445
8446static PyObject *
8447os_getgroups_impl(PyModuleDef *module)
8448/*[clinic end generated code: output=d9a3559b2e6f4ab8 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00008449{
8450 PyObject *result = NULL;
8451
Fred Drakec9680921999-12-13 16:37:25 +00008452#ifdef NGROUPS_MAX
8453#define MAX_GROUPS NGROUPS_MAX
8454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00008456#define MAX_GROUPS 64
8457#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008459
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008460 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008461 * This is a helper variable to store the intermediate result when
8462 * that happens.
8463 *
8464 * To keep the code readable the OSX behaviour is unconditional,
8465 * according to the POSIX spec this should be safe on all unix-y
8466 * systems.
8467 */
8468 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 int n;
Fred Drakec9680921999-12-13 16:37:25 +00008470
Ned Deilyb5dd6d22013-08-01 21:21:15 -07008471#ifdef __APPLE__
8472 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
8473 * there are more groups than can fit in grouplist. Therefore, on OS X
8474 * always first call getgroups with length 0 to get the actual number
8475 * of groups.
8476 */
8477 n = getgroups(0, NULL);
8478 if (n < 0) {
8479 return posix_error();
8480 } else if (n <= MAX_GROUPS) {
8481 /* groups will fit in existing array */
8482 alt_grouplist = grouplist;
8483 } else {
8484 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
8485 if (alt_grouplist == NULL) {
8486 errno = EINVAL;
8487 return posix_error();
8488 }
8489 }
8490
8491 n = getgroups(n, alt_grouplist);
8492 if (n == -1) {
8493 if (alt_grouplist != grouplist) {
8494 PyMem_Free(alt_grouplist);
8495 }
8496 return posix_error();
8497 }
8498#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008500 if (n < 0) {
8501 if (errno == EINVAL) {
8502 n = getgroups(0, NULL);
8503 if (n == -1) {
8504 return posix_error();
8505 }
8506 if (n == 0) {
8507 /* Avoid malloc(0) */
8508 alt_grouplist = grouplist;
8509 } else {
8510 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
8511 if (alt_grouplist == NULL) {
8512 errno = EINVAL;
8513 return posix_error();
8514 }
8515 n = getgroups(n, alt_grouplist);
8516 if (n == -1) {
8517 PyMem_Free(alt_grouplist);
8518 return posix_error();
8519 }
8520 }
8521 } else {
8522 return posix_error();
8523 }
8524 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07008525#endif
8526
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008527 result = PyList_New(n);
8528 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 int i;
8530 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008531 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008533 Py_DECREF(result);
8534 result = NULL;
8535 break;
Fred Drakec9680921999-12-13 16:37:25 +00008536 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00008538 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00008539 }
8540
8541 if (alt_grouplist != grouplist) {
8542 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00008543 }
Neal Norwitze241ce82003-02-17 18:17:05 +00008544
Fred Drakec9680921999-12-13 16:37:25 +00008545 return result;
8546}
Larry Hastings2f936352014-08-05 14:04:04 +10008547#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00008548
Antoine Pitroub7572f02009-12-02 20:46:48 +00008549#ifdef HAVE_INITGROUPS
8550PyDoc_STRVAR(posix_initgroups__doc__,
8551"initgroups(username, gid) -> None\n\n\
8552Call the system initgroups() to initialize the group access list with all of\n\
8553the groups of which the specified username is a member, plus the specified\n\
8554group id.");
8555
Larry Hastings2f936352014-08-05 14:04:04 +10008556/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00008557static PyObject *
8558posix_initgroups(PyObject *self, PyObject *args)
8559{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008560 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008562 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008563#ifdef __APPLE__
8564 int gid;
8565#else
8566 gid_t gid;
8567#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00008568
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008569#ifdef __APPLE__
8570 if (!PyArg_ParseTuple(args, "O&i:initgroups",
8571 PyUnicode_FSConverter, &oname,
8572 &gid))
8573#else
8574 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
8575 PyUnicode_FSConverter, &oname,
8576 _Py_Gid_Converter, &gid))
8577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008579 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00008580
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008581 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00008582 Py_DECREF(oname);
8583 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00008585
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 Py_INCREF(Py_None);
8587 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00008588}
Larry Hastings2f936352014-08-05 14:04:04 +10008589#endif /* HAVE_INITGROUPS */
8590
Antoine Pitroub7572f02009-12-02 20:46:48 +00008591
Martin v. Löwis606edc12002-06-13 21:09:11 +00008592#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008593/*[clinic input]
8594os.getpgid
8595
8596 pid: pid_t
8597
8598Call the system call getpgid(), and return the result.
8599[clinic start generated code]*/
8600
8601PyDoc_STRVAR(os_getpgid__doc__,
8602"getpgid($module, /, pid)\n"
8603"--\n"
8604"\n"
8605"Call the system call getpgid(), and return the result.");
8606
8607#define OS_GETPGID_METHODDEF \
8608 {"getpgid", (PyCFunction)os_getpgid, METH_VARARGS|METH_KEYWORDS, os_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008609
8610static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008611os_getpgid_impl(PyModuleDef *module, pid_t pid);
8612
8613static PyObject *
8614os_getpgid(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwis606edc12002-06-13 21:09:11 +00008615{
Larry Hastings2f936352014-08-05 14:04:04 +10008616 PyObject *return_value = NULL;
8617 static char *_keywords[] = {"pid", NULL};
8618 pid_t pid;
8619
8620 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
8621 "" _Py_PARSE_PID ":getpgid", _keywords,
8622 &pid))
8623 goto exit;
8624 return_value = os_getpgid_impl(module, pid);
8625
8626exit:
8627 return return_value;
8628}
8629
8630static PyObject *
8631os_getpgid_impl(PyModuleDef *module, pid_t pid)
8632/*[clinic end generated code: output=3db4ed686179160d input=39d710ae3baaf1c7]*/
8633{
8634 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 if (pgid < 0)
8636 return posix_error();
8637 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00008638}
8639#endif /* HAVE_GETPGID */
8640
8641
Guido van Rossumb6775db1994-08-01 11:34:53 +00008642#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008643/*[clinic input]
8644os.getpgrp
8645
8646Return the current process group id.
8647[clinic start generated code]*/
8648
8649PyDoc_STRVAR(os_getpgrp__doc__,
8650"getpgrp($module, /)\n"
8651"--\n"
8652"\n"
8653"Return the current process group id.");
8654
8655#define OS_GETPGRP_METHODDEF \
8656 {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008657
Barry Warsaw53699e91996-12-10 23:23:01 +00008658static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008659os_getpgrp_impl(PyModuleDef *module);
8660
8661static PyObject *
8662os_getpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8663{
8664 return os_getpgrp_impl(module);
8665}
8666
8667static PyObject *
8668os_getpgrp_impl(PyModuleDef *module)
8669/*[clinic end generated code: output=3b0d3663ea054277 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00008670{
Guido van Rossumb6775db1994-08-01 11:34:53 +00008671#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008673#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008675#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00008676}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008677#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00008678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008679
Guido van Rossumb6775db1994-08-01 11:34:53 +00008680#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008681/*[clinic input]
8682os.setpgrp
8683
8684Make the current process the leader of its process group.
8685[clinic start generated code]*/
8686
8687PyDoc_STRVAR(os_setpgrp__doc__,
8688"setpgrp($module, /)\n"
8689"--\n"
8690"\n"
8691"Make the current process the leader of its process group.");
8692
8693#define OS_SETPGRP_METHODDEF \
8694 {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008695
Barry Warsaw53699e91996-12-10 23:23:01 +00008696static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008697os_setpgrp_impl(PyModuleDef *module);
8698
8699static PyObject *
8700os_setpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8701{
8702 return os_setpgrp_impl(module);
8703}
8704
8705static PyObject *
8706os_setpgrp_impl(PyModuleDef *module)
8707/*[clinic end generated code: output=8fbb0ee29ef6fb2d input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008708{
Guido van Rossum64933891994-10-20 21:56:42 +00008709#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00008711#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00008713#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 return posix_error();
8715 Py_INCREF(Py_None);
8716 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008717}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008718#endif /* HAVE_SETPGRP */
8719
Guido van Rossumad0ee831995-03-01 10:34:45 +00008720#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008721
8722#ifdef MS_WINDOWS
8723#include <tlhelp32.h>
8724
8725static PyObject*
8726win32_getppid()
8727{
8728 HANDLE snapshot;
8729 pid_t mypid;
8730 PyObject* result = NULL;
8731 BOOL have_record;
8732 PROCESSENTRY32 pe;
8733
8734 mypid = getpid(); /* This function never fails */
8735
8736 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
8737 if (snapshot == INVALID_HANDLE_VALUE)
8738 return PyErr_SetFromWindowsErr(GetLastError());
8739
8740 pe.dwSize = sizeof(pe);
8741 have_record = Process32First(snapshot, &pe);
8742 while (have_record) {
8743 if (mypid == (pid_t)pe.th32ProcessID) {
8744 /* We could cache the ulong value in a static variable. */
8745 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
8746 break;
8747 }
8748
8749 have_record = Process32Next(snapshot, &pe);
8750 }
8751
8752 /* If our loop exits and our pid was not found (result will be NULL)
8753 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
8754 * error anyway, so let's raise it. */
8755 if (!result)
8756 result = PyErr_SetFromWindowsErr(GetLastError());
8757
8758 CloseHandle(snapshot);
8759
8760 return result;
8761}
8762#endif /*MS_WINDOWS*/
8763
Larry Hastings2f936352014-08-05 14:04:04 +10008764
8765/*[clinic input]
8766os.getppid
8767
8768Return the parent's process id.
8769
8770If the parent process has already exited, Windows machines will still
8771return its id; others systems will return the id of the 'init' process (1).
8772[clinic start generated code]*/
8773
8774PyDoc_STRVAR(os_getppid__doc__,
8775"getppid($module, /)\n"
8776"--\n"
8777"\n"
8778"Return the parent\'s process id.\n"
8779"\n"
8780"If the parent process has already exited, Windows machines will still\n"
8781"return its id; others systems will return the id of the \'init\' process (1).");
8782
8783#define OS_GETPPID_METHODDEF \
8784 {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008785
Barry Warsaw53699e91996-12-10 23:23:01 +00008786static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008787os_getppid_impl(PyModuleDef *module);
8788
8789static PyObject *
8790os_getppid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8791{
8792 return os_getppid_impl(module);
8793}
8794
8795static PyObject *
8796os_getppid_impl(PyModuleDef *module)
8797/*[clinic end generated code: output=9ff3b387781edf3a input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00008798{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008799#ifdef MS_WINDOWS
8800 return win32_getppid();
8801#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00008803#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00008804}
8805#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008807
Fred Drake12c6e2d1999-12-14 21:25:03 +00008808#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10008809/*[clinic input]
8810os.getlogin
8811
8812Return the actual login name.
8813[clinic start generated code]*/
8814
8815PyDoc_STRVAR(os_getlogin__doc__,
8816"getlogin($module, /)\n"
8817"--\n"
8818"\n"
8819"Return the actual login name.");
8820
8821#define OS_GETLOGIN_METHODDEF \
8822 {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008823
8824static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008825os_getlogin_impl(PyModuleDef *module);
8826
8827static PyObject *
8828os_getlogin(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8829{
8830 return os_getlogin_impl(module);
8831}
8832
8833static PyObject *
8834os_getlogin_impl(PyModuleDef *module)
8835/*[clinic end generated code: output=ab6211dab104cbb2 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00008836{
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008838#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008839 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02008840 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008841
8842 if (GetUserNameW(user_name, &num_chars)) {
8843 /* num_chars is the number of unicode chars plus null terminator */
8844 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008845 }
8846 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008847 result = PyErr_SetFromWindowsErr(GetLastError());
8848#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 char *name;
8850 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008851
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 errno = 0;
8853 name = getlogin();
8854 if (name == NULL) {
8855 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00008856 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00008857 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00008858 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 }
8860 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00008861 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008863#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00008864 return result;
8865}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00008866#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008867
Larry Hastings2f936352014-08-05 14:04:04 +10008868
Guido van Rossumad0ee831995-03-01 10:34:45 +00008869#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10008870/*[clinic input]
8871os.getuid
8872
8873Return the current process's user id.
8874[clinic start generated code]*/
8875
8876PyDoc_STRVAR(os_getuid__doc__,
8877"getuid($module, /)\n"
8878"--\n"
8879"\n"
8880"Return the current process\'s user id.");
8881
8882#define OS_GETUID_METHODDEF \
8883 {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008884
Barry Warsaw53699e91996-12-10 23:23:01 +00008885static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008886os_getuid_impl(PyModuleDef *module);
8887
8888static PyObject *
8889os_getuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
8890{
8891 return os_getuid_impl(module);
8892}
8893
8894static PyObject *
8895os_getuid_impl(PyModuleDef *module)
8896/*[clinic end generated code: output=77e0dcf2e37d1e89 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00008897{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008898 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00008899}
Larry Hastings2f936352014-08-05 14:04:04 +10008900#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00008901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008902
Brian Curtineb24d742010-04-12 17:16:38 +00008903#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008904#define HAVE_KILL
8905#endif /* MS_WINDOWS */
8906
8907#ifdef HAVE_KILL
8908/*[clinic input]
8909os.kill
8910
8911 pid: pid_t
8912 signal: Py_ssize_t
8913 /
8914
8915Kill a process with a signal.
8916[clinic start generated code]*/
8917
8918PyDoc_STRVAR(os_kill__doc__,
8919"kill($module, pid, signal, /)\n"
8920"--\n"
8921"\n"
8922"Kill a process with a signal.");
8923
8924#define OS_KILL_METHODDEF \
8925 {"kill", (PyCFunction)os_kill, METH_VARARGS, os_kill__doc__},
Brian Curtineb24d742010-04-12 17:16:38 +00008926
8927static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10008928os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal);
8929
8930static PyObject *
8931os_kill(PyModuleDef *module, PyObject *args)
8932{
8933 PyObject *return_value = NULL;
8934 pid_t pid;
8935 Py_ssize_t signal;
8936
8937 if (!PyArg_ParseTuple(args,
8938 "" _Py_PARSE_PID "n:kill",
8939 &pid, &signal))
8940 goto exit;
8941 return_value = os_kill_impl(module, pid, signal);
8942
8943exit:
8944 return return_value;
8945}
8946
8947static PyObject *
8948os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
8949/*[clinic end generated code: output=2f5c77920ed575e6 input=61a36b86ca275ab9]*/
8950#ifndef MS_WINDOWS
8951{
8952 if (kill(pid, (int)signal) == -1)
8953 return posix_error();
8954 Py_RETURN_NONE;
8955}
8956#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00008957{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00008958 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10008959 DWORD sig = (DWORD)signal;
8960 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00008962
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 /* Console processes which share a common console can be sent CTRL+C or
8964 CTRL+BREAK events, provided they handle said events. */
8965 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01008966 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 err = GetLastError();
8968 PyErr_SetFromWindowsErr(err);
8969 }
8970 else
8971 Py_RETURN_NONE;
8972 }
Brian Curtineb24d742010-04-12 17:16:38 +00008973
Victor Stinner8c62be82010-05-06 00:08:46 +00008974 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
8975 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01008976 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 if (handle == NULL) {
8978 err = GetLastError();
8979 return PyErr_SetFromWindowsErr(err);
8980 }
Brian Curtineb24d742010-04-12 17:16:38 +00008981
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 if (TerminateProcess(handle, sig) == 0) {
8983 err = GetLastError();
8984 result = PyErr_SetFromWindowsErr(err);
8985 } else {
8986 Py_INCREF(Py_None);
8987 result = Py_None;
8988 }
Brian Curtineb24d742010-04-12 17:16:38 +00008989
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 CloseHandle(handle);
8991 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00008992}
Larry Hastings2f936352014-08-05 14:04:04 +10008993#endif /* !MS_WINDOWS */
8994#endif /* HAVE_KILL */
8995
8996
8997#ifdef HAVE_KILLPG
8998/*[clinic input]
8999os.killpg
9000
9001 pgid: pid_t
9002 signal: int
9003 /
9004
9005Kill a process group with a signal.
9006[clinic start generated code]*/
9007
9008PyDoc_STRVAR(os_killpg__doc__,
9009"killpg($module, pgid, signal, /)\n"
9010"--\n"
9011"\n"
9012"Kill a process group with a signal.");
9013
9014#define OS_KILLPG_METHODDEF \
9015 {"killpg", (PyCFunction)os_killpg, METH_VARARGS, os_killpg__doc__},
9016
9017static PyObject *
9018os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal);
9019
9020static PyObject *
9021os_killpg(PyModuleDef *module, PyObject *args)
9022{
9023 PyObject *return_value = NULL;
9024 pid_t pgid;
9025 int signal;
9026
9027 if (!PyArg_ParseTuple(args,
9028 "" _Py_PARSE_PID "i:killpg",
9029 &pgid, &signal))
9030 goto exit;
9031 return_value = os_killpg_impl(module, pgid, signal);
9032
9033exit:
9034 return return_value;
9035}
9036
9037static PyObject *
9038os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
9039/*[clinic end generated code: output=0e05215d1c007e01 input=38b5449eb8faec19]*/
9040{
9041 /* XXX some man pages make the `pgid` parameter an int, others
9042 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
9043 take the same type. Moreover, pid_t is always at least as wide as
9044 int (else compilation of this module fails), which is safe. */
9045 if (killpg(pgid, signal) == -1)
9046 return posix_error();
9047 Py_RETURN_NONE;
9048}
9049#endif /* HAVE_KILLPG */
9050
Brian Curtineb24d742010-04-12 17:16:38 +00009051
Guido van Rossumc0125471996-06-28 18:55:32 +00009052#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00009053#ifdef HAVE_SYS_LOCK_H
9054#include <sys/lock.h>
9055#endif
9056
Larry Hastings2f936352014-08-05 14:04:04 +10009057/*[clinic input]
9058os.plock
9059 op: int
9060 /
9061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009062Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10009063[clinic start generated code]*/
9064
9065PyDoc_STRVAR(os_plock__doc__,
9066"plock($module, op, /)\n"
9067"--\n"
9068"\n"
9069"Lock program segments into memory.\");");
9070
9071#define OS_PLOCK_METHODDEF \
9072 {"plock", (PyCFunction)os_plock, METH_VARARGS, os_plock__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009073
Barry Warsaw53699e91996-12-10 23:23:01 +00009074static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009075os_plock_impl(PyModuleDef *module, int op);
9076
9077static PyObject *
9078os_plock(PyModuleDef *module, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00009079{
Larry Hastings2f936352014-08-05 14:04:04 +10009080 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 int op;
Larry Hastings2f936352014-08-05 14:04:04 +10009082
9083 if (!PyArg_ParseTuple(args,
9084 "i:plock",
9085 &op))
9086 goto exit;
9087 return_value = os_plock_impl(module, op);
9088
9089exit:
9090 return return_value;
9091}
9092
9093static PyObject *
9094os_plock_impl(PyModuleDef *module, int op)
9095/*[clinic end generated code: output=2744fe4b6e5f4dbc input=e6e5e348e1525f60]*/
9096{
Victor Stinner8c62be82010-05-06 00:08:46 +00009097 if (plock(op) == -1)
9098 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009099 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00009100}
Larry Hastings2f936352014-08-05 14:04:04 +10009101#endif /* HAVE_PLOCK */
9102
Guido van Rossumc0125471996-06-28 18:55:32 +00009103
Guido van Rossumb6775db1994-08-01 11:34:53 +00009104#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10009105/*[clinic input]
9106os.setuid
9107
9108 uid: uid_t
9109 /
9110
9111Set the current process's user id.
9112[clinic start generated code]*/
9113
9114PyDoc_STRVAR(os_setuid__doc__,
9115"setuid($module, uid, /)\n"
9116"--\n"
9117"\n"
9118"Set the current process\'s user id.");
9119
9120#define OS_SETUID_METHODDEF \
9121 {"setuid", (PyCFunction)os_setuid, METH_VARARGS, os_setuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009122
Barry Warsaw53699e91996-12-10 23:23:01 +00009123static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009124os_setuid_impl(PyModuleDef *module, uid_t uid);
9125
9126static PyObject *
9127os_setuid(PyModuleDef *module, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009128{
Larry Hastings2f936352014-08-05 14:04:04 +10009129 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 uid_t uid;
Larry Hastings2f936352014-08-05 14:04:04 +10009131
9132 if (!PyArg_ParseTuple(args,
9133 "O&:setuid",
9134 _Py_Uid_Converter, &uid))
9135 goto exit;
9136 return_value = os_setuid_impl(module, uid);
9137
9138exit:
9139 return return_value;
9140}
9141
9142static PyObject *
9143os_setuid_impl(PyModuleDef *module, uid_t uid)
9144/*[clinic end generated code: output=aea344bc22ccf400 input=c921a3285aa22256]*/
9145{
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 if (setuid(uid) < 0)
9147 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009148 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009149}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009150#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009152
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009153#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10009154/*[clinic input]
9155os.seteuid
9156
9157 euid: uid_t
9158 /
9159
9160Set the current process's effective user id.
9161[clinic start generated code]*/
9162
9163PyDoc_STRVAR(os_seteuid__doc__,
9164"seteuid($module, euid, /)\n"
9165"--\n"
9166"\n"
9167"Set the current process\'s effective user id.");
9168
9169#define OS_SETEUID_METHODDEF \
9170 {"seteuid", (PyCFunction)os_seteuid, METH_VARARGS, os_seteuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009171
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009172static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009173os_seteuid_impl(PyModuleDef *module, uid_t euid);
9174
9175static PyObject *
9176os_seteuid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009177{
Larry Hastings2f936352014-08-05 14:04:04 +10009178 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 uid_t euid;
Larry Hastings2f936352014-08-05 14:04:04 +10009180
9181 if (!PyArg_ParseTuple(args,
9182 "O&:seteuid",
9183 _Py_Uid_Converter, &euid))
9184 goto exit;
9185 return_value = os_seteuid_impl(module, euid);
9186
9187exit:
9188 return return_value;
9189}
9190
9191static PyObject *
9192os_seteuid_impl(PyModuleDef *module, uid_t euid)
9193/*[clinic end generated code: output=6e824cce4f3b8a5d input=ba93d927e4781aa9]*/
9194{
9195 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009197 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009198}
9199#endif /* HAVE_SETEUID */
9200
Larry Hastings2f936352014-08-05 14:04:04 +10009201
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009202#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10009203/*[clinic input]
9204os.setegid
9205
9206 egid: gid_t
9207 /
9208
9209Set the current process's effective group id.
9210[clinic start generated code]*/
9211
9212PyDoc_STRVAR(os_setegid__doc__,
9213"setegid($module, egid, /)\n"
9214"--\n"
9215"\n"
9216"Set the current process\'s effective group id.");
9217
9218#define OS_SETEGID_METHODDEF \
9219 {"setegid", (PyCFunction)os_setegid, METH_VARARGS, os_setegid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009220
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009221static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009222os_setegid_impl(PyModuleDef *module, gid_t egid);
9223
9224static PyObject *
9225os_setegid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009226{
Larry Hastings2f936352014-08-05 14:04:04 +10009227 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 gid_t egid;
Larry Hastings2f936352014-08-05 14:04:04 +10009229
9230 if (!PyArg_ParseTuple(args,
9231 "O&:setegid",
9232 _Py_Gid_Converter, &egid))
9233 goto exit;
9234 return_value = os_setegid_impl(module, egid);
9235
9236exit:
9237 return return_value;
9238}
9239
9240static PyObject *
9241os_setegid_impl(PyModuleDef *module, gid_t egid)
9242/*[clinic end generated code: output=80a32263a4d56a9c input=4080526d0ccd6ce3]*/
9243{
9244 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009246 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009247}
9248#endif /* HAVE_SETEGID */
9249
Larry Hastings2f936352014-08-05 14:04:04 +10009250
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009251#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10009252/*[clinic input]
9253os.setreuid
9254
9255 ruid: uid_t
9256 euid: uid_t
9257 /
9258
9259Set the current process's real and effective user ids.
9260[clinic start generated code]*/
9261
9262PyDoc_STRVAR(os_setreuid__doc__,
9263"setreuid($module, ruid, euid, /)\n"
9264"--\n"
9265"\n"
9266"Set the current process\'s real and effective user ids.");
9267
9268#define OS_SETREUID_METHODDEF \
9269 {"setreuid", (PyCFunction)os_setreuid, METH_VARARGS, os_setreuid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009270
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009271static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009272os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid);
9273
9274static PyObject *
9275os_setreuid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009276{
Larry Hastings2f936352014-08-05 14:04:04 +10009277 PyObject *return_value = NULL;
9278 uid_t ruid;
9279 uid_t euid;
9280
9281 if (!PyArg_ParseTuple(args,
9282 "O&O&:setreuid",
9283 _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid))
9284 goto exit;
9285 return_value = os_setreuid_impl(module, ruid, euid);
9286
9287exit:
9288 return return_value;
9289}
9290
9291static PyObject *
9292os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
9293/*[clinic end generated code: output=d7f226f943dad739 input=0ca8978de663880c]*/
9294{
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 if (setreuid(ruid, euid) < 0) {
9296 return posix_error();
9297 } else {
9298 Py_INCREF(Py_None);
9299 return Py_None;
9300 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009301}
9302#endif /* HAVE_SETREUID */
9303
Larry Hastings2f936352014-08-05 14:04:04 +10009304
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009305#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10009306/*[clinic input]
9307os.setregid
9308
9309 rgid: gid_t
9310 egid: gid_t
9311 /
9312
9313Set the current process's real and effective group ids.
9314[clinic start generated code]*/
9315
9316PyDoc_STRVAR(os_setregid__doc__,
9317"setregid($module, rgid, egid, /)\n"
9318"--\n"
9319"\n"
9320"Set the current process\'s real and effective group ids.");
9321
9322#define OS_SETREGID_METHODDEF \
9323 {"setregid", (PyCFunction)os_setregid, METH_VARARGS, os_setregid__doc__},
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009324
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009325static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009326os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid);
9327
9328static PyObject *
9329os_setregid(PyModuleDef *module, PyObject *args)
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009330{
Larry Hastings2f936352014-08-05 14:04:04 +10009331 PyObject *return_value = NULL;
9332 gid_t rgid;
9333 gid_t egid;
9334
9335 if (!PyArg_ParseTuple(args,
9336 "O&O&:setregid",
9337 _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid))
9338 goto exit;
9339 return_value = os_setregid_impl(module, rgid, egid);
9340
9341exit:
9342 return return_value;
9343}
9344
9345static PyObject *
9346os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
9347/*[clinic end generated code: output=a82d9ab70f8e6562 input=c59499f72846db78]*/
9348{
9349 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009351 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00009352}
9353#endif /* HAVE_SETREGID */
9354
Larry Hastings2f936352014-08-05 14:04:04 +10009355
Guido van Rossumb6775db1994-08-01 11:34:53 +00009356#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10009357/*[clinic input]
9358os.setgid
9359 gid: gid_t
9360 /
9361
9362Set the current process's group id.
9363[clinic start generated code]*/
9364
9365PyDoc_STRVAR(os_setgid__doc__,
9366"setgid($module, gid, /)\n"
9367"--\n"
9368"\n"
9369"Set the current process\'s group id.");
9370
9371#define OS_SETGID_METHODDEF \
9372 {"setgid", (PyCFunction)os_setgid, METH_VARARGS, os_setgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009373
Barry Warsaw53699e91996-12-10 23:23:01 +00009374static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009375os_setgid_impl(PyModuleDef *module, gid_t gid);
9376
9377static PyObject *
9378os_setgid(PyModuleDef *module, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009379{
Larry Hastings2f936352014-08-05 14:04:04 +10009380 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 gid_t gid;
Larry Hastings2f936352014-08-05 14:04:04 +10009382
9383 if (!PyArg_ParseTuple(args,
9384 "O&:setgid",
9385 _Py_Gid_Converter, &gid))
9386 goto exit;
9387 return_value = os_setgid_impl(module, gid);
9388
9389exit:
9390 return return_value;
9391}
9392
9393static PyObject *
9394os_setgid_impl(PyModuleDef *module, gid_t gid)
9395/*[clinic end generated code: output=08287886db435f23 input=27d30c4059045dc6]*/
9396{
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 if (setgid(gid) < 0)
9398 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009399 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009400}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009401#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00009402
Larry Hastings2f936352014-08-05 14:04:04 +10009403
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009404#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10009405/*[clinic input]
9406os.setgroups
9407
9408 groups: object
9409 /
9410
9411Set the groups of the current process to list.
9412[clinic start generated code]*/
9413
9414PyDoc_STRVAR(os_setgroups__doc__,
9415"setgroups($module, groups, /)\n"
9416"--\n"
9417"\n"
9418"Set the groups of the current process to list.");
9419
9420#define OS_SETGROUPS_METHODDEF \
9421 {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009422
9423static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009424os_setgroups(PyModuleDef *module, PyObject *groups)
9425/*[clinic end generated code: output=0b8de65d5b3cda94 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009426{
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 int i, len;
9428 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00009429
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 if (!PySequence_Check(groups)) {
9431 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
9432 return NULL;
9433 }
9434 len = PySequence_Size(groups);
9435 if (len > MAX_GROUPS) {
9436 PyErr_SetString(PyExc_ValueError, "too many groups");
9437 return NULL;
9438 }
9439 for(i = 0; i < len; i++) {
9440 PyObject *elem;
9441 elem = PySequence_GetItem(groups, i);
9442 if (!elem)
9443 return NULL;
9444 if (!PyLong_Check(elem)) {
9445 PyErr_SetString(PyExc_TypeError,
9446 "groups must be integers");
9447 Py_DECREF(elem);
9448 return NULL;
9449 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009450 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 Py_DECREF(elem);
9452 return NULL;
9453 }
9454 }
9455 Py_DECREF(elem);
9456 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009457
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 if (setgroups(len, grouplist) < 0)
9459 return posix_error();
9460 Py_INCREF(Py_None);
9461 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009462}
9463#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009464
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009465#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
9466static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01009467wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009468{
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 PyObject *result;
9470 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02009471 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009472
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 if (pid == -1)
9474 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009475
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 if (struct_rusage == NULL) {
9477 PyObject *m = PyImport_ImportModuleNoBlock("resource");
9478 if (m == NULL)
9479 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02009480 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 Py_DECREF(m);
9482 if (struct_rusage == NULL)
9483 return NULL;
9484 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009485
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
9487 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
9488 if (!result)
9489 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009490
9491#ifndef doubletime
9492#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
9493#endif
9494
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009496 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009498 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009499#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
9501 SET_INT(result, 2, ru->ru_maxrss);
9502 SET_INT(result, 3, ru->ru_ixrss);
9503 SET_INT(result, 4, ru->ru_idrss);
9504 SET_INT(result, 5, ru->ru_isrss);
9505 SET_INT(result, 6, ru->ru_minflt);
9506 SET_INT(result, 7, ru->ru_majflt);
9507 SET_INT(result, 8, ru->ru_nswap);
9508 SET_INT(result, 9, ru->ru_inblock);
9509 SET_INT(result, 10, ru->ru_oublock);
9510 SET_INT(result, 11, ru->ru_msgsnd);
9511 SET_INT(result, 12, ru->ru_msgrcv);
9512 SET_INT(result, 13, ru->ru_nsignals);
9513 SET_INT(result, 14, ru->ru_nvcsw);
9514 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009515#undef SET_INT
9516
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 if (PyErr_Occurred()) {
9518 Py_DECREF(result);
9519 return NULL;
9520 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009521
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009523}
9524#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
9525
Larry Hastings2f936352014-08-05 14:04:04 +10009526
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009527#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10009528/*[clinic input]
9529os.wait3
9530
9531 options: int
9532Wait for completion of a child process.
9533
9534Returns a tuple of information about the child process:
9535 (pid, status, rusage)
9536[clinic start generated code]*/
9537
9538PyDoc_STRVAR(os_wait3__doc__,
9539"wait3($module, /, options)\n"
9540"--\n"
9541"\n"
9542"Wait for completion of a child process.\n"
9543"\n"
9544"Returns a tuple of information about the child process:\n"
9545" (pid, status, rusage)");
9546
9547#define OS_WAIT3_METHODDEF \
9548 {"wait3", (PyCFunction)os_wait3, METH_VARARGS|METH_KEYWORDS, os_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009549
9550static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009551os_wait3_impl(PyModuleDef *module, int options);
9552
9553static PyObject *
9554os_wait3(PyModuleDef *module, PyObject *args, PyObject *kwargs)
9555{
9556 PyObject *return_value = NULL;
9557 static char *_keywords[] = {"options", NULL};
9558 int options;
9559
9560 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
9561 "i:wait3", _keywords,
9562 &options))
9563 goto exit;
9564 return_value = os_wait3_impl(module, options);
9565
9566exit:
9567 return return_value;
9568}
9569
9570static PyObject *
9571os_wait3_impl(PyModuleDef *module, int options)
9572/*[clinic end generated code: output=1f2a63b6a93cbb57 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009573{
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 struct rusage ru;
9576 WAIT_TYPE status;
9577 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009578
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 Py_BEGIN_ALLOW_THREADS
9580 pid = wait3(&status, options, &ru);
9581 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009582
Victor Stinner4195b5c2012-02-08 23:03:19 +01009583 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009584}
9585#endif /* HAVE_WAIT3 */
9586
Larry Hastings2f936352014-08-05 14:04:04 +10009587
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009588#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10009589/*[clinic input]
9590
9591os.wait4
9592
9593 pid: pid_t
9594 options: int
9595
9596Wait for completion of a specific child process.
9597
9598Returns a tuple of information about the child process:
9599 (pid, status, rusage)
9600[clinic start generated code]*/
9601
9602PyDoc_STRVAR(os_wait4__doc__,
9603"wait4($module, /, pid, options)\n"
9604"--\n"
9605"\n"
9606"Wait for completion of a specific child process.\n"
9607"\n"
9608"Returns a tuple of information about the child process:\n"
9609" (pid, status, rusage)");
9610
9611#define OS_WAIT4_METHODDEF \
9612 {"wait4", (PyCFunction)os_wait4, METH_VARARGS|METH_KEYWORDS, os_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009613
9614static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009615os_wait4_impl(PyModuleDef *module, pid_t pid, int options);
9616
9617static PyObject *
9618os_wait4(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009619{
Larry Hastings2f936352014-08-05 14:04:04 +10009620 PyObject *return_value = NULL;
9621 static char *_keywords[] = {"pid", "options", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 pid_t pid;
9623 int options;
Larry Hastings2f936352014-08-05 14:04:04 +10009624
9625 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
9626 "" _Py_PARSE_PID "i:wait4", _keywords,
9627 &pid, &options))
9628 goto exit;
9629 return_value = os_wait4_impl(module, pid, options);
9630
9631exit:
9632 return return_value;
9633}
9634
9635static PyObject *
9636os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
9637/*[clinic end generated code: output=20dfb05289d37dc6 input=d11deed0750600ba]*/
9638{
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 struct rusage ru;
9640 WAIT_TYPE status;
9641 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009642
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 Py_BEGIN_ALLOW_THREADS
9644 pid = wait4(pid, &status, options, &ru);
9645 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009646
Victor Stinner4195b5c2012-02-08 23:03:19 +01009647 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009648}
9649#endif /* HAVE_WAIT4 */
9650
Larry Hastings2f936352014-08-05 14:04:04 +10009651
Ross Lagerwall7807c352011-03-17 20:20:30 +02009652#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10009653/*[clinic input]
9654os.waitid
9655
9656 idtype: idtype_t
9657 Must be one of be P_PID, P_PGID or P_ALL.
9658 id: id_t
9659 The id to wait on.
9660 options: int
9661 Constructed from the ORing of one or more of WEXITED, WSTOPPED
9662 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
9663 /
9664
9665Returns the result of waiting for a process or processes.
9666
9667Returns either waitid_result or None if WNOHANG is specified and there are
9668no children in a waitable state.
9669[clinic start generated code]*/
9670
9671PyDoc_STRVAR(os_waitid__doc__,
9672"waitid($module, idtype, id, options, /)\n"
9673"--\n"
9674"\n"
9675"Returns the result of waiting for a process or processes.\n"
9676"\n"
9677" idtype\n"
9678" Must be one of be P_PID, P_PGID or P_ALL.\n"
9679" id\n"
9680" The id to wait on.\n"
9681" options\n"
9682" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n"
9683" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n"
9684"\n"
9685"Returns either waitid_result or None if WNOHANG is specified and there are\n"
9686"no children in a waitable state.");
9687
9688#define OS_WAITID_METHODDEF \
9689 {"waitid", (PyCFunction)os_waitid, METH_VARARGS, os_waitid__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +02009690
9691static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009692os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options);
9693
9694static PyObject *
9695os_waitid(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009696{
Larry Hastings2f936352014-08-05 14:04:04 +10009697 PyObject *return_value = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009698 idtype_t idtype;
9699 id_t id;
Larry Hastings2f936352014-08-05 14:04:04 +10009700 int options;
9701
9702 if (!PyArg_ParseTuple(args,
9703 "i" _Py_PARSE_PID "i:waitid",
9704 &idtype, &id, &options))
9705 goto exit;
9706 return_value = os_waitid_impl(module, idtype, id, options);
9707
9708exit:
9709 return return_value;
9710}
9711
9712static PyObject *
9713os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
9714/*[clinic end generated code: output=fb44bf97f01021b2 input=d8e7f76e052b7920]*/
9715{
9716 PyObject *result;
9717 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009718 siginfo_t si;
9719 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009720
Ross Lagerwall7807c352011-03-17 20:20:30 +02009721 Py_BEGIN_ALLOW_THREADS
9722 res = waitid(idtype, id, &si, options);
9723 Py_END_ALLOW_THREADS
9724 if (res == -1)
9725 return posix_error();
9726
9727 if (si.si_pid == 0)
9728 Py_RETURN_NONE;
9729
9730 result = PyStructSequence_New(&WaitidResultType);
9731 if (!result)
9732 return NULL;
9733
9734 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009735 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009736 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
9737 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
9738 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
9739 if (PyErr_Occurred()) {
9740 Py_DECREF(result);
9741 return NULL;
9742 }
9743
9744 return result;
9745}
Larry Hastings2f936352014-08-05 14:04:04 +10009746#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009747
Larry Hastings2f936352014-08-05 14:04:04 +10009748
9749#if defined(HAVE_WAITPID)
9750/*[clinic input]
9751os.waitpid
9752 pid: pid_t
9753 options: int
9754 /
9755
9756Wait for completion of a given child process.
9757
9758Returns a tuple of information regarding the child process:
9759 (pid, status)
9760
9761The options argument is ignored on Windows.
9762[clinic start generated code]*/
9763
9764PyDoc_STRVAR(os_waitpid__doc__,
9765"waitpid($module, pid, options, /)\n"
9766"--\n"
9767"\n"
9768"Wait for completion of a given child process.\n"
9769"\n"
9770"Returns a tuple of information regarding the child process:\n"
9771" (pid, status)\n"
9772"\n"
9773"The options argument is ignored on Windows.");
9774
9775#define OS_WAITPID_METHODDEF \
9776 {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009777
Barry Warsaw53699e91996-12-10 23:23:01 +00009778static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009779os_waitpid_impl(PyModuleDef *module, pid_t pid, int options);
9780
9781static PyObject *
9782os_waitpid(PyModuleDef *module, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00009783{
Larry Hastings2f936352014-08-05 14:04:04 +10009784 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 pid_t pid;
9786 int options;
Larry Hastings2f936352014-08-05 14:04:04 +10009787
9788 if (!PyArg_ParseTuple(args,
9789 "" _Py_PARSE_PID "i:waitpid",
9790 &pid, &options))
9791 goto exit;
9792 return_value = os_waitpid_impl(module, pid, options);
9793
9794exit:
9795 return return_value;
9796}
9797
9798static PyObject *
9799os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
9800/*[clinic end generated code: output=095a6b00af70b7ac input=0bf1666b8758fda3]*/
9801{
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 WAIT_TYPE status;
9803 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009804
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 Py_BEGIN_ALLOW_THREADS
9806 pid = waitpid(pid, &status, options);
9807 Py_END_ALLOW_THREADS
9808 if (pid == -1)
9809 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009810
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00009812}
Tim Petersab034fa2002-02-01 11:27:43 +00009813#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00009814/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10009815/*[clinic input]
9816os.waitpid
9817 pid: Py_intptr_t
9818 options: int
9819 /
9820
9821Wait for completion of a given process.
9822
9823Returns a tuple of information regarding the process:
9824 (pid, status << 8)
9825
9826The options argument is ignored on Windows.
9827[clinic start generated code]*/
9828
9829PyDoc_STRVAR(os_waitpid__doc__,
9830"waitpid($module, pid, options, /)\n"
9831"--\n"
9832"\n"
9833"Wait for completion of a given process.\n"
9834"\n"
9835"Returns a tuple of information regarding the process:\n"
9836" (pid, status << 8)\n"
9837"\n"
9838"The options argument is ignored on Windows.");
9839
9840#define OS_WAITPID_METHODDEF \
9841 {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__},
Tim Petersab034fa2002-02-01 11:27:43 +00009842
9843static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009844os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options);
Tim Petersab034fa2002-02-01 11:27:43 +00009845
Larry Hastings2f936352014-08-05 14:04:04 +10009846static PyObject *
9847os_waitpid(PyModuleDef *module, PyObject *args)
9848{
9849 PyObject *return_value = NULL;
9850 Py_intptr_t pid;
9851 int options;
9852
9853 if (!PyArg_ParseTuple(args,
9854 "" _Py_PARSE_INTPTR "i:waitpid",
9855 &pid, &options))
9856 goto exit;
9857 return_value = os_waitpid_impl(module, pid, options);
9858
9859exit:
9860 return return_value;
9861}
9862
9863static PyObject *
9864os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
9865/*[clinic end generated code: output=c20b95b15ad44a3a input=444c8f51cca5b862]*/
9866{
9867 int status;
9868
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 Py_BEGIN_ALLOW_THREADS
9870 pid = _cwait(&status, pid, options);
9871 Py_END_ALLOW_THREADS
9872 if (pid == -1)
9873 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009874
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01009876 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00009877}
Larry Hastings2f936352014-08-05 14:04:04 +10009878#endif
9879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009880
Guido van Rossumad0ee831995-03-01 10:34:45 +00009881#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10009882/*[clinic input]
9883os.wait
9884
9885Wait for completion of a child process.
9886
9887Returns a tuple of information about the child process:
9888 (pid, status)
9889[clinic start generated code]*/
9890
9891PyDoc_STRVAR(os_wait__doc__,
9892"wait($module, /)\n"
9893"--\n"
9894"\n"
9895"Wait for completion of a child process.\n"
9896"\n"
9897"Returns a tuple of information about the child process:\n"
9898" (pid, status)");
9899
9900#define OS_WAIT_METHODDEF \
9901 {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009902
Barry Warsaw53699e91996-12-10 23:23:01 +00009903static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10009904os_wait_impl(PyModuleDef *module);
9905
9906static PyObject *
9907os_wait(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
9908{
9909 return os_wait_impl(module);
9910}
9911
9912static PyObject *
9913os_wait_impl(PyModuleDef *module)
9914/*[clinic end generated code: output=2a83a9d164e7e6a8 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00009915{
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 pid_t pid;
9917 WAIT_TYPE status;
9918 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00009919
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 Py_BEGIN_ALLOW_THREADS
9921 pid = wait(&status);
9922 Py_END_ALLOW_THREADS
9923 if (pid == -1)
9924 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009925
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00009927}
Larry Hastings2f936352014-08-05 14:04:04 +10009928#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00009929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009930
Larry Hastings9cf065c2012-06-22 16:30:09 -07009931#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
9932PyDoc_STRVAR(readlink__doc__,
9933"readlink(path, *, dir_fd=None) -> path\n\n\
9934Return a string representing the path to which the symbolic link points.\n\
9935\n\
9936If dir_fd is not None, it should be a file descriptor open to a directory,\n\
9937 and path should be relative; path will then be relative to that directory.\n\
9938dir_fd may not be implemented on your platform.\n\
9939 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009940#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009941
Guido van Rossumb6775db1994-08-01 11:34:53 +00009942#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009943
Larry Hastings2f936352014-08-05 14:04:04 +10009944/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00009945static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009946posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009947{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009948 path_t path;
9949 int dir_fd = DEFAULT_DIR_FD;
9950 char buffer[MAXPATHLEN];
9951 ssize_t length;
9952 PyObject *return_value = NULL;
9953 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00009954
Larry Hastings9cf065c2012-06-22 16:30:09 -07009955 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009956 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009957 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
9958 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10009959 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00009961
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009963#ifdef HAVE_READLINKAT
9964 if (dir_fd != DEFAULT_DIR_FD)
9965 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00009966 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009967#endif
9968 length = readlink(path.narrow, buffer, sizeof(buffer));
9969 Py_END_ALLOW_THREADS
9970
9971 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01009972 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009973 goto exit;
9974 }
9975
9976 if (PyUnicode_Check(path.object))
9977 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
9978 else
9979 return_value = PyBytes_FromStringAndSize(buffer, length);
9980exit:
9981 path_cleanup(&path);
9982 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009983}
Larry Hastings9cf065c2012-06-22 16:30:09 -07009984
Guido van Rossumb6775db1994-08-01 11:34:53 +00009985#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009986
Larry Hastings2f936352014-08-05 14:04:04 +10009987#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
9988
9989static PyObject *
9990win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
9991{
9992 wchar_t *path;
9993 DWORD n_bytes_returned;
9994 DWORD io_result;
9995 PyObject *po, *result;
9996 int dir_fd;
9997 HANDLE reparse_point_handle;
9998
9999 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
10000 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
10001 wchar_t *print_name;
10002
10003 static char *keywords[] = {"path", "dir_fd", NULL};
10004
10005 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
10006 &po,
10007 dir_fd_unavailable, &dir_fd
10008 ))
10009 return NULL;
10010
10011 path = PyUnicode_AsUnicode(po);
10012 if (path == NULL)
10013 return NULL;
10014
10015 /* First get a handle to the reparse point */
10016 Py_BEGIN_ALLOW_THREADS
10017 reparse_point_handle = CreateFileW(
10018 path,
10019 0,
10020 0,
10021 0,
10022 OPEN_EXISTING,
10023 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
10024 0);
10025 Py_END_ALLOW_THREADS
10026
10027 if (reparse_point_handle==INVALID_HANDLE_VALUE)
10028 return win32_error_object("readlink", po);
10029
10030 Py_BEGIN_ALLOW_THREADS
10031 /* New call DeviceIoControl to read the reparse point */
10032 io_result = DeviceIoControl(
10033 reparse_point_handle,
10034 FSCTL_GET_REPARSE_POINT,
10035 0, 0, /* in buffer */
10036 target_buffer, sizeof(target_buffer),
10037 &n_bytes_returned,
10038 0 /* we're not using OVERLAPPED_IO */
10039 );
10040 CloseHandle(reparse_point_handle);
10041 Py_END_ALLOW_THREADS
10042
10043 if (io_result==0)
10044 return win32_error_object("readlink", po);
10045
10046 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
10047 {
10048 PyErr_SetString(PyExc_ValueError,
10049 "not a symbolic link");
10050 return NULL;
10051 }
10052 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
10053 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
10054
10055 result = PyUnicode_FromWideChar(print_name,
10056 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
10057 return result;
10058}
10059
10060#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
10061
10062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010063
Larry Hastings9cf065c2012-06-22 16:30:09 -070010064#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010065
10066#if defined(MS_WINDOWS)
10067
10068/* Grab CreateSymbolicLinkW dynamically from kernel32 */
10069static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
10070static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +020010071
Larry Hastings9cf065c2012-06-22 16:30:09 -070010072static int
Victor Stinner31b3b922013-06-05 01:49:17 +020010073check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010074{
10075 HINSTANCE hKernel32;
10076 /* only recheck */
10077 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
10078 return 1;
10079 hKernel32 = GetModuleHandleW(L"KERNEL32");
10080 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
10081 "CreateSymbolicLinkW");
10082 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
10083 "CreateSymbolicLinkA");
10084 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
10085}
10086
Victor Stinner31b3b922013-06-05 01:49:17 +020010087/* Remove the last portion of the path */
10088static void
10089_dirnameW(WCHAR *path)
10090{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010091 WCHAR *ptr;
10092
10093 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +020010094 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +020010095 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -040010096 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010097 }
10098 *ptr = 0;
10099}
10100
Victor Stinner31b3b922013-06-05 01:49:17 +020010101/* Remove the last portion of the path */
10102static void
10103_dirnameA(char *path)
10104{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010105 char *ptr;
10106
10107 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +020010108 for(ptr = path + strlen(path); ptr != path; ptr--) {
10109 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -040010110 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010111 }
10112 *ptr = 0;
10113}
10114
Victor Stinner31b3b922013-06-05 01:49:17 +020010115/* Is this path absolute? */
10116static int
10117_is_absW(const WCHAR *path)
10118{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010119 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
10120
10121}
10122
Victor Stinner31b3b922013-06-05 01:49:17 +020010123/* Is this path absolute? */
10124static int
10125_is_absA(const char *path)
10126{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010127 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
10128
10129}
10130
Victor Stinner31b3b922013-06-05 01:49:17 +020010131/* join root and rest with a backslash */
10132static void
10133_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
10134{
Victor Stinnere7e7eba2013-06-05 00:35:54 +020010135 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010136
Victor Stinner31b3b922013-06-05 01:49:17 +020010137 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -040010138 wcscpy(dest_path, rest);
10139 return;
10140 }
10141
10142 root_len = wcslen(root);
10143
10144 wcscpy(dest_path, root);
10145 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +020010146 dest_path[root_len] = L'\\';
10147 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010148 }
10149 wcscpy(dest_path+root_len, rest);
10150}
10151
Victor Stinner31b3b922013-06-05 01:49:17 +020010152/* join root and rest with a backslash */
10153static void
10154_joinA(char *dest_path, const char *root, const char *rest)
10155{
Victor Stinnere7e7eba2013-06-05 00:35:54 +020010156 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010157
Victor Stinner31b3b922013-06-05 01:49:17 +020010158 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -040010159 strcpy(dest_path, rest);
10160 return;
10161 }
10162
10163 root_len = strlen(root);
10164
10165 strcpy(dest_path, root);
10166 if(root_len) {
10167 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +020010168 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -040010169 }
10170 strcpy(dest_path+root_len, rest);
10171}
10172
Victor Stinner31b3b922013-06-05 01:49:17 +020010173/* Return True if the path at src relative to dest is a directory */
10174static int
10175_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -040010176{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010177 WIN32_FILE_ATTRIBUTE_DATA src_info;
10178 WCHAR dest_parent[MAX_PATH];
10179 WCHAR src_resolved[MAX_PATH] = L"";
10180
10181 /* dest_parent = os.path.dirname(dest) */
10182 wcscpy(dest_parent, dest);
10183 _dirnameW(dest_parent);
10184 /* src_resolved = os.path.join(dest_parent, src) */
10185 _joinW(src_resolved, dest_parent, src);
10186 return (
10187 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
10188 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
10189 );
10190}
10191
Victor Stinner31b3b922013-06-05 01:49:17 +020010192/* Return True if the path at src relative to dest is a directory */
10193static int
10194_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -040010195{
Jason R. Coombs3a092862013-05-27 23:21:28 -040010196 WIN32_FILE_ATTRIBUTE_DATA src_info;
10197 char dest_parent[MAX_PATH];
10198 char src_resolved[MAX_PATH] = "";
10199
10200 /* dest_parent = os.path.dirname(dest) */
10201 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +020010202 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010203 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +020010204 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010205 return (
10206 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
10207 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
10208 );
10209}
Larry Hastings9cf065c2012-06-22 16:30:09 -070010210#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010211
Larry Hastings2f936352014-08-05 14:04:04 +100010212
10213/*[clinic input]
10214os.symlink
10215 src: path_t
10216 dst: path_t
10217 target_is_directory: bool = False
10218 *
10219 dir_fd: dir_fd(requires='symlinkat')=None
10220
10221# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
10222
10223Create a symbolic link pointing to src named dst.
10224
10225target_is_directory is required on Windows if the target is to be
10226 interpreted as a directory. (On Windows, symlink requires
10227 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
10228 target_is_directory is ignored on non-Windows platforms.
10229
10230If dir_fd is not None, it should be a file descriptor open to a directory,
10231 and path should be relative; path will then be relative to that directory.
10232dir_fd may not be implemented on your platform.
10233 If it is unavailable, using it will raise a NotImplementedError.
10234
10235[clinic start generated code]*/
10236
10237PyDoc_STRVAR(os_symlink__doc__,
10238"symlink($module, /, src, dst, target_is_directory=False, *, dir_fd=None)\n"
10239"--\n"
10240"\n"
10241"Create a symbolic link pointing to src named dst.\n"
10242"\n"
10243"target_is_directory is required on Windows if the target is to be\n"
10244" interpreted as a directory. (On Windows, symlink requires\n"
10245" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n"
10246" target_is_directory is ignored on non-Windows platforms.\n"
10247"\n"
10248"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
10249" and path should be relative; path will then be relative to that directory.\n"
10250"dir_fd may not be implemented on your platform.\n"
10251" If it is unavailable, using it will raise a NotImplementedError.");
10252
10253#define OS_SYMLINK_METHODDEF \
10254 {"symlink", (PyCFunction)os_symlink, METH_VARARGS|METH_KEYWORDS, os_symlink__doc__},
10255
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010256static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010257os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd);
10258
10259static PyObject *
10260os_symlink(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010261{
Larry Hastings2f936352014-08-05 14:04:04 +100010262 PyObject *return_value = NULL;
10263 static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL};
10264 path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0);
10265 path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010266 int target_is_directory = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010267 int dir_fd = DEFAULT_DIR_FD;
10268
10269 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10270 "O&O&|p$O&:symlink", _keywords,
10271 path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd))
10272 goto exit;
10273 return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd);
10274
10275exit:
10276 /* Cleanup for src */
10277 path_cleanup(&src);
10278 /* Cleanup for dst */
10279 path_cleanup(&dst);
10280
10281 return return_value;
10282}
10283
10284static PyObject *
10285os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd)
10286/*[clinic end generated code: output=1a31e6d88aafe9b6 input=e820ec4472547bc3]*/
10287{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010288#ifdef MS_WINDOWS
10289 DWORD result;
10290#else
10291 int result;
10292#endif
10293
Larry Hastings9cf065c2012-06-22 16:30:09 -070010294#ifdef MS_WINDOWS
10295 if (!check_CreateSymbolicLink()) {
10296 PyErr_SetString(PyExc_NotImplementedError,
10297 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +100010298 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +030010299 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010300 if (!win32_can_symlink) {
10301 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +100010302 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +030010303 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010304#endif
10305
Larry Hastings2f936352014-08-05 14:04:04 +100010306 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010307 PyErr_SetString(PyExc_ValueError,
10308 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +100010309 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010310 }
10311
10312#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -040010313
Larry Hastings9cf065c2012-06-22 16:30:09 -070010314 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010315 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -040010316 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +100010317 target_is_directory |= _check_dirW(src->wide, dst->wide);
10318 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010319 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010320 }
10321 else {
10322 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +100010323 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
10324 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010325 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -040010326 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010327 Py_END_ALLOW_THREADS
10328
Larry Hastings2f936352014-08-05 14:04:04 +100010329 if (!result)
10330 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010331
10332#else
10333
10334 Py_BEGIN_ALLOW_THREADS
10335#if HAVE_SYMLINKAT
10336 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +100010337 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010338 else
10339#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010340 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010341 Py_END_ALLOW_THREADS
10342
Larry Hastings2f936352014-08-05 14:04:04 +100010343 if (result)
10344 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010345#endif
10346
Larry Hastings2f936352014-08-05 14:04:04 +100010347 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010348}
10349#endif /* HAVE_SYMLINK */
10350
Larry Hastings9cf065c2012-06-22 16:30:09 -070010351
Brian Curtind40e6f72010-07-08 21:39:08 +000010352
Guido van Rossumbfaf3d61997-12-29 20:02:27 +000010353
Larry Hastings605a62d2012-06-24 04:33:36 -070010354static PyStructSequence_Field times_result_fields[] = {
10355 {"user", "user time"},
10356 {"system", "system time"},
10357 {"children_user", "user time of children"},
10358 {"children_system", "system time of children"},
10359 {"elapsed", "elapsed time since an arbitrary point in the past"},
10360 {NULL}
10361};
10362
10363PyDoc_STRVAR(times_result__doc__,
10364"times_result: Result from os.times().\n\n\
10365This object may be accessed either as a tuple of\n\
10366 (user, system, children_user, children_system, elapsed),\n\
10367or via the attributes user, system, children_user, children_system,\n\
10368and elapsed.\n\
10369\n\
10370See os.times for more information.");
10371
10372static PyStructSequence_Desc times_result_desc = {
10373 "times_result", /* name */
10374 times_result__doc__, /* doc */
10375 times_result_fields,
10376 5
10377};
10378
10379static PyTypeObject TimesResultType;
10380
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010381#ifdef MS_WINDOWS
10382#define HAVE_TIMES /* mandatory, for the method table */
10383#endif
Larry Hastings605a62d2012-06-24 04:33:36 -070010384
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010385#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -070010386
10387static PyObject *
10388build_times_result(double user, double system,
10389 double children_user, double children_system,
10390 double elapsed)
10391{
10392 PyObject *value = PyStructSequence_New(&TimesResultType);
10393 if (value == NULL)
10394 return NULL;
10395
10396#define SET(i, field) \
10397 { \
10398 PyObject *o = PyFloat_FromDouble(field); \
10399 if (!o) { \
10400 Py_DECREF(value); \
10401 return NULL; \
10402 } \
10403 PyStructSequence_SET_ITEM(value, i, o); \
10404 } \
10405
10406 SET(0, user);
10407 SET(1, system);
10408 SET(2, children_user);
10409 SET(3, children_system);
10410 SET(4, elapsed);
10411
10412#undef SET
10413
10414 return value;
10415}
10416
Larry Hastings605a62d2012-06-24 04:33:36 -070010417
Larry Hastings2f936352014-08-05 14:04:04 +100010418#ifndef MS_WINDOWS
10419#define NEED_TICKS_PER_SECOND
10420static long ticks_per_second = -1;
10421#endif /* MS_WINDOWS */
10422
10423/*[clinic input]
10424os.times
10425
10426Return a collection containing process timing information.
10427
10428The object returned behaves like a named tuple with these fields:
10429 (utime, stime, cutime, cstime, elapsed_time)
10430All fields are floating point numbers.
10431[clinic start generated code]*/
10432
10433PyDoc_STRVAR(os_times__doc__,
10434"times($module, /)\n"
10435"--\n"
10436"\n"
10437"Return a collection containing process timing information.\n"
10438"\n"
10439"The object returned behaves like a named tuple with these fields:\n"
10440" (utime, stime, cutime, cstime, elapsed_time)\n"
10441"All fields are floating point numbers.");
10442
10443#define OS_TIMES_METHODDEF \
10444 {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__},
10445
Barry Warsaw53699e91996-12-10 23:23:01 +000010446static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010447os_times_impl(PyModuleDef *module);
10448
10449static PyObject *
10450os_times(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
10451{
10452 return os_times_impl(module);
10453}
10454
10455static PyObject *
10456os_times_impl(PyModuleDef *module)
10457/*[clinic end generated code: output=b86896d031a9b768 input=2bf9df3d6ab2e48b]*/
10458#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +000010459{
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 FILETIME create, exit, kernel, user;
10461 HANDLE hProc;
10462 hProc = GetCurrentProcess();
10463 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
10464 /* The fields of a FILETIME structure are the hi and lo part
10465 of a 64-bit value expressed in 100 nanosecond units.
10466 1e7 is one second in such units; 1e-7 the inverse.
10467 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
10468 */
Larry Hastings605a62d2012-06-24 04:33:36 -070010469 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 (double)(user.dwHighDateTime*429.4967296 +
10471 user.dwLowDateTime*1e-7),
10472 (double)(kernel.dwHighDateTime*429.4967296 +
10473 kernel.dwLowDateTime*1e-7),
10474 (double)0,
10475 (double)0,
10476 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000010477}
Larry Hastings2f936352014-08-05 14:04:04 +100010478#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010479{
Larry Hastings2f936352014-08-05 14:04:04 +100010480
10481
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010482 struct tms t;
10483 clock_t c;
10484 errno = 0;
10485 c = times(&t);
10486 if (c == (clock_t) -1)
10487 return posix_error();
10488 return build_times_result(
10489 (double)t.tms_utime / ticks_per_second,
10490 (double)t.tms_stime / ticks_per_second,
10491 (double)t.tms_cutime / ticks_per_second,
10492 (double)t.tms_cstime / ticks_per_second,
10493 (double)c / ticks_per_second);
10494}
Larry Hastings2f936352014-08-05 14:04:04 +100010495#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +020010496#endif /* HAVE_TIMES */
10497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010498
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010499#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +100010500/*[clinic input]
10501os.getsid
10502
10503 pid: pid_t
10504 /
10505
10506Call the system call getsid(pid) and return the result.
10507[clinic start generated code]*/
10508
10509PyDoc_STRVAR(os_getsid__doc__,
10510"getsid($module, pid, /)\n"
10511"--\n"
10512"\n"
10513"Call the system call getsid(pid) and return the result.");
10514
10515#define OS_GETSID_METHODDEF \
10516 {"getsid", (PyCFunction)os_getsid, METH_VARARGS, os_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010517
10518static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010519os_getsid_impl(PyModuleDef *module, pid_t pid);
10520
10521static PyObject *
10522os_getsid(PyModuleDef *module, PyObject *args)
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010523{
Larry Hastings2f936352014-08-05 14:04:04 +100010524 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +100010526
10527 if (!PyArg_ParseTuple(args,
10528 "" _Py_PARSE_PID ":getsid",
10529 &pid))
10530 goto exit;
10531 return_value = os_getsid_impl(module, pid);
10532
10533exit:
10534 return return_value;
10535}
10536
10537static PyObject *
10538os_getsid_impl(PyModuleDef *module, pid_t pid)
10539/*[clinic end generated code: output=ea8390f395f4e0e1 input=eeb2b923a30ce04e]*/
10540{
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 sid = getsid(pid);
10543 if (sid < 0)
10544 return posix_error();
10545 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010546}
10547#endif /* HAVE_GETSID */
10548
10549
Guido van Rossumb6775db1994-08-01 11:34:53 +000010550#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +100010551/*[clinic input]
10552os.setsid
10553
10554Call the system call setsid().
10555[clinic start generated code]*/
10556
10557PyDoc_STRVAR(os_setsid__doc__,
10558"setsid($module, /)\n"
10559"--\n"
10560"\n"
10561"Call the system call setsid().");
10562
10563#define OS_SETSID_METHODDEF \
10564 {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010565
Barry Warsaw53699e91996-12-10 23:23:01 +000010566static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010567os_setsid_impl(PyModuleDef *module);
10568
10569static PyObject *
10570os_setsid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
10571{
10572 return os_setsid_impl(module);
10573}
10574
10575static PyObject *
10576os_setsid_impl(PyModuleDef *module)
10577/*[clinic end generated code: output=2a9a1435d8d764d5 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +000010578{
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 if (setsid() < 0)
10580 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010581 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +000010582}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010583#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +000010584
Larry Hastings2f936352014-08-05 14:04:04 +100010585
Guido van Rossumb6775db1994-08-01 11:34:53 +000010586#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +100010587/*[clinic input]
10588os.setpgid
10589
10590 pid: pid_t
10591 pgrp: pid_t
10592 /
10593
10594Call the system call setpgid(pid, pgrp).
10595[clinic start generated code]*/
10596
10597PyDoc_STRVAR(os_setpgid__doc__,
10598"setpgid($module, pid, pgrp, /)\n"
10599"--\n"
10600"\n"
10601"Call the system call setpgid(pid, pgrp).");
10602
10603#define OS_SETPGID_METHODDEF \
10604 {"setpgid", (PyCFunction)os_setpgid, METH_VARARGS, os_setpgid__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010605
Barry Warsaw53699e91996-12-10 23:23:01 +000010606static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010607os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp);
10608
10609static PyObject *
10610os_setpgid(PyModuleDef *module, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +000010611{
Larry Hastings2f936352014-08-05 14:04:04 +100010612 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 pid_t pid;
Larry Hastings2f936352014-08-05 14:04:04 +100010614 pid_t pgrp;
10615
10616 if (!PyArg_ParseTuple(args,
10617 "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid",
10618 &pid, &pgrp))
10619 goto exit;
10620 return_value = os_setpgid_impl(module, pid, pgrp);
10621
10622exit:
10623 return return_value;
10624}
10625
10626static PyObject *
10627os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
10628/*[clinic end generated code: output=7ad79b725f890e1f input=fceb395eca572e1a]*/
10629{
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 if (setpgid(pid, pgrp) < 0)
10631 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010632 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +000010633}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010634#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +000010635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010636
Guido van Rossumb6775db1994-08-01 11:34:53 +000010637#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +100010638/*[clinic input]
10639os.tcgetpgrp
10640
10641 fd: int
10642 /
10643
10644Return the process group associated with the terminal specified by fd.
10645[clinic start generated code]*/
10646
10647PyDoc_STRVAR(os_tcgetpgrp__doc__,
10648"tcgetpgrp($module, fd, /)\n"
10649"--\n"
10650"\n"
10651"Return the process group associated with the terminal specified by fd.");
10652
10653#define OS_TCGETPGRP_METHODDEF \
10654 {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_VARARGS, os_tcgetpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010655
Barry Warsaw53699e91996-12-10 23:23:01 +000010656static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010657os_tcgetpgrp_impl(PyModuleDef *module, int fd);
10658
10659static PyObject *
10660os_tcgetpgrp(PyModuleDef *module, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +000010661{
Larry Hastings2f936352014-08-05 14:04:04 +100010662 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100010664
10665 if (!PyArg_ParseTuple(args,
10666 "i:tcgetpgrp",
10667 &fd))
10668 goto exit;
10669 return_value = os_tcgetpgrp_impl(module, fd);
10670
10671exit:
10672 return return_value;
10673}
10674
10675static PyObject *
10676os_tcgetpgrp_impl(PyModuleDef *module, int fd)
10677/*[clinic end generated code: output=abcf52ed4c8d22cb input=7f6c18eac10ada86]*/
10678{
10679 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 if (pgid < 0)
10681 return posix_error();
10682 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +000010683}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010684#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +000010685
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010686
Guido van Rossumb6775db1994-08-01 11:34:53 +000010687#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +100010688/*[clinic input]
10689os.tcsetpgrp
10690
10691 fd: int
10692 pgid: pid_t
10693 /
10694
10695Set the process group associated with the terminal specified by fd.
10696[clinic start generated code]*/
10697
10698PyDoc_STRVAR(os_tcsetpgrp__doc__,
10699"tcsetpgrp($module, fd, pgid, /)\n"
10700"--\n"
10701"\n"
10702"Set the process group associated with the terminal specified by fd.");
10703
10704#define OS_TCSETPGRP_METHODDEF \
10705 {"tcsetpgrp", (PyCFunction)os_tcsetpgrp, METH_VARARGS, os_tcsetpgrp__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010706
Barry Warsaw53699e91996-12-10 23:23:01 +000010707static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010708os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid);
10709
10710static PyObject *
10711os_tcsetpgrp(PyModuleDef *module, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +000010712{
Larry Hastings2f936352014-08-05 14:04:04 +100010713 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 int fd;
10715 pid_t pgid;
Larry Hastings2f936352014-08-05 14:04:04 +100010716
10717 if (!PyArg_ParseTuple(args,
10718 "i" _Py_PARSE_PID ":tcsetpgrp",
10719 &fd, &pgid))
10720 goto exit;
10721 return_value = os_tcsetpgrp_impl(module, fd, pgid);
10722
10723exit:
10724 return return_value;
10725}
10726
10727static PyObject *
10728os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
10729/*[clinic end generated code: output=76f9bb8fd00f20f5 input=5bdc997c6a619020]*/
10730{
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 if (tcsetpgrp(fd, pgid) < 0)
10732 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010733 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +000010734}
Guido van Rossumb6775db1994-08-01 11:34:53 +000010735#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +000010736
Guido van Rossum687dd131993-05-17 08:34:16 +000010737/* Functions acting on file descriptors */
10738
Victor Stinnerdaf45552013-08-28 00:53:59 +020010739#ifdef O_CLOEXEC
10740extern int _Py_open_cloexec_works;
10741#endif
10742
Larry Hastings2f936352014-08-05 14:04:04 +100010743
10744/*[clinic input]
10745os.open -> int
10746 path: path_t
10747 flags: int
10748 mode: int = 0o777
10749 *
10750 dir_fd: dir_fd(requires='openat') = None
10751
10752# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
10753
10754Open a file for low level IO. Returns a file descriptor (integer).
10755
10756If dir_fd is not None, it should be a file descriptor open to a directory,
10757 and path should be relative; path will then be relative to that directory.
10758dir_fd may not be implemented on your platform.
10759 If it is unavailable, using it will raise a NotImplementedError.
10760[clinic start generated code]*/
10761
10762PyDoc_STRVAR(os_open__doc__,
10763"open($module, /, path, flags, mode=511, *, dir_fd=None)\n"
10764"--\n"
10765"\n"
10766"Open a file for low level IO. Returns a file descriptor (integer).\n"
10767"\n"
10768"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
10769" and path should be relative; path will then be relative to that directory.\n"
10770"dir_fd may not be implemented on your platform.\n"
10771" If it is unavailable, using it will raise a NotImplementedError.");
10772
10773#define OS_OPEN_METHODDEF \
10774 {"open", (PyCFunction)os_open, METH_VARARGS|METH_KEYWORDS, os_open__doc__},
10775
10776static int
10777os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010778
Barry Warsaw53699e91996-12-10 23:23:01 +000010779static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010780os_open(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000010781{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010783 static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
10784 path_t path = PATH_T_INITIALIZE("open", "path", 0, 0);
10785 int flags;
10786 int mode = 511;
10787 int dir_fd = DEFAULT_DIR_FD;
10788 int _return_value;
10789
10790 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10791 "O&i|i$O&:open", _keywords,
10792 path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd))
10793 goto exit;
10794 _return_value = os_open_impl(module, &path, flags, mode, dir_fd);
10795 if ((_return_value == -1) && PyErr_Occurred())
10796 goto exit;
10797 return_value = PyLong_FromLong((long)_return_value);
10798
10799exit:
10800 /* Cleanup for path */
10801 path_cleanup(&path);
10802
10803 return return_value;
10804}
10805
10806static int
10807os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd)
10808/*[clinic end generated code: output=05b68fc4ed5e29c9 input=ad8623b29acd2934]*/
10809{
10810 int fd;
10811
Victor Stinnerdaf45552013-08-28 00:53:59 +020010812#ifdef O_CLOEXEC
10813 int *atomic_flag_works = &_Py_open_cloexec_works;
10814#elif !defined(MS_WINDOWS)
10815 int *atomic_flag_works = NULL;
10816#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +000010817
Victor Stinnerdaf45552013-08-28 00:53:59 +020010818#ifdef MS_WINDOWS
10819 flags |= O_NOINHERIT;
10820#elif defined(O_CLOEXEC)
10821 flags |= O_CLOEXEC;
10822#endif
10823
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010826 if (path->wide)
10827 fd = _wopen(path->wide, flags, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 else
10829#endif
10830#ifdef HAVE_OPENAT
10831 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +100010832 fd = openat(dir_fd, path->narrow, flags, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010833 else
10834#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010835 fd = open(path->narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +000010837
Larry Hastings9cf065c2012-06-22 16:30:09 -070010838 if (fd == -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100010839 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
10840 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 }
10842
Victor Stinnerdaf45552013-08-28 00:53:59 +020010843#ifndef MS_WINDOWS
10844 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
10845 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +100010846 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010847 }
10848#endif
10849
Larry Hastings2f936352014-08-05 14:04:04 +100010850 return fd;
10851}
10852
10853
10854/*[clinic input]
10855os.close
10856
10857 fd: int
10858
10859Close a file descriptor.
10860[clinic start generated code]*/
10861
10862PyDoc_STRVAR(os_close__doc__,
10863"close($module, /, fd)\n"
10864"--\n"
10865"\n"
10866"Close a file descriptor.");
10867
10868#define OS_CLOSE_METHODDEF \
10869 {"close", (PyCFunction)os_close, METH_VARARGS|METH_KEYWORDS, os_close__doc__},
10870
10871static PyObject *
10872os_close_impl(PyModuleDef *module, int fd);
10873
10874static PyObject *
10875os_close(PyModuleDef *module, PyObject *args, PyObject *kwargs)
10876{
10877 PyObject *return_value = NULL;
10878 static char *_keywords[] = {"fd", NULL};
10879 int fd;
10880
10881 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
10882 "i:close", _keywords,
10883 &fd))
10884 goto exit;
10885 return_value = os_close_impl(module, fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010886
10887exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010888 return return_value;
10889}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010890
Barry Warsaw53699e91996-12-10 23:23:01 +000010891static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010892os_close_impl(PyModuleDef *module, int fd)
10893/*[clinic end generated code: output=927004e29ad55808 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010894{
Larry Hastings2f936352014-08-05 14:04:04 +100010895 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 if (!_PyVerify_fd(fd))
10897 return posix_error();
10898 Py_BEGIN_ALLOW_THREADS
10899 res = close(fd);
10900 Py_END_ALLOW_THREADS
10901 if (res < 0)
10902 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +100010903 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +000010904}
10905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010906
Larry Hastings2f936352014-08-05 14:04:04 +100010907/*[clinic input]
10908os.closerange
10909
10910 fd_low: int
10911 fd_high: int
10912 /
10913
10914Closes all file descriptors in [fd_low, fd_high), ignoring errors.
10915[clinic start generated code]*/
10916
10917PyDoc_STRVAR(os_closerange__doc__,
10918"closerange($module, fd_low, fd_high, /)\n"
10919"--\n"
10920"\n"
10921"Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
10922
10923#define OS_CLOSERANGE_METHODDEF \
10924 {"closerange", (PyCFunction)os_closerange, METH_VARARGS, os_closerange__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +000010925
10926static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010927os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high);
10928
10929static PyObject *
10930os_closerange(PyModuleDef *module, PyObject *args)
Christian Heimesfdab48e2008-01-20 09:06:41 +000010931{
Larry Hastings2f936352014-08-05 14:04:04 +100010932 PyObject *return_value = NULL;
10933 int fd_low;
10934 int fd_high;
10935
10936 if (!PyArg_ParseTuple(args,
10937 "ii:closerange",
10938 &fd_low, &fd_high))
10939 goto exit;
10940 return_value = os_closerange_impl(module, fd_low, fd_high);
10941
10942exit:
10943 return return_value;
10944}
10945
10946static PyObject *
10947os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
10948/*[clinic end generated code: output=0a929ece386811c3 input=5855a3d053ebd4ec]*/
10949{
10950 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010952 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 if (_PyVerify_fd(i))
10954 close(i);
10955 Py_END_ALLOW_THREADS
10956 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +000010957}
10958
10959
Larry Hastings2f936352014-08-05 14:04:04 +100010960/*[clinic input]
10961os.dup -> int
10962
10963 fd: int
10964 /
10965
10966Return a duplicate of a file descriptor.
10967[clinic start generated code]*/
10968
10969PyDoc_STRVAR(os_dup__doc__,
10970"dup($module, fd, /)\n"
10971"--\n"
10972"\n"
10973"Return a duplicate of a file descriptor.");
10974
10975#define OS_DUP_METHODDEF \
10976 {"dup", (PyCFunction)os_dup, METH_VARARGS, os_dup__doc__},
10977
10978static int
10979os_dup_impl(PyModuleDef *module, int fd);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010980
Barry Warsaw53699e91996-12-10 23:23:01 +000010981static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010982os_dup(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000010983{
Larry Hastings2f936352014-08-05 14:04:04 +100010984 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100010986 int _return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010987
Larry Hastings2f936352014-08-05 14:04:04 +100010988 if (!PyArg_ParseTuple(args,
10989 "i:dup",
10990 &fd))
10991 goto exit;
10992 _return_value = os_dup_impl(module, fd);
10993 if ((_return_value == -1) && PyErr_Occurred())
10994 goto exit;
10995 return_value = PyLong_FromLong((long)_return_value);
Tim Golden23005082013-10-25 11:22:37 +010010996
Larry Hastings2f936352014-08-05 14:04:04 +100010997exit:
10998 return return_value;
10999}
Victor Stinnerdaf45552013-08-28 00:53:59 +020011000
Larry Hastings2f936352014-08-05 14:04:04 +100011001static int
11002os_dup_impl(PyModuleDef *module, int fd)
11003/*[clinic end generated code: output=75943e057b25e1bd input=6f10f7ea97f7852a]*/
11004{
11005 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +000011006}
11007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011008
Larry Hastings2f936352014-08-05 14:04:04 +100011009/*[clinic input]
11010os.dup2
11011 fd: int
11012 fd2: int
11013 inheritable: bool=True
11014
11015Duplicate file descriptor.
11016[clinic start generated code]*/
11017
11018PyDoc_STRVAR(os_dup2__doc__,
11019"dup2($module, /, fd, fd2, inheritable=True)\n"
11020"--\n"
11021"\n"
11022"Duplicate file descriptor.");
11023
11024#define OS_DUP2_METHODDEF \
11025 {"dup2", (PyCFunction)os_dup2, METH_VARARGS|METH_KEYWORDS, os_dup2__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011026
Barry Warsaw53699e91996-12-10 23:23:01 +000011027static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011028os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable);
11029
11030static PyObject *
11031os_dup2(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000011032{
Larry Hastings2f936352014-08-05 14:04:04 +100011033 PyObject *return_value = NULL;
11034 static char *_keywords[] = {"fd", "fd2", "inheritable", NULL};
11035 int fd;
11036 int fd2;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011037 int inheritable = 1;
Larry Hastings2f936352014-08-05 14:04:04 +100011038
11039 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
11040 "ii|p:dup2", _keywords,
11041 &fd, &fd2, &inheritable))
11042 goto exit;
11043 return_value = os_dup2_impl(module, fd, fd2, inheritable);
11044
11045exit:
11046 return return_value;
11047}
11048
11049static PyObject *
11050os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
11051/*[clinic end generated code: output=531e482dd11a99a0 input=76e96f511be0352f]*/
11052{
Victor Stinnerdaf45552013-08-28 00:53:59 +020011053 int res;
11054#if defined(HAVE_DUP3) && \
11055 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
11056 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
11057 int dup3_works = -1;
11058#endif
11059
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 if (!_PyVerify_fd_dup2(fd, fd2))
11061 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +020011062
11063#ifdef MS_WINDOWS
11064 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +020011066 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 if (res < 0)
11068 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +020011069
11070 /* Character files like console cannot be make non-inheritable */
11071 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
11072 close(fd2);
11073 return NULL;
11074 }
11075
11076#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
11077 Py_BEGIN_ALLOW_THREADS
11078 if (!inheritable)
11079 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
11080 else
11081 res = dup2(fd, fd2);
11082 Py_END_ALLOW_THREADS
11083 if (res < 0)
11084 return posix_error();
11085
11086#else
11087
11088#ifdef HAVE_DUP3
11089 if (!inheritable && dup3_works != 0) {
11090 Py_BEGIN_ALLOW_THREADS
11091 res = dup3(fd, fd2, O_CLOEXEC);
11092 Py_END_ALLOW_THREADS
11093 if (res < 0) {
11094 if (dup3_works == -1)
11095 dup3_works = (errno != ENOSYS);
11096 if (dup3_works)
11097 return posix_error();
11098 }
11099 }
11100
11101 if (inheritable || dup3_works == 0)
11102 {
11103#endif
11104 Py_BEGIN_ALLOW_THREADS
11105 res = dup2(fd, fd2);
11106 Py_END_ALLOW_THREADS
11107 if (res < 0)
11108 return posix_error();
11109
11110 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
11111 close(fd2);
11112 return NULL;
11113 }
11114#ifdef HAVE_DUP3
11115 }
11116#endif
11117
11118#endif
11119
Larry Hastings2f936352014-08-05 14:04:04 +100011120 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +000011121}
11122
Larry Hastings2f936352014-08-05 14:04:04 +100011123
Ross Lagerwall7807c352011-03-17 20:20:30 +020011124#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +100011125/*[clinic input]
11126os.lockf
11127
11128 fd: int
11129 An open file descriptor.
11130 command: int
11131 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
11132 length: Py_off_t
11133 The number of bytes to lock, starting at the current position.
11134 /
11135
11136Apply, test or remove a POSIX lock on an open file descriptor.
11137
11138[clinic start generated code]*/
11139
11140PyDoc_STRVAR(os_lockf__doc__,
11141"lockf($module, fd, command, length, /)\n"
11142"--\n"
11143"\n"
11144"Apply, test or remove a POSIX lock on an open file descriptor.\n"
11145"\n"
11146" fd\n"
11147" An open file descriptor.\n"
11148" command\n"
11149" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n"
11150" length\n"
11151" The number of bytes to lock, starting at the current position.");
11152
11153#define OS_LOCKF_METHODDEF \
11154 {"lockf", (PyCFunction)os_lockf, METH_VARARGS, os_lockf__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011155
11156static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011157os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length);
11158
11159static PyObject *
11160os_lockf(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011161{
Larry Hastings2f936352014-08-05 14:04:04 +100011162 PyObject *return_value = NULL;
11163 int fd;
11164 int command;
11165 Py_off_t length;
11166
11167 if (!PyArg_ParseTuple(args,
11168 "iiO&:lockf",
11169 &fd, &command, Py_off_t_converter, &length))
11170 goto exit;
11171 return_value = os_lockf_impl(module, fd, command, length);
11172
11173exit:
11174 return return_value;
11175}
11176
11177static PyObject *
11178os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
11179/*[clinic end generated code: output=1b28346ac7335c0f input=65da41d2106e9b79]*/
11180{
11181 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011182
11183 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011184 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011185 Py_END_ALLOW_THREADS
11186
11187 if (res < 0)
11188 return posix_error();
11189
11190 Py_RETURN_NONE;
11191}
Larry Hastings2f936352014-08-05 14:04:04 +100011192#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011194
Larry Hastings2f936352014-08-05 14:04:04 +100011195/*[clinic input]
11196os.lseek -> Py_off_t
11197
11198 fd: int
11199 position: Py_off_t
11200 how: int
11201 /
11202
11203Set the position of a file descriptor. Return the new position.
11204
11205Return the new cursor position in number of bytes
11206relative to the beginning of the file.
11207[clinic start generated code]*/
11208
11209PyDoc_STRVAR(os_lseek__doc__,
11210"lseek($module, fd, position, how, /)\n"
11211"--\n"
11212"\n"
11213"Set the position of a file descriptor. Return the new position.\n"
11214"\n"
11215"Return the new cursor position in number of bytes\n"
11216"relative to the beginning of the file.");
11217
11218#define OS_LSEEK_METHODDEF \
11219 {"lseek", (PyCFunction)os_lseek, METH_VARARGS, os_lseek__doc__},
11220
11221static Py_off_t
11222os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how);
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011223
Barry Warsaw53699e91996-12-10 23:23:01 +000011224static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011225os_lseek(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000011226{
Larry Hastings2f936352014-08-05 14:04:04 +100011227 PyObject *return_value = NULL;
11228 int fd;
11229 Py_off_t position;
11230 int how;
11231 Py_off_t _return_value;
11232
11233 if (!PyArg_ParseTuple(args,
11234 "iO&i:lseek",
11235 &fd, Py_off_t_converter, &position, &how))
11236 goto exit;
11237 _return_value = os_lseek_impl(module, fd, position, how);
11238 if ((_return_value == -1) && PyErr_Occurred())
11239 goto exit;
11240 return_value = PyLong_FromPy_off_t(_return_value);
11241
11242exit:
11243 return return_value;
11244}
11245
11246static Py_off_t
11247os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
11248/*[clinic end generated code: output=88cfc146f55667af input=902654ad3f96a6d3]*/
11249{
11250 Py_off_t result;
11251
11252 if (!_PyVerify_fd(fd)) {
11253 posix_error();
11254 return -1;
11255 }
Guido van Rossum687dd131993-05-17 08:34:16 +000011256#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
11258 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +100011259 case 0: how = SEEK_SET; break;
11260 case 1: how = SEEK_CUR; break;
11261 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011263#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011264
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100011266 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +000011267
Larry Hastings2f936352014-08-05 14:04:04 +100011268 if (!_PyVerify_fd(fd)) {
11269 posix_error();
11270 return -1;
11271 }
Victor Stinner8c62be82010-05-06 00:08:46 +000011272 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +020011273#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011274 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +000011275#else
Larry Hastings2f936352014-08-05 14:04:04 +100011276 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +000011277#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011279 if (result < 0)
11280 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +000011281
Larry Hastings2f936352014-08-05 14:04:04 +100011282 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +000011283}
11284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011285
Larry Hastings2f936352014-08-05 14:04:04 +100011286/*[clinic input]
11287os.read
11288 fd: int
11289 length: Py_ssize_t
11290 /
11291
11292Read from a file descriptor. Returns a bytes object.
11293[clinic start generated code]*/
11294
11295PyDoc_STRVAR(os_read__doc__,
11296"read($module, fd, length, /)\n"
11297"--\n"
11298"\n"
11299"Read from a file descriptor. Returns a bytes object.");
11300
11301#define OS_READ_METHODDEF \
11302 {"read", (PyCFunction)os_read, METH_VARARGS, os_read__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011303
Barry Warsaw53699e91996-12-10 23:23:01 +000011304static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011305os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length);
11306
11307static PyObject *
11308os_read(PyModuleDef *module, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +000011309{
Larry Hastings2f936352014-08-05 14:04:04 +100011310 PyObject *return_value = NULL;
Victor Stinnerb28ed922014-07-11 17:04:41 +020011311 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011312 Py_ssize_t length;
11313
11314 if (!PyArg_ParseTuple(args,
11315 "in:read",
11316 &fd, &length))
11317 goto exit;
11318 return_value = os_read_impl(module, fd, length);
11319
11320exit:
11321 return return_value;
11322}
11323
11324static PyObject *
11325os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
11326/*[clinic end generated code: output=1f3bc27260a24968 input=1df2eaa27c0bf1d3]*/
11327{
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 Py_ssize_t n;
11329 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +100011330
11331 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 errno = EINVAL;
11333 return posix_error();
11334 }
Larry Hastings2f936352014-08-05 14:04:04 +100011335 if (!_PyVerify_fd(fd))
11336 return posix_error();
11337
11338#ifdef MS_WINDOWS
11339 #define READ_CAST (int)
11340 if (length > INT_MAX)
11341 length = INT_MAX;
11342#else
11343 #define READ_CAST
11344#endif
11345
11346 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 if (buffer == NULL)
11348 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011350 n = read(fd, PyBytes_AS_STRING(buffer), READ_CAST length);
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011352
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 if (n < 0) {
11354 Py_DECREF(buffer);
11355 return posix_error();
11356 }
Larry Hastings2f936352014-08-05 14:04:04 +100011357
11358 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +100011360
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +000011362}
11363
Ross Lagerwall7807c352011-03-17 20:20:30 +020011364#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
11365 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011366static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011367iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
11368{
11369 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011370 Py_ssize_t blen, total = 0;
11371
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011372 *iov = PyMem_New(struct iovec, cnt);
11373 if (*iov == NULL) {
11374 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +010011375 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011376 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011377
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011378 *buf = PyMem_New(Py_buffer, cnt);
11379 if (*buf == NULL) {
11380 PyMem_Del(*iov);
11381 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +010011382 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011383 }
11384
11385 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011386 PyObject *item = PySequence_GetItem(seq, i);
11387 if (item == NULL)
11388 goto fail;
11389 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
11390 Py_DECREF(item);
11391 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011392 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011393 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011394 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011395 blen = (*buf)[i].len;
11396 (*iov)[i].iov_len = blen;
11397 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011398 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011399 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +020011400
11401fail:
11402 PyMem_Del(*iov);
11403 for (j = 0; j < i; j++) {
11404 PyBuffer_Release(&(*buf)[j]);
11405 }
11406 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +010011407 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011408}
11409
11410static void
11411iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
11412{
11413 int i;
11414 PyMem_Del(iov);
11415 for (i = 0; i < cnt; i++) {
11416 PyBuffer_Release(&buf[i]);
11417 }
11418 PyMem_Del(buf);
11419}
11420#endif
11421
Larry Hastings2f936352014-08-05 14:04:04 +100011422
Ross Lagerwall7807c352011-03-17 20:20:30 +020011423#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +100011424/*[clinic input]
11425os.readv -> Py_ssize_t
11426
11427 fd: int
11428 buffers: object
11429 /
11430
11431Read from a file descriptor fd into an iterable of buffers.
11432
11433The buffers should be mutable buffers accepting bytes.
11434readv will transfer data into each buffer until it is full
11435and then move on to the next buffer in the sequence to hold
11436the rest of the data.
11437
11438readv returns the total number of bytes read,
11439which may be less than the total capacity of all the buffers.
11440[clinic start generated code]*/
11441
11442PyDoc_STRVAR(os_readv__doc__,
11443"readv($module, fd, buffers, /)\n"
11444"--\n"
11445"\n"
11446"Read from a file descriptor fd into an iterable of buffers.\n"
11447"\n"
11448"The buffers should be mutable buffers accepting bytes.\n"
11449"readv will transfer data into each buffer until it is full\n"
11450"and then move on to the next buffer in the sequence to hold\n"
11451"the rest of the data.\n"
11452"\n"
11453"readv returns the total number of bytes read,\n"
11454"which may be less than the total capacity of all the buffers.");
11455
11456#define OS_READV_METHODDEF \
11457 {"readv", (PyCFunction)os_readv, METH_VARARGS, os_readv__doc__},
11458
11459static Py_ssize_t
11460os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011461
11462static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011463os_readv(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011464{
Larry Hastings2f936352014-08-05 14:04:04 +100011465 PyObject *return_value = NULL;
11466 int fd;
11467 PyObject *buffers;
11468 Py_ssize_t _return_value;
11469
11470 if (!PyArg_ParseTuple(args,
11471 "iO:readv",
11472 &fd, &buffers))
11473 goto exit;
11474 _return_value = os_readv_impl(module, fd, buffers);
11475 if ((_return_value == -1) && PyErr_Occurred())
11476 goto exit;
11477 return_value = PyLong_FromSsize_t(_return_value);
11478
11479exit:
11480 return return_value;
11481}
11482
11483static Py_ssize_t
11484os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
11485/*[clinic end generated code: output=72748b1c32a6e2a1 input=e679eb5dbfa0357d]*/
11486{
11487 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011488 Py_ssize_t n;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011489 struct iovec *iov;
11490 Py_buffer *buf;
11491
Larry Hastings2f936352014-08-05 14:04:04 +100011492 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011493 PyErr_SetString(PyExc_TypeError,
11494 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100011495 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011496 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011497
Larry Hastings2f936352014-08-05 14:04:04 +100011498 cnt = PySequence_Size(buffers);
11499
11500 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
11501 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011502
11503 Py_BEGIN_ALLOW_THREADS
11504 n = readv(fd, iov, cnt);
11505 Py_END_ALLOW_THREADS
11506
11507 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +100011508 if (n < 0) {
11509 posix_error();
11510 return -1;
11511 }
Victor Stinner57ddf782014-01-08 15:21:28 +010011512
Larry Hastings2f936352014-08-05 14:04:04 +100011513 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011514}
Larry Hastings2f936352014-08-05 14:04:04 +100011515#endif /* HAVE_READV */
11516
Ross Lagerwall7807c352011-03-17 20:20:30 +020011517
11518#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +100011519/*[clinic input]
11520# TODO length should be size_t! but Python doesn't support parsing size_t yet.
11521os.pread
11522
11523 fd: int
11524 length: int
11525 offset: Py_off_t
11526 /
11527
11528Read a number of bytes from a file descriptor starting at a particular offset.
11529
11530Read length bytes from file descriptor fd, starting at offset bytes from
11531the beginning of the file. The file offset remains unchanged.
11532[clinic start generated code]*/
11533
11534PyDoc_STRVAR(os_pread__doc__,
11535"pread($module, fd, length, offset, /)\n"
11536"--\n"
11537"\n"
11538"Read a number of bytes from a file descriptor starting at a particular offset.\n"
11539"\n"
11540"Read length bytes from file descriptor fd, starting at offset bytes from\n"
11541"the beginning of the file. The file offset remains unchanged.");
11542
11543#define OS_PREAD_METHODDEF \
11544 {"pread", (PyCFunction)os_pread, METH_VARARGS, os_pread__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011545
11546static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011547os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset);
11548
11549static PyObject *
11550os_pread(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011551{
Larry Hastings2f936352014-08-05 14:04:04 +100011552 PyObject *return_value = NULL;
11553 int fd;
11554 int length;
11555 Py_off_t offset;
11556
11557 if (!PyArg_ParseTuple(args,
11558 "iiO&:pread",
11559 &fd, &length, Py_off_t_converter, &offset))
11560 goto exit;
11561 return_value = os_pread_impl(module, fd, length, offset);
11562
11563exit:
11564 return return_value;
11565}
11566
11567static PyObject *
11568os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
11569/*[clinic end generated code: output=7b62bf6c06e20ae8 input=084948dcbaa35d4c]*/
11570{
Ross Lagerwall7807c352011-03-17 20:20:30 +020011571 Py_ssize_t n;
11572 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011573
Larry Hastings2f936352014-08-05 14:04:04 +100011574 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011575 errno = EINVAL;
11576 return posix_error();
11577 }
Larry Hastings2f936352014-08-05 14:04:04 +100011578 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011579 if (buffer == NULL)
11580 return NULL;
11581 if (!_PyVerify_fd(fd)) {
11582 Py_DECREF(buffer);
11583 return posix_error();
11584 }
11585 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011586 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011587 Py_END_ALLOW_THREADS
11588 if (n < 0) {
11589 Py_DECREF(buffer);
11590 return posix_error();
11591 }
Larry Hastings2f936352014-08-05 14:04:04 +100011592 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011593 _PyBytes_Resize(&buffer, n);
11594 return buffer;
11595}
Larry Hastings2f936352014-08-05 14:04:04 +100011596#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011597
Larry Hastings2f936352014-08-05 14:04:04 +100011598
11599/*[clinic input]
11600os.write -> Py_ssize_t
11601
11602 fd: int
11603 data: Py_buffer
11604 /
11605
11606Write a bytes object to a file descriptor.
11607[clinic start generated code]*/
11608
11609PyDoc_STRVAR(os_write__doc__,
11610"write($module, fd, data, /)\n"
11611"--\n"
11612"\n"
11613"Write a bytes object to a file descriptor.");
11614
11615#define OS_WRITE_METHODDEF \
11616 {"write", (PyCFunction)os_write, METH_VARARGS, os_write__doc__},
11617
11618static Py_ssize_t
11619os_write_impl(PyModuleDef *module, int fd, Py_buffer *data);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011620
11621static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011622os_write(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011623{
Larry Hastings2f936352014-08-05 14:04:04 +100011624 PyObject *return_value = NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011625 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011626 Py_buffer data = {NULL, NULL};
11627 Py_ssize_t _return_value;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011628
Larry Hastings2f936352014-08-05 14:04:04 +100011629 if (!PyArg_ParseTuple(args,
11630 "iy*:write",
11631 &fd, &data))
11632 goto exit;
11633 _return_value = os_write_impl(module, fd, &data);
11634 if ((_return_value == -1) && PyErr_Occurred())
11635 goto exit;
11636 return_value = PyLong_FromSsize_t(_return_value);
11637
11638exit:
11639 /* Cleanup for data */
11640 if (data.obj)
11641 PyBuffer_Release(&data);
11642
11643 return return_value;
11644}
11645
11646static Py_ssize_t
11647os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
11648/*[clinic end generated code: output=aeb96acfdd4d5112 input=3207e28963234f3c]*/
11649{
11650 Py_ssize_t size;
11651 Py_ssize_t len = data->len;
11652
Ross Lagerwall7807c352011-03-17 20:20:30 +020011653 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011654 posix_error();
11655 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011656 }
Larry Hastings2f936352014-08-05 14:04:04 +100011657
Ross Lagerwall7807c352011-03-17 20:20:30 +020011658 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +020011659#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +020011660 if (len > INT_MAX)
11661 len = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +100011662 size = write(fd, data->buf, (int)len);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011663#else
Larry Hastings2f936352014-08-05 14:04:04 +100011664 size = write(fd, data->buf, len);
Ross Lagerwall7807c352011-03-17 20:20:30 +020011665#endif
11666 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100011667 if (size < 0) {
11668 posix_error();
11669 return -1;
11670 }
11671 return size;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011672}
11673
11674#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011675PyDoc_STRVAR(posix_sendfile__doc__,
11676"sendfile(out, in, offset, nbytes) -> byteswritten\n\
11677sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
11678 -> byteswritten\n\
11679Copy nbytes bytes from file descriptor in to file descriptor out.");
11680
Larry Hastings2f936352014-08-05 14:04:04 +100011681/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011682static PyObject *
11683posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
11684{
11685 int in, out;
11686 Py_ssize_t ret;
11687 off_t offset;
11688
11689#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
11690#ifndef __APPLE__
11691 Py_ssize_t len;
11692#endif
11693 PyObject *headers = NULL, *trailers = NULL;
11694 Py_buffer *hbuf, *tbuf;
11695 off_t sbytes;
11696 struct sf_hdtr sf;
11697 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +000011698 static char *keywords[] = {"out", "in",
11699 "offset", "count",
11700 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011701
Victor Stinner6ce0dbf2013-07-07 16:32:36 +020011702 sf.headers = NULL;
11703 sf.trailers = NULL;
11704
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011705#ifdef __APPLE__
11706 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +100011707 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011708#else
11709 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +100011710 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011711#endif
11712 &headers, &trailers, &flags))
11713 return NULL;
11714 if (headers != NULL) {
11715 if (!PySequence_Check(headers)) {
11716 PyErr_SetString(PyExc_TypeError,
11717 "sendfile() headers must be a sequence or None");
11718 return NULL;
11719 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011720 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011721 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011722 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +010011723 (i = iov_setup(&(sf.headers), &hbuf,
11724 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011725 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011726#ifdef __APPLE__
11727 sbytes += i;
11728#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011729 }
11730 }
11731 if (trailers != NULL) {
11732 if (!PySequence_Check(trailers)) {
11733 PyErr_SetString(PyExc_TypeError,
11734 "sendfile() trailers must be a sequence or None");
11735 return NULL;
11736 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011737 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011738 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011739 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +010011740 (i = iov_setup(&(sf.trailers), &tbuf,
11741 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011742 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +000011743#ifdef __APPLE__
11744 sbytes += i;
11745#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011746 }
11747 }
11748
11749 Py_BEGIN_ALLOW_THREADS
11750#ifdef __APPLE__
11751 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
11752#else
11753 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
11754#endif
11755 Py_END_ALLOW_THREADS
11756
11757 if (sf.headers != NULL)
11758 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
11759 if (sf.trailers != NULL)
11760 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
11761
11762 if (ret < 0) {
11763 if ((errno == EAGAIN) || (errno == EBUSY)) {
11764 if (sbytes != 0) {
11765 // some data has been sent
11766 goto done;
11767 }
11768 else {
11769 // no data has been sent; upper application is supposed
11770 // to retry on EAGAIN or EBUSY
11771 return posix_error();
11772 }
11773 }
11774 return posix_error();
11775 }
11776 goto done;
11777
11778done:
11779 #if !defined(HAVE_LARGEFILE_SUPPORT)
11780 return Py_BuildValue("l", sbytes);
11781 #else
11782 return Py_BuildValue("L", sbytes);
11783 #endif
11784
11785#else
11786 Py_ssize_t count;
11787 PyObject *offobj;
11788 static char *keywords[] = {"out", "in",
11789 "offset", "count", NULL};
11790 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
11791 keywords, &out, &in, &offobj, &count))
11792 return NULL;
11793#ifdef linux
11794 if (offobj == Py_None) {
11795 Py_BEGIN_ALLOW_THREADS
11796 ret = sendfile(out, in, NULL, count);
11797 Py_END_ALLOW_THREADS
11798 if (ret < 0)
11799 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +020011800 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011801 }
11802#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011803 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +000011804 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011805 Py_BEGIN_ALLOW_THREADS
11806 ret = sendfile(out, in, &offset, count);
11807 Py_END_ALLOW_THREADS
11808 if (ret < 0)
11809 return posix_error();
11810 return Py_BuildValue("n", ret);
11811#endif
11812}
Larry Hastings2f936352014-08-05 14:04:04 +100011813#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011814
Larry Hastings2f936352014-08-05 14:04:04 +100011815
11816/*[clinic input]
11817os.fstat
11818
11819 fd : int
11820
11821Perform a stat system call on the given file descriptor.
11822
11823Like stat(), but for an open file descriptor.
11824Equivalent to os.stat(fd).
11825[clinic start generated code]*/
11826
11827PyDoc_STRVAR(os_fstat__doc__,
11828"fstat($module, /, fd)\n"
11829"--\n"
11830"\n"
11831"Perform a stat system call on the given file descriptor.\n"
11832"\n"
11833"Like stat(), but for an open file descriptor.\n"
11834"Equivalent to os.stat(fd).");
11835
11836#define OS_FSTAT_METHODDEF \
11837 {"fstat", (PyCFunction)os_fstat, METH_VARARGS|METH_KEYWORDS, os_fstat__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011838
Barry Warsaw53699e91996-12-10 23:23:01 +000011839static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011840os_fstat_impl(PyModuleDef *module, int fd);
11841
11842static PyObject *
11843os_fstat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +000011844{
Larry Hastings2f936352014-08-05 14:04:04 +100011845 PyObject *return_value = NULL;
11846 static char *_keywords[] = {"fd", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011848
11849 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
11850 "i:fstat", _keywords,
11851 &fd))
11852 goto exit;
11853 return_value = os_fstat_impl(module, fd);
11854
11855exit:
11856 return return_value;
11857}
11858
11859static PyObject *
11860os_fstat_impl(PyModuleDef *module, int fd)
11861/*[clinic end generated code: output=dae4a9678c7bd881 input=27e0e0ebbe5600c9]*/
11862{
Victor Stinner8c62be82010-05-06 00:08:46 +000011863 STRUCT_STAT st;
11864 int res;
Larry Hastings2f936352014-08-05 14:04:04 +100011865
Victor Stinner8c62be82010-05-06 00:08:46 +000011866 Py_BEGIN_ALLOW_THREADS
11867 res = FSTAT(fd, &st);
11868 Py_END_ALLOW_THREADS
11869 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +000011870#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +010011871 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +000011872#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011873 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +000011874#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011875 }
Tim Peters5aa91602002-01-30 05:46:57 +000011876
Victor Stinner4195b5c2012-02-08 23:03:19 +010011877 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +000011878}
11879
Larry Hastings2f936352014-08-05 14:04:04 +100011880
11881/*[clinic input]
11882os.isatty -> bool
11883 fd: int
11884 /
11885
11886Return True if the fd is connected to a terminal.
11887
11888Return True if the file descriptor is an open file descriptor
11889connected to the slave end of a terminal.
11890[clinic start generated code]*/
11891
11892PyDoc_STRVAR(os_isatty__doc__,
11893"isatty($module, fd, /)\n"
11894"--\n"
11895"\n"
11896"Return True if the fd is connected to a terminal.\n"
11897"\n"
11898"Return True if the file descriptor is an open file descriptor\n"
11899"connected to the slave end of a terminal.");
11900
11901#define OS_ISATTY_METHODDEF \
11902 {"isatty", (PyCFunction)os_isatty, METH_VARARGS, os_isatty__doc__},
11903
11904static int
11905os_isatty_impl(PyModuleDef *module, int fd);
Skip Montanaro1517d842000-07-19 14:34:14 +000011906
11907static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011908os_isatty(PyModuleDef *module, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +000011909{
Larry Hastings2f936352014-08-05 14:04:04 +100011910 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011911 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +100011912 int _return_value;
11913
11914 if (!PyArg_ParseTuple(args,
11915 "i:isatty",
11916 &fd))
11917 goto exit;
11918 _return_value = os_isatty_impl(module, fd);
11919 if ((_return_value == -1) && PyErr_Occurred())
11920 goto exit;
11921 return_value = PyBool_FromLong((long)_return_value);
11922
11923exit:
11924 return return_value;
Skip Montanaro1517d842000-07-19 14:34:14 +000011925}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011926
Larry Hastings2f936352014-08-05 14:04:04 +100011927static int
11928os_isatty_impl(PyModuleDef *module, int fd)
11929/*[clinic end generated code: output=4bfadbfe22715097 input=08ce94aa1eaf7b5e]*/
11930{
11931 if (!_PyVerify_fd(fd))
11932 return 0;
11933 return isatty(fd);
11934}
11935
11936
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011937#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100011938/*[clinic input]
11939os.pipe
11940
11941Create a pipe.
11942
11943Returns a tuple of two file descriptors:
11944 (read_fd, write_fd)
11945[clinic start generated code]*/
11946
11947PyDoc_STRVAR(os_pipe__doc__,
11948"pipe($module, /)\n"
11949"--\n"
11950"\n"
11951"Create a pipe.\n"
11952"\n"
11953"Returns a tuple of two file descriptors:\n"
11954" (read_fd, write_fd)");
11955
11956#define OS_PIPE_METHODDEF \
11957 {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__},
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000011958
Barry Warsaw53699e91996-12-10 23:23:01 +000011959static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100011960os_pipe_impl(PyModuleDef *module);
11961
11962static PyObject *
11963os_pipe(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
11964{
11965 return os_pipe_impl(module);
11966}
11967
11968static PyObject *
11969os_pipe_impl(PyModuleDef *module)
11970/*[clinic end generated code: output=0da2479f2266e774 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000011971{
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020011973#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011974 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011975 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000011976 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011977#else
11978 int res;
11979#endif
11980
11981#ifdef MS_WINDOWS
11982 attr.nLength = sizeof(attr);
11983 attr.lpSecurityDescriptor = NULL;
11984 attr.bInheritHandle = FALSE;
11985
11986 Py_BEGIN_ALLOW_THREADS
11987 ok = CreatePipe(&read, &write, &attr, 0);
11988 if (ok) {
11989 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
11990 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
11991 if (fds[0] == -1 || fds[1] == -1) {
11992 CloseHandle(read);
11993 CloseHandle(write);
11994 ok = 0;
11995 }
11996 }
11997 Py_END_ALLOW_THREADS
11998
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010012000 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020012001#else
12002
12003#ifdef HAVE_PIPE2
12004 Py_BEGIN_ALLOW_THREADS
12005 res = pipe2(fds, O_CLOEXEC);
12006 Py_END_ALLOW_THREADS
12007
12008 if (res != 0 && errno == ENOSYS)
12009 {
12010#endif
12011 Py_BEGIN_ALLOW_THREADS
12012 res = pipe(fds);
12013 Py_END_ALLOW_THREADS
12014
12015 if (res == 0) {
12016 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
12017 close(fds[0]);
12018 close(fds[1]);
12019 return NULL;
12020 }
12021 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
12022 close(fds[0]);
12023 close(fds[1]);
12024 return NULL;
12025 }
12026 }
12027#ifdef HAVE_PIPE2
12028 }
12029#endif
12030
12031 if (res != 0)
12032 return PyErr_SetFromErrno(PyExc_OSError);
12033#endif /* !MS_WINDOWS */
12034 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000012035}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000012036#endif /* HAVE_PIPE */
12037
Larry Hastings2f936352014-08-05 14:04:04 +100012038
Charles-François Natalidaafdd52011-05-29 20:07:40 +020012039#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100012040/*[clinic input]
12041os.pipe2
12042
12043 flags: int
12044 /
12045
12046Create a pipe with flags set atomically.
12047
12048Returns a tuple of two file descriptors:
12049 (read_fd, write_fd)
12050
12051flags can be constructed by ORing together one or more of these values:
12052O_NONBLOCK, O_CLOEXEC.
12053[clinic start generated code]*/
12054
12055PyDoc_STRVAR(os_pipe2__doc__,
12056"pipe2($module, flags, /)\n"
12057"--\n"
12058"\n"
12059"Create a pipe with flags set atomically.\n"
12060"\n"
12061"Returns a tuple of two file descriptors:\n"
12062" (read_fd, write_fd)\n"
12063"\n"
12064"flags can be constructed by ORing together one or more of these values:\n"
12065"O_NONBLOCK, O_CLOEXEC.");
12066
12067#define OS_PIPE2_METHODDEF \
12068 {"pipe2", (PyCFunction)os_pipe2, METH_VARARGS, os_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020012069
12070static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012071os_pipe2_impl(PyModuleDef *module, int flags);
12072
12073static PyObject *
12074os_pipe2(PyModuleDef *module, PyObject *args)
Charles-François Natalidaafdd52011-05-29 20:07:40 +020012075{
Larry Hastings2f936352014-08-05 14:04:04 +100012076 PyObject *return_value = NULL;
Charles-François Natali368f34b2011-06-06 19:49:47 +020012077 int flags;
Larry Hastings2f936352014-08-05 14:04:04 +100012078
12079 if (!PyArg_ParseTuple(args,
12080 "i:pipe2",
12081 &flags))
12082 goto exit;
12083 return_value = os_pipe2_impl(module, flags);
12084
12085exit:
12086 return return_value;
12087}
12088
12089static PyObject *
12090os_pipe2_impl(PyModuleDef *module, int flags)
12091/*[clinic end generated code: output=9e27c799ce19220b input=f261b6e7e63c6817]*/
12092{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020012093 int fds[2];
12094 int res;
12095
Charles-François Natalidaafdd52011-05-29 20:07:40 +020012096 res = pipe2(fds, flags);
12097 if (res != 0)
12098 return posix_error();
12099 return Py_BuildValue("(ii)", fds[0], fds[1]);
12100}
12101#endif /* HAVE_PIPE2 */
12102
Larry Hastings2f936352014-08-05 14:04:04 +100012103
Ross Lagerwall7807c352011-03-17 20:20:30 +020012104#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100012105/*[clinic input]
12106os.writev -> Py_ssize_t
12107 fd: int
12108 buffers: object
12109 /
12110
12111Iterate over buffers, and write the contents of each to a file descriptor.
12112
12113Returns the total number of bytes written.
12114buffers must be a sequence of bytes-like objects.
12115[clinic start generated code]*/
12116
12117PyDoc_STRVAR(os_writev__doc__,
12118"writev($module, fd, buffers, /)\n"
12119"--\n"
12120"\n"
12121"Iterate over buffers, and write the contents of each to a file descriptor.\n"
12122"\n"
12123"Returns the total number of bytes written.\n"
12124"buffers must be a sequence of bytes-like objects.");
12125
12126#define OS_WRITEV_METHODDEF \
12127 {"writev", (PyCFunction)os_writev, METH_VARARGS, os_writev__doc__},
12128
12129static Py_ssize_t
12130os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012131
12132static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012133os_writev(PyModuleDef *module, PyObject *args)
Ross Lagerwall7807c352011-03-17 20:20:30 +020012134{
Larry Hastings2f936352014-08-05 14:04:04 +100012135 PyObject *return_value = NULL;
12136 int fd;
12137 PyObject *buffers;
12138 Py_ssize_t _return_value;
12139
12140 if (!PyArg_ParseTuple(args,
12141 "iO:writev",
12142 &fd, &buffers))
12143 goto exit;
12144 _return_value = os_writev_impl(module, fd, buffers);
12145 if ((_return_value == -1) && PyErr_Occurred())
12146 goto exit;
12147 return_value = PyLong_FromSsize_t(_return_value);
12148
12149exit:
12150 return return_value;
12151}
12152
12153static Py_ssize_t
12154os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
12155/*[clinic end generated code: output=591c662dccbe4951 input=5b8d17fe4189d2fe]*/
12156{
12157 int cnt;
12158 Py_ssize_t result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012159 struct iovec *iov;
12160 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100012161
12162 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012163 PyErr_SetString(PyExc_TypeError,
12164 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100012165 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012166 }
Larry Hastings2f936352014-08-05 14:04:04 +100012167 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012168
Larry Hastings2f936352014-08-05 14:04:04 +100012169 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
12170 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012171 }
12172
12173 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012174 result = writev(fd, iov, cnt);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012175 Py_END_ALLOW_THREADS
12176
12177 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +100012178 if (result < 0)
12179 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010012180
Georg Brandl306336b2012-06-24 12:55:33 +020012181 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012182}
Larry Hastings2f936352014-08-05 14:04:04 +100012183#endif /* HAVE_WRITEV */
12184
12185
12186#ifdef HAVE_PWRITE
12187/*[clinic input]
12188os.pwrite -> Py_ssize_t
12189
12190 fd: int
12191 buffer: Py_buffer
12192 offset: Py_off_t
12193 /
12194
12195Write bytes to a file descriptor starting at a particular offset.
12196
12197Write buffer to fd, starting at offset bytes from the beginning of
12198the file. Returns the number of bytes writte. Does not change the
12199current file offset.
12200[clinic start generated code]*/
12201
12202PyDoc_STRVAR(os_pwrite__doc__,
12203"pwrite($module, fd, buffer, offset, /)\n"
12204"--\n"
12205"\n"
12206"Write bytes to a file descriptor starting at a particular offset.\n"
12207"\n"
12208"Write buffer to fd, starting at offset bytes from the beginning of\n"
12209"the file. Returns the number of bytes writte. Does not change the\n"
12210"current file offset.");
12211
12212#define OS_PWRITE_METHODDEF \
12213 {"pwrite", (PyCFunction)os_pwrite, METH_VARARGS, os_pwrite__doc__},
12214
12215static Py_ssize_t
12216os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset);
12217
12218static PyObject *
12219os_pwrite(PyModuleDef *module, PyObject *args)
12220{
12221 PyObject *return_value = NULL;
12222 int fd;
12223 Py_buffer buffer = {NULL, NULL};
12224 Py_off_t offset;
12225 Py_ssize_t _return_value;
12226
12227 if (!PyArg_ParseTuple(args,
12228 "iy*O&:pwrite",
12229 &fd, &buffer, Py_off_t_converter, &offset))
12230 goto exit;
12231 _return_value = os_pwrite_impl(module, fd, &buffer, offset);
12232 if ((_return_value == -1) && PyErr_Occurred())
12233 goto exit;
12234 return_value = PyLong_FromSsize_t(_return_value);
12235
12236exit:
12237 /* Cleanup for buffer */
12238 if (buffer.obj)
12239 PyBuffer_Release(&buffer);
12240
12241 return return_value;
12242}
12243
12244static Py_ssize_t
12245os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset)
12246/*[clinic end generated code: output=ec9cc5b2238e96a7 input=19903f1b3dd26377]*/
12247{
12248 Py_ssize_t size;
12249
12250 if (!_PyVerify_fd(fd)) {
12251 posix_error();
12252 return -1;
12253 }
12254
12255 Py_BEGIN_ALLOW_THREADS
12256 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
12257 Py_END_ALLOW_THREADS
12258
12259 if (size < 0)
12260 posix_error();
12261 return size;
12262}
12263#endif /* HAVE_PWRITE */
12264
12265
12266#ifdef HAVE_MKFIFO
12267/*[clinic input]
12268os.mkfifo
12269
12270 path: path_t
12271 mode: int=0o666
12272 *
12273 dir_fd: dir_fd(requires='mkfifoat')=None
12274
12275Create a "fifo" (a POSIX named pipe).
12276
12277If dir_fd is not None, it should be a file descriptor open to a directory,
12278 and path should be relative; path will then be relative to that directory.
12279dir_fd may not be implemented on your platform.
12280 If it is unavailable, using it will raise a NotImplementedError.
12281[clinic start generated code]*/
12282
12283PyDoc_STRVAR(os_mkfifo__doc__,
12284"mkfifo($module, /, path, mode=438, *, dir_fd=None)\n"
12285"--\n"
12286"\n"
12287"Create a \"fifo\" (a POSIX named pipe).\n"
12288"\n"
12289"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
12290" and path should be relative; path will then be relative to that directory.\n"
12291"dir_fd may not be implemented on your platform.\n"
12292" If it is unavailable, using it will raise a NotImplementedError.");
12293
12294#define OS_MKFIFO_METHODDEF \
12295 {"mkfifo", (PyCFunction)os_mkfifo, METH_VARARGS|METH_KEYWORDS, os_mkfifo__doc__},
12296
12297static PyObject *
12298os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd);
12299
12300static PyObject *
12301os_mkfifo(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12302{
12303 PyObject *return_value = NULL;
12304 static char *_keywords[] = {"path", "mode", "dir_fd", NULL};
12305 path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0);
12306 int mode = 438;
12307 int dir_fd = DEFAULT_DIR_FD;
12308
12309 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
12310 "O&|i$O&:mkfifo", _keywords,
12311 path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd))
12312 goto exit;
12313 return_value = os_mkfifo_impl(module, &path, mode, dir_fd);
12314
12315exit:
12316 /* Cleanup for path */
12317 path_cleanup(&path);
12318
12319 return return_value;
12320}
12321
12322static PyObject *
12323os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
12324/*[clinic end generated code: output=b3321927546893d0 input=73032e98a36e0e19]*/
12325{
12326 int result;
12327
12328 Py_BEGIN_ALLOW_THREADS
12329#ifdef HAVE_MKFIFOAT
12330 if (dir_fd != DEFAULT_DIR_FD)
12331 result = mkfifoat(dir_fd, path->narrow, mode);
12332 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020012333#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012334 result = mkfifo(path->narrow, mode);
12335 Py_END_ALLOW_THREADS
12336
12337 if (result < 0)
12338 return posix_error();
12339
12340 Py_RETURN_NONE;
12341}
12342#endif /* HAVE_MKFIFO */
12343
12344
12345#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
12346/*[clinic input]
12347os.mknod
12348
12349 path: path_t
12350 mode: int=0o600
12351 device: int=0
12352 *
12353 dir_fd: dir_fd(requires='mknodat')=None
12354
12355Create a node in the file system.
12356
12357Create a node in the file system (file, device special file or named pipe)
12358at path. mode specifies both the permissions to use and the
12359type of node to be created, being combined (bitwise OR) with one of
12360S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
12361device defines the newly created device special file (probably using
12362os.makedev()). Otherwise device is ignored.
12363
12364If dir_fd is not None, it should be a file descriptor open to a directory,
12365 and path should be relative; path will then be relative to that directory.
12366dir_fd may not be implemented on your platform.
12367 If it is unavailable, using it will raise a NotImplementedError.
12368[clinic start generated code]*/
12369
12370PyDoc_STRVAR(os_mknod__doc__,
12371"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n"
12372"--\n"
12373"\n"
12374"Create a node in the file system.\n"
12375"\n"
12376"Create a node in the file system (file, device special file or named pipe)\n"
12377"at path. mode specifies both the permissions to use and the\n"
12378"type of node to be created, being combined (bitwise OR) with one of\n"
12379"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n"
12380"device defines the newly created device special file (probably using\n"
12381"os.makedev()). Otherwise device is ignored.\n"
12382"\n"
12383"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
12384" and path should be relative; path will then be relative to that directory.\n"
12385"dir_fd may not be implemented on your platform.\n"
12386" If it is unavailable, using it will raise a NotImplementedError.");
12387
12388#define OS_MKNOD_METHODDEF \
12389 {"mknod", (PyCFunction)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__},
12390
12391static PyObject *
12392os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd);
12393
12394static PyObject *
12395os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12396{
12397 PyObject *return_value = NULL;
12398 static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL};
12399 path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0);
12400 int mode = 384;
12401 int device = 0;
12402 int dir_fd = DEFAULT_DIR_FD;
12403
12404 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
12405 "O&|ii$O&:mknod", _keywords,
12406 path_converter, &path, &mode, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd))
12407 goto exit;
12408 return_value = os_mknod_impl(module, &path, mode, device, dir_fd);
12409
12410exit:
12411 /* Cleanup for path */
12412 path_cleanup(&path);
12413
12414 return return_value;
12415}
12416
12417static PyObject *
12418os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd)
12419/*[clinic end generated code: output=c688739c15ca7bbb input=30e02126aba9732e]*/
12420{
12421 int result;
12422
12423 Py_BEGIN_ALLOW_THREADS
12424#ifdef HAVE_MKNODAT
12425 if (dir_fd != DEFAULT_DIR_FD)
12426 result = mknodat(dir_fd, path->narrow, mode, device);
12427 else
12428#endif
12429 result = mknod(path->narrow, mode, device);
12430 Py_END_ALLOW_THREADS
12431
12432 if (result < 0)
12433 return posix_error();
12434
12435 Py_RETURN_NONE;
12436}
12437#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
12438
12439
12440#ifdef HAVE_DEVICE_MACROS
12441/*[clinic input]
12442os.major -> unsigned_int
12443
12444 device: int
12445 /
12446
12447Extracts a device major number from a raw device number.
12448[clinic start generated code]*/
12449
12450PyDoc_STRVAR(os_major__doc__,
12451"major($module, device, /)\n"
12452"--\n"
12453"\n"
12454"Extracts a device major number from a raw device number.");
12455
12456#define OS_MAJOR_METHODDEF \
12457 {"major", (PyCFunction)os_major, METH_VARARGS, os_major__doc__},
12458
12459static unsigned int
12460os_major_impl(PyModuleDef *module, int device);
12461
12462static PyObject *
12463os_major(PyModuleDef *module, PyObject *args)
12464{
12465 PyObject *return_value = NULL;
12466 int device;
12467 unsigned int _return_value;
12468
12469 if (!PyArg_ParseTuple(args,
12470 "i:major",
12471 &device))
12472 goto exit;
12473 _return_value = os_major_impl(module, device);
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012474 if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012475 goto exit;
12476 return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
12477
12478exit:
12479 return return_value;
12480}
12481
12482static unsigned int
12483os_major_impl(PyModuleDef *module, int device)
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012484/*[clinic end generated code: output=52e6743300dcf4ad input=ea48820b7e10d310]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012485{
12486 return major(device);
12487}
12488
12489
12490/*[clinic input]
12491os.minor -> unsigned_int
12492
12493 device: int
12494 /
12495
12496Extracts a device minor number from a raw device number.
12497[clinic start generated code]*/
12498
12499PyDoc_STRVAR(os_minor__doc__,
12500"minor($module, device, /)\n"
12501"--\n"
12502"\n"
12503"Extracts a device minor number from a raw device number.");
12504
12505#define OS_MINOR_METHODDEF \
12506 {"minor", (PyCFunction)os_minor, METH_VARARGS, os_minor__doc__},
12507
12508static unsigned int
12509os_minor_impl(PyModuleDef *module, int device);
12510
12511static PyObject *
12512os_minor(PyModuleDef *module, PyObject *args)
12513{
12514 PyObject *return_value = NULL;
12515 int device;
12516 unsigned int _return_value;
12517
12518 if (!PyArg_ParseTuple(args,
12519 "i:minor",
12520 &device))
12521 goto exit;
12522 _return_value = os_minor_impl(module, device);
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012523 if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012524 goto exit;
12525 return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
12526
12527exit:
12528 return return_value;
12529}
12530
12531static unsigned int
12532os_minor_impl(PyModuleDef *module, int device)
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012533/*[clinic end generated code: output=aebe4bd7f455b755 input=089733ebbf9754e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012534{
12535 return minor(device);
12536}
12537
12538
12539/*[clinic input]
12540os.makedev -> unsigned_int
12541
12542 major: int
12543 minor: int
12544 /
12545
12546Composes a raw device number from the major and minor device numbers.
12547[clinic start generated code]*/
12548
12549PyDoc_STRVAR(os_makedev__doc__,
12550"makedev($module, major, minor, /)\n"
12551"--\n"
12552"\n"
12553"Composes a raw device number from the major and minor device numbers.");
12554
12555#define OS_MAKEDEV_METHODDEF \
12556 {"makedev", (PyCFunction)os_makedev, METH_VARARGS, os_makedev__doc__},
12557
12558static unsigned int
12559os_makedev_impl(PyModuleDef *module, int major, int minor);
12560
12561static PyObject *
12562os_makedev(PyModuleDef *module, PyObject *args)
12563{
12564 PyObject *return_value = NULL;
12565 int major;
12566 int minor;
12567 unsigned int _return_value;
12568
12569 if (!PyArg_ParseTuple(args,
12570 "ii:makedev",
12571 &major, &minor))
12572 goto exit;
12573 _return_value = os_makedev_impl(module, major, minor);
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012574 if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +100012575 goto exit;
12576 return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
12577
12578exit:
12579 return return_value;
12580}
12581
12582static unsigned int
12583os_makedev_impl(PyModuleDef *module, int major, int minor)
Larry Hastingsa73cb8a2014-08-05 19:55:21 +100012584/*[clinic end generated code: output=5cb79d9c9eac58b0 input=f55bf7cffb028a08]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012585{
12586 return makedev(major, minor);
12587}
12588#endif /* HAVE_DEVICE_MACROS */
12589
12590
12591#ifdef HAVE_FTRUNCATE
12592/*[clinic input]
12593os.ftruncate
12594
12595 fd: int
12596 length: Py_off_t
12597 /
12598
12599Truncate a file, specified by file descriptor, to a specific length.
12600[clinic start generated code]*/
12601
12602PyDoc_STRVAR(os_ftruncate__doc__,
12603"ftruncate($module, fd, length, /)\n"
12604"--\n"
12605"\n"
12606"Truncate a file, specified by file descriptor, to a specific length.");
12607
12608#define OS_FTRUNCATE_METHODDEF \
12609 {"ftruncate", (PyCFunction)os_ftruncate, METH_VARARGS, os_ftruncate__doc__},
12610
12611static PyObject *
12612os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length);
12613
12614static PyObject *
12615os_ftruncate(PyModuleDef *module, PyObject *args)
12616{
12617 PyObject *return_value = NULL;
12618 int fd;
12619 Py_off_t length;
12620
12621 if (!PyArg_ParseTuple(args,
12622 "iO&:ftruncate",
12623 &fd, Py_off_t_converter, &length))
12624 goto exit;
12625 return_value = os_ftruncate_impl(module, fd, length);
12626
12627exit:
12628 return return_value;
12629}
12630
12631static PyObject *
12632os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
12633/*[clinic end generated code: output=62326766cb9b76bf input=63b43641e52818f2]*/
12634{
12635 int result;
12636
12637 Py_BEGIN_ALLOW_THREADS
12638 result = ftruncate(fd, length);
12639 Py_END_ALLOW_THREADS
12640 if (result < 0)
12641 return posix_error();
12642 Py_RETURN_NONE;
12643}
12644#endif /* HAVE_FTRUNCATE */
12645
12646
12647#ifdef HAVE_TRUNCATE
12648/*[clinic input]
12649os.truncate
12650 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
12651 length: Py_off_t
12652
12653Truncate a file, specified by path, to a specific length.
12654
12655On some platforms, path may also be specified as an open file descriptor.
12656 If this functionality is unavailable, using it raises an exception.
12657[clinic start generated code]*/
12658
12659PyDoc_STRVAR(os_truncate__doc__,
12660"truncate($module, /, path, length)\n"
12661"--\n"
12662"\n"
12663"Truncate a file, specified by path, to a specific length.\n"
12664"\n"
12665"On some platforms, path may also be specified as an open file descriptor.\n"
12666" If this functionality is unavailable, using it raises an exception.");
12667
12668#define OS_TRUNCATE_METHODDEF \
12669 {"truncate", (PyCFunction)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__},
12670
12671static PyObject *
12672os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length);
12673
12674static PyObject *
12675os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs)
12676{
12677 PyObject *return_value = NULL;
12678 static char *_keywords[] = {"path", "length", NULL};
12679 path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE);
12680 Py_off_t length;
12681
12682 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
12683 "O&O&:truncate", _keywords,
12684 path_converter, &path, Py_off_t_converter, &length))
12685 goto exit;
12686 return_value = os_truncate_impl(module, &path, length);
12687
12688exit:
12689 /* Cleanup for path */
12690 path_cleanup(&path);
12691
12692 return return_value;
12693}
12694
12695static PyObject *
12696os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
12697/*[clinic end generated code: output=6bd76262d2e027c6 input=77229cf0b50a9b77]*/
12698{
12699 int result;
12700
12701 Py_BEGIN_ALLOW_THREADS
12702#ifdef HAVE_FTRUNCATE
12703 if (path->fd != -1)
12704 result = ftruncate(path->fd, length);
12705 else
12706#endif
12707 result = truncate(path->narrow, length);
12708 Py_END_ALLOW_THREADS
12709 if (result < 0)
12710 return path_error(path);
12711
12712 Py_RETURN_NONE;
12713}
12714#endif /* HAVE_TRUNCATE */
12715
Ross Lagerwall7807c352011-03-17 20:20:30 +020012716
Victor Stinnerd6b17692014-09-30 12:20:05 +020012717/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
12718 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
12719 defined, which is the case in Python on AIX. AIX bug report:
12720 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
12721#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
12722# define POSIX_FADVISE_AIX_BUG
12723#endif
12724
Victor Stinnerec39e262014-09-30 12:35:58 +020012725
Victor Stinnerd6b17692014-09-30 12:20:05 +020012726#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100012727/*[clinic input]
12728os.posix_fallocate
12729
12730 fd: int
12731 offset: Py_off_t
12732 length: Py_off_t
12733 /
12734
12735Ensure a file has allocated at least a particular number of bytes on disk.
12736
12737Ensure that the file specified by fd encompasses a range of bytes
12738starting at offset bytes from the beginning and continuing for length bytes.
12739[clinic start generated code]*/
12740
12741PyDoc_STRVAR(os_posix_fallocate__doc__,
12742"posix_fallocate($module, fd, offset, length, /)\n"
12743"--\n"
12744"\n"
12745"Ensure a file has allocated at least a particular number of bytes on disk.\n"
12746"\n"
12747"Ensure that the file specified by fd encompasses a range of bytes\n"
12748"starting at offset bytes from the beginning and continuing for length bytes.");
12749
12750#define OS_POSIX_FALLOCATE_METHODDEF \
12751 {"posix_fallocate", (PyCFunction)os_posix_fallocate, METH_VARARGS, os_posix_fallocate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020012752
12753static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012754os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012755
Larry Hastings2f936352014-08-05 14:04:04 +100012756static PyObject *
12757os_posix_fallocate(PyModuleDef *module, PyObject *args)
12758{
12759 PyObject *return_value = NULL;
12760 int fd;
12761 Py_off_t offset;
12762 Py_off_t length;
12763
12764 if (!PyArg_ParseTuple(args,
12765 "iO&O&:posix_fallocate",
12766 &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length))
12767 goto exit;
12768 return_value = os_posix_fallocate_impl(module, fd, offset, length);
12769
12770exit:
12771 return return_value;
12772}
12773
12774static PyObject *
12775os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length)
12776/*[clinic end generated code: output=0cd702d2065c79db input=d7a2ef0ab2ca52fb]*/
12777{
12778 int result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012779
12780 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012781 result = posix_fallocate(fd, offset, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012782 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012783 if (result != 0) {
12784 errno = result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012785 return posix_error();
12786 }
12787 Py_RETURN_NONE;
12788}
Victor Stinnerec39e262014-09-30 12:35:58 +020012789#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100012790
Ross Lagerwall7807c352011-03-17 20:20:30 +020012791
Victor Stinnerd6b17692014-09-30 12:20:05 +020012792#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100012793/*[clinic input]
12794os.posix_fadvise
12795
12796 fd: int
12797 offset: Py_off_t
12798 length: Py_off_t
12799 advice: int
12800 /
12801
12802Announce an intention to access data in a specific pattern.
12803
12804Announce an intention to access data in a specific pattern, thus allowing
12805the kernel to make optimizations.
12806The advice applies to the region of the file specified by fd starting at
12807offset and continuing for length bytes.
12808advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
12809POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
12810POSIX_FADV_DONTNEED.
12811[clinic start generated code]*/
12812
12813PyDoc_STRVAR(os_posix_fadvise__doc__,
12814"posix_fadvise($module, fd, offset, length, advice, /)\n"
12815"--\n"
12816"\n"
12817"Announce an intention to access data in a specific pattern.\n"
12818"\n"
12819"Announce an intention to access data in a specific pattern, thus allowing\n"
12820"the kernel to make optimizations.\n"
12821"The advice applies to the region of the file specified by fd starting at\n"
12822"offset and continuing for length bytes.\n"
12823"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n"
12824"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n"
12825"POSIX_FADV_DONTNEED.");
12826
12827#define OS_POSIX_FADVISE_METHODDEF \
12828 {"posix_fadvise", (PyCFunction)os_posix_fadvise, METH_VARARGS, os_posix_fadvise__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020012829
12830static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012831os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012832
Larry Hastings2f936352014-08-05 14:04:04 +100012833static PyObject *
12834os_posix_fadvise(PyModuleDef *module, PyObject *args)
12835{
12836 PyObject *return_value = NULL;
12837 int fd;
12838 Py_off_t offset;
12839 Py_off_t length;
12840 int advice;
12841
12842 if (!PyArg_ParseTuple(args,
12843 "iO&O&i:posix_fadvise",
12844 &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice))
12845 goto exit;
12846 return_value = os_posix_fadvise_impl(module, fd, offset, length, advice);
12847
12848exit:
12849 return return_value;
12850}
12851
12852static PyObject *
12853os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice)
12854/*[clinic end generated code: output=dad93f32c04dd4f7 input=0fbe554edc2f04b5]*/
12855{
12856 int result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012857
12858 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012859 result = posix_fadvise(fd, offset, length, advice);
Ross Lagerwall7807c352011-03-17 20:20:30 +020012860 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100012861 if (result != 0) {
12862 errno = result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012863 return posix_error();
12864 }
12865 Py_RETURN_NONE;
12866}
Victor Stinnerec39e262014-09-30 12:35:58 +020012867#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020012868
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012869#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000012870
Fred Drake762e2061999-08-26 17:23:54 +000012871/* Save putenv() parameters as values here, so we can collect them when they
12872 * get re-set with another call for the same key. */
12873static PyObject *posix_putenv_garbage;
12874
Larry Hastings2f936352014-08-05 14:04:04 +100012875static void
12876posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012877{
Larry Hastings2f936352014-08-05 14:04:04 +100012878 /* Install the first arg and newstr in posix_putenv_garbage;
12879 * this will cause previous value to be collected. This has to
12880 * happen after the real putenv() call because the old value
12881 * was still accessible until then. */
12882 if (PyDict_SetItem(posix_putenv_garbage, name, value))
12883 /* really not much we can do; just leak */
12884 PyErr_Clear();
12885 else
12886 Py_DECREF(value);
12887}
12888
12889
Thomas Hellerf78f12a2007-11-08 19:33:05 +000012890#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012891/*[clinic input]
12892os.putenv
12893
12894 name: unicode
12895 value: unicode
12896 /
12897
12898Change or add an environment variable.
12899[clinic start generated code]*/
12900
12901PyDoc_STRVAR(os_putenv__doc__,
12902"putenv($module, name, value, /)\n"
12903"--\n"
12904"\n"
12905"Change or add an environment variable.");
12906
12907#define OS_PUTENV_METHODDEF \
12908 {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__},
12909
12910static PyObject *
12911os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value);
12912
12913static PyObject *
12914os_putenv(PyModuleDef *module, PyObject *args)
12915{
12916 PyObject *return_value = NULL;
12917 PyObject *name;
12918 PyObject *value;
Victor Stinner65170952011-11-22 22:16:17 +010012919
Victor Stinner8c62be82010-05-06 00:08:46 +000012920 if (!PyArg_ParseTuple(args,
Larry Hastings2f936352014-08-05 14:04:04 +100012921 "UU:putenv",
12922 &name, &value))
12923 goto exit;
12924 return_value = os_putenv_impl(module, name, value);
Guido van Rossumd48f2521997-12-05 22:19:34 +000012925
Larry Hastings2f936352014-08-05 14:04:04 +100012926exit:
12927 return return_value;
12928}
12929
12930static PyObject *
12931os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
12932/*[clinic end generated code: output=5ce9ef9b15606e7e input=ba586581c2e6105f]*/
12933{
12934 wchar_t *env;
12935
12936 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
12937 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +000012938 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +100012939 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +000012940 }
Larry Hastings2f936352014-08-05 14:04:04 +100012941 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +010012942 PyErr_Format(PyExc_ValueError,
12943 "the environment variable is longer than %u characters",
12944 _MAX_ENV);
12945 goto error;
12946 }
12947
Larry Hastings2f936352014-08-05 14:04:04 +100012948 env = PyUnicode_AsUnicode(unicode);
12949 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +020012950 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +100012951 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012952 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +000012953 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +000012954 }
Guido van Rossuma4916fa1996-05-23 22:58:55 +000012955
Larry Hastings2f936352014-08-05 14:04:04 +100012956 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +000012957 Py_RETURN_NONE;
12958
12959error:
Larry Hastings2f936352014-08-05 14:04:04 +100012960 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +000012961 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000012962}
Larry Hastings2f936352014-08-05 14:04:04 +100012963#else /* MS_WINDOWS */
12964/*[clinic input]
12965os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000012966
Larry Hastings2f936352014-08-05 14:04:04 +100012967 name: FSConverter
12968 value: FSConverter
12969 /
12970
12971Change or add an environment variable.
12972[clinic start generated code]*/
12973
12974PyDoc_STRVAR(os_putenv__doc__,
12975"putenv($module, name, value, /)\n"
12976"--\n"
12977"\n"
12978"Change or add an environment variable.");
12979
12980#define OS_PUTENV_METHODDEF \
12981 {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000012982
12983static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100012984os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value);
12985
12986static PyObject *
12987os_putenv(PyModuleDef *module, PyObject *args)
Guido van Rossumc524d952001-10-19 01:31:59 +000012988{
Larry Hastings2f936352014-08-05 14:04:04 +100012989 PyObject *return_value = NULL;
12990 PyObject *name = NULL;
12991 PyObject *value = NULL;
12992
12993 if (!PyArg_ParseTuple(args,
12994 "O&O&:putenv",
12995 PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value))
12996 goto exit;
12997 return_value = os_putenv_impl(module, name, value);
12998
12999exit:
13000 /* Cleanup for name */
13001 Py_XDECREF(name);
13002 /* Cleanup for value */
13003 Py_XDECREF(value);
13004
13005 return return_value;
13006}
13007
13008static PyObject *
13009os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
13010/*[clinic end generated code: output=85ab223393dc7afd input=a97bc6152f688d31]*/
13011{
13012 PyObject *bytes = NULL;
13013 char *env;
13014 char *name_string = PyBytes_AsString(name);
13015 char *value_string = PyBytes_AsString(value);
13016
13017 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
13018 if (bytes == NULL) {
13019 PyErr_NoMemory();
13020 return NULL;
13021 }
13022
13023 env = PyBytes_AS_STRING(bytes);
13024 if (putenv(env)) {
13025 Py_DECREF(bytes);
13026 return posix_error();
13027 }
13028
13029 posix_putenv_garbage_setitem(name, bytes);
13030 Py_RETURN_NONE;
13031}
13032#endif /* MS_WINDOWS */
13033#endif /* HAVE_PUTENV */
13034
13035
13036#ifdef HAVE_UNSETENV
13037/*[clinic input]
13038os.unsetenv
13039 name: FSConverter
13040 /
13041
13042Delete an environment variable.
13043[clinic start generated code]*/
13044
13045PyDoc_STRVAR(os_unsetenv__doc__,
13046"unsetenv($module, name, /)\n"
13047"--\n"
13048"\n"
13049"Delete an environment variable.");
13050
13051#define OS_UNSETENV_METHODDEF \
13052 {"unsetenv", (PyCFunction)os_unsetenv, METH_VARARGS, os_unsetenv__doc__},
13053
13054static PyObject *
13055os_unsetenv_impl(PyModuleDef *module, PyObject *name);
13056
13057static PyObject *
13058os_unsetenv(PyModuleDef *module, PyObject *args)
13059{
13060 PyObject *return_value = NULL;
13061 PyObject *name = NULL;
13062
13063 if (!PyArg_ParseTuple(args,
13064 "O&:unsetenv",
13065 PyUnicode_FSConverter, &name))
13066 goto exit;
13067 return_value = os_unsetenv_impl(module, name);
13068
13069exit:
13070 /* Cleanup for name */
13071 Py_XDECREF(name);
13072
13073 return return_value;
13074}
13075
13076static PyObject *
13077os_unsetenv_impl(PyModuleDef *module, PyObject *name)
13078/*[clinic end generated code: output=91318c995f9a0767 input=2bb5288a599c7107]*/
13079{
Victor Stinner984890f2011-11-24 13:53:38 +010013080#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010013081 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010013082#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000013083
Victor Stinner984890f2011-11-24 13:53:38 +010013084#ifdef HAVE_BROKEN_UNSETENV
13085 unsetenv(PyBytes_AS_STRING(name));
13086#else
Victor Stinner65170952011-11-22 22:16:17 +010013087 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100013088 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010013089 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010013090#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000013091
Victor Stinner8c62be82010-05-06 00:08:46 +000013092 /* Remove the key from posix_putenv_garbage;
13093 * this will cause it to be collected. This has to
13094 * happen after the real unsetenv() call because the
13095 * old value was still accessible until then.
13096 */
Victor Stinner65170952011-11-22 22:16:17 +010013097 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000013098 /* really not much we can do; just leak */
13099 PyErr_Clear();
13100 }
Victor Stinner84ae1182010-05-06 22:05:07 +000013101 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000013102}
Larry Hastings2f936352014-08-05 14:04:04 +100013103#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000013104
Larry Hastings2f936352014-08-05 14:04:04 +100013105
13106/*[clinic input]
13107os.strerror
13108
13109 code: int
13110 /
13111
13112Translate an error code to a message string.
13113[clinic start generated code]*/
13114
13115PyDoc_STRVAR(os_strerror__doc__,
13116"strerror($module, code, /)\n"
13117"--\n"
13118"\n"
13119"Translate an error code to a message string.");
13120
13121#define OS_STRERROR_METHODDEF \
13122 {"strerror", (PyCFunction)os_strerror, METH_VARARGS, os_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +000013123
Guido van Rossumf68d8e52001-04-14 17:55:09 +000013124static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013125os_strerror_impl(PyModuleDef *module, int code);
13126
13127static PyObject *
13128os_strerror(PyModuleDef *module, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +000013129{
Larry Hastings2f936352014-08-05 14:04:04 +100013130 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013131 int code;
Larry Hastings2f936352014-08-05 14:04:04 +100013132
13133 if (!PyArg_ParseTuple(args,
13134 "i:strerror",
13135 &code))
13136 goto exit;
13137 return_value = os_strerror_impl(module, code);
13138
13139exit:
13140 return return_value;
13141}
13142
13143static PyObject *
13144os_strerror_impl(PyModuleDef *module, int code)
13145/*[clinic end generated code: output=8665c70bb2ca4720 input=75a8673d97915a91]*/
13146{
13147 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000013148 if (message == NULL) {
13149 PyErr_SetString(PyExc_ValueError,
13150 "strerror() argument out of range");
13151 return NULL;
13152 }
Victor Stinner1b579672011-12-17 05:47:23 +010013153 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000013154}
Guido van Rossumb6a47161997-09-15 22:54:34 +000013155
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000013156
Guido van Rossumc9641791998-08-04 15:26:23 +000013157#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000013158#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100013159/*[clinic input]
13160os.WCOREDUMP -> bool
13161
13162 status: int
13163 /
13164
13165Return True if the process returning status was dumped to a core file.
13166[clinic start generated code]*/
13167
13168PyDoc_STRVAR(os_WCOREDUMP__doc__,
13169"WCOREDUMP($module, status, /)\n"
13170"--\n"
13171"\n"
13172"Return True if the process returning status was dumped to a core file.");
13173
13174#define OS_WCOREDUMP_METHODDEF \
13175 {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_VARARGS, os_WCOREDUMP__doc__},
13176
13177static int
13178os_WCOREDUMP_impl(PyModuleDef *module, int status);
Fred Drake106c1a02002-04-23 15:58:02 +000013179
13180static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013181os_WCOREDUMP(PyModuleDef *module, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +000013182{
Larry Hastings2f936352014-08-05 14:04:04 +100013183 PyObject *return_value = NULL;
13184 int status;
13185 int _return_value;
Fred Drake106c1a02002-04-23 15:58:02 +000013186
Larry Hastings2f936352014-08-05 14:04:04 +100013187 if (!PyArg_ParseTuple(args,
13188 "i:WCOREDUMP",
13189 &status))
13190 goto exit;
13191 _return_value = os_WCOREDUMP_impl(module, status);
13192 if ((_return_value == -1) && PyErr_Occurred())
13193 goto exit;
13194 return_value = PyBool_FromLong((long)_return_value);
Fred Drake106c1a02002-04-23 15:58:02 +000013195
Larry Hastings2f936352014-08-05 14:04:04 +100013196exit:
13197 return return_value;
13198}
13199
13200static int
13201os_WCOREDUMP_impl(PyModuleDef *module, int status)
13202/*[clinic end generated code: output=e04d55c09c299828 input=8b05e7ab38528d04]*/
13203{
13204 WAIT_TYPE wait_status;
13205 WAIT_STATUS_INT(wait_status) = status;
13206 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000013207}
13208#endif /* WCOREDUMP */
13209
Larry Hastings2f936352014-08-05 14:04:04 +100013210
Fred Drake106c1a02002-04-23 15:58:02 +000013211#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100013212/*[clinic input]
13213os.WIFCONTINUED -> bool
13214
13215 status: int
13216
13217Return True if a particular process was continued from a job control stop.
13218
13219Return True if the process returning status was continued from a
13220job control stop.
13221[clinic start generated code]*/
13222
13223PyDoc_STRVAR(os_WIFCONTINUED__doc__,
13224"WIFCONTINUED($module, /, status)\n"
13225"--\n"
13226"\n"
13227"Return True if a particular process was continued from a job control stop.\n"
13228"\n"
13229"Return True if the process returning status was continued from a\n"
13230"job control stop.");
13231
13232#define OS_WIFCONTINUED_METHODDEF \
13233 {"WIFCONTINUED", (PyCFunction)os_WIFCONTINUED, METH_VARARGS|METH_KEYWORDS, os_WIFCONTINUED__doc__},
13234
13235static int
13236os_WIFCONTINUED_impl(PyModuleDef *module, int status);
Fred Drake106c1a02002-04-23 15:58:02 +000013237
13238static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013239os_WIFCONTINUED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Fred Drake106c1a02002-04-23 15:58:02 +000013240{
Larry Hastings2f936352014-08-05 14:04:04 +100013241 PyObject *return_value = NULL;
13242 static char *_keywords[] = {"status", NULL};
13243 int status;
13244 int _return_value;
Fred Drake106c1a02002-04-23 15:58:02 +000013245
Larry Hastings2f936352014-08-05 14:04:04 +100013246 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13247 "i:WIFCONTINUED", _keywords,
13248 &status))
13249 goto exit;
13250 _return_value = os_WIFCONTINUED_impl(module, status);
13251 if ((_return_value == -1) && PyErr_Occurred())
13252 goto exit;
13253 return_value = PyBool_FromLong((long)_return_value);
Fred Drake106c1a02002-04-23 15:58:02 +000013254
Larry Hastings2f936352014-08-05 14:04:04 +100013255exit:
13256 return return_value;
13257}
13258
13259static int
13260os_WIFCONTINUED_impl(PyModuleDef *module, int status)
13261/*[clinic end generated code: output=9c4e6105a4520ab5 input=e777e7d38eb25bd9]*/
13262{
13263 WAIT_TYPE wait_status;
13264 WAIT_STATUS_INT(wait_status) = status;
13265 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000013266}
13267#endif /* WIFCONTINUED */
13268
Larry Hastings2f936352014-08-05 14:04:04 +100013269
Guido van Rossumc9641791998-08-04 15:26:23 +000013270#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100013271/*[clinic input]
13272os.WIFSTOPPED -> bool
13273
13274 status: int
13275
13276Return True if the process returning status was stopped.
13277[clinic start generated code]*/
13278
13279PyDoc_STRVAR(os_WIFSTOPPED__doc__,
13280"WIFSTOPPED($module, /, status)\n"
13281"--\n"
13282"\n"
13283"Return True if the process returning status was stopped.");
13284
13285#define OS_WIFSTOPPED_METHODDEF \
13286 {"WIFSTOPPED", (PyCFunction)os_WIFSTOPPED, METH_VARARGS|METH_KEYWORDS, os_WIFSTOPPED__doc__},
13287
13288static int
13289os_WIFSTOPPED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013290
13291static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013292os_WIFSTOPPED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013293{
Larry Hastings2f936352014-08-05 14:04:04 +100013294 PyObject *return_value = NULL;
13295 static char *_keywords[] = {"status", NULL};
13296 int status;
13297 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013298
Larry Hastings2f936352014-08-05 14:04:04 +100013299 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13300 "i:WIFSTOPPED", _keywords,
13301 &status))
13302 goto exit;
13303 _return_value = os_WIFSTOPPED_impl(module, status);
13304 if ((_return_value == -1) && PyErr_Occurred())
13305 goto exit;
13306 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013307
Larry Hastings2f936352014-08-05 14:04:04 +100013308exit:
13309 return return_value;
13310}
13311
13312static int
13313os_WIFSTOPPED_impl(PyModuleDef *module, int status)
13314/*[clinic end generated code: output=e0de2da8ec9593ff input=043cb7f1289ef904]*/
13315{
13316 WAIT_TYPE wait_status;
13317 WAIT_STATUS_INT(wait_status) = status;
13318 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013319}
13320#endif /* WIFSTOPPED */
13321
Larry Hastings2f936352014-08-05 14:04:04 +100013322
Guido van Rossumc9641791998-08-04 15:26:23 +000013323#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100013324/*[clinic input]
13325os.WIFSIGNALED -> bool
13326
13327 status: int
13328
13329Return True if the process returning status was terminated by a signal.
13330[clinic start generated code]*/
13331
13332PyDoc_STRVAR(os_WIFSIGNALED__doc__,
13333"WIFSIGNALED($module, /, status)\n"
13334"--\n"
13335"\n"
13336"Return True if the process returning status was terminated by a signal.");
13337
13338#define OS_WIFSIGNALED_METHODDEF \
13339 {"WIFSIGNALED", (PyCFunction)os_WIFSIGNALED, METH_VARARGS|METH_KEYWORDS, os_WIFSIGNALED__doc__},
13340
13341static int
13342os_WIFSIGNALED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013343
13344static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013345os_WIFSIGNALED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013346{
Larry Hastings2f936352014-08-05 14:04:04 +100013347 PyObject *return_value = NULL;
13348 static char *_keywords[] = {"status", NULL};
13349 int status;
13350 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013351
Larry Hastings2f936352014-08-05 14:04:04 +100013352 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13353 "i:WIFSIGNALED", _keywords,
13354 &status))
13355 goto exit;
13356 _return_value = os_WIFSIGNALED_impl(module, status);
13357 if ((_return_value == -1) && PyErr_Occurred())
13358 goto exit;
13359 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013360
Larry Hastings2f936352014-08-05 14:04:04 +100013361exit:
13362 return return_value;
13363}
13364
13365static int
13366os_WIFSIGNALED_impl(PyModuleDef *module, int status)
13367/*[clinic end generated code: output=f14d106558f406be input=d55ba7cc9ce5dc43]*/
13368{
13369 WAIT_TYPE wait_status;
13370 WAIT_STATUS_INT(wait_status) = status;
13371 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013372}
13373#endif /* WIFSIGNALED */
13374
Larry Hastings2f936352014-08-05 14:04:04 +100013375
Guido van Rossumc9641791998-08-04 15:26:23 +000013376#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100013377/*[clinic input]
13378os.WIFEXITED -> bool
13379
13380 status: int
13381
13382Return True if the process returning status exited via the exit() system call.
13383[clinic start generated code]*/
13384
13385PyDoc_STRVAR(os_WIFEXITED__doc__,
13386"WIFEXITED($module, /, status)\n"
13387"--\n"
13388"\n"
13389"Return True if the process returning status exited via the exit() system call.");
13390
13391#define OS_WIFEXITED_METHODDEF \
13392 {"WIFEXITED", (PyCFunction)os_WIFEXITED, METH_VARARGS|METH_KEYWORDS, os_WIFEXITED__doc__},
13393
13394static int
13395os_WIFEXITED_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013396
13397static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013398os_WIFEXITED(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013399{
Larry Hastings2f936352014-08-05 14:04:04 +100013400 PyObject *return_value = NULL;
13401 static char *_keywords[] = {"status", NULL};
13402 int status;
13403 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013404
Larry Hastings2f936352014-08-05 14:04:04 +100013405 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13406 "i:WIFEXITED", _keywords,
13407 &status))
13408 goto exit;
13409 _return_value = os_WIFEXITED_impl(module, status);
13410 if ((_return_value == -1) && PyErr_Occurred())
13411 goto exit;
13412 return_value = PyBool_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013413
Larry Hastings2f936352014-08-05 14:04:04 +100013414exit:
13415 return return_value;
13416}
13417
13418static int
13419os_WIFEXITED_impl(PyModuleDef *module, int status)
13420/*[clinic end generated code: output=2f76087d53721255 input=d63775a6791586c0]*/
13421{
13422 WAIT_TYPE wait_status;
13423 WAIT_STATUS_INT(wait_status) = status;
13424 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013425}
13426#endif /* WIFEXITED */
13427
Larry Hastings2f936352014-08-05 14:04:04 +100013428
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000013429#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100013430/*[clinic input]
13431os.WEXITSTATUS -> int
13432
13433 status: int
13434
13435Return the process return code from status.
13436[clinic start generated code]*/
13437
13438PyDoc_STRVAR(os_WEXITSTATUS__doc__,
13439"WEXITSTATUS($module, /, status)\n"
13440"--\n"
13441"\n"
13442"Return the process return code from status.");
13443
13444#define OS_WEXITSTATUS_METHODDEF \
13445 {"WEXITSTATUS", (PyCFunction)os_WEXITSTATUS, METH_VARARGS|METH_KEYWORDS, os_WEXITSTATUS__doc__},
13446
13447static int
13448os_WEXITSTATUS_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013449
13450static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013451os_WEXITSTATUS(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013452{
Larry Hastings2f936352014-08-05 14:04:04 +100013453 PyObject *return_value = NULL;
13454 static char *_keywords[] = {"status", NULL};
13455 int status;
13456 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013457
Larry Hastings2f936352014-08-05 14:04:04 +100013458 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13459 "i:WEXITSTATUS", _keywords,
13460 &status))
13461 goto exit;
13462 _return_value = os_WEXITSTATUS_impl(module, status);
13463 if ((_return_value == -1) && PyErr_Occurred())
13464 goto exit;
13465 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013466
Larry Hastings2f936352014-08-05 14:04:04 +100013467exit:
13468 return return_value;
13469}
13470
13471static int
13472os_WEXITSTATUS_impl(PyModuleDef *module, int status)
13473/*[clinic end generated code: output=13b6c270e2a326b1 input=e1fb4944e377585b]*/
13474{
13475 WAIT_TYPE wait_status;
13476 WAIT_STATUS_INT(wait_status) = status;
13477 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013478}
13479#endif /* WEXITSTATUS */
13480
Larry Hastings2f936352014-08-05 14:04:04 +100013481
Guido van Rossumc9641791998-08-04 15:26:23 +000013482#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100013483/*[clinic input]
13484os.WTERMSIG -> int
13485
13486 status: int
13487
13488Return the signal that terminated the process that provided the status value.
13489[clinic start generated code]*/
13490
13491PyDoc_STRVAR(os_WTERMSIG__doc__,
13492"WTERMSIG($module, /, status)\n"
13493"--\n"
13494"\n"
13495"Return the signal that terminated the process that provided the status value.");
13496
13497#define OS_WTERMSIG_METHODDEF \
13498 {"WTERMSIG", (PyCFunction)os_WTERMSIG, METH_VARARGS|METH_KEYWORDS, os_WTERMSIG__doc__},
13499
13500static int
13501os_WTERMSIG_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013502
13503static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013504os_WTERMSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013505{
Larry Hastings2f936352014-08-05 14:04:04 +100013506 PyObject *return_value = NULL;
13507 static char *_keywords[] = {"status", NULL};
13508 int status;
13509 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013510
Larry Hastings2f936352014-08-05 14:04:04 +100013511 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13512 "i:WTERMSIG", _keywords,
13513 &status))
13514 goto exit;
13515 _return_value = os_WTERMSIG_impl(module, status);
13516 if ((_return_value == -1) && PyErr_Occurred())
13517 goto exit;
13518 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013519
Larry Hastings2f936352014-08-05 14:04:04 +100013520exit:
13521 return return_value;
13522}
13523
13524static int
13525os_WTERMSIG_impl(PyModuleDef *module, int status)
13526/*[clinic end generated code: output=bf1fd4b002d0a9ed input=727fd7f84ec3f243]*/
13527{
13528 WAIT_TYPE wait_status;
13529 WAIT_STATUS_INT(wait_status) = status;
13530 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013531}
13532#endif /* WTERMSIG */
13533
Larry Hastings2f936352014-08-05 14:04:04 +100013534
Guido van Rossumc9641791998-08-04 15:26:23 +000013535#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100013536/*[clinic input]
13537os.WSTOPSIG -> int
13538
13539 status: int
13540
13541Return the signal that stopped the process that provided the status value.
13542[clinic start generated code]*/
13543
13544PyDoc_STRVAR(os_WSTOPSIG__doc__,
13545"WSTOPSIG($module, /, status)\n"
13546"--\n"
13547"\n"
13548"Return the signal that stopped the process that provided the status value.");
13549
13550#define OS_WSTOPSIG_METHODDEF \
13551 {"WSTOPSIG", (PyCFunction)os_WSTOPSIG, METH_VARARGS|METH_KEYWORDS, os_WSTOPSIG__doc__},
13552
13553static int
13554os_WSTOPSIG_impl(PyModuleDef *module, int status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013555
13556static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013557os_WSTOPSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Guido van Rossumc9641791998-08-04 15:26:23 +000013558{
Larry Hastings2f936352014-08-05 14:04:04 +100013559 PyObject *return_value = NULL;
13560 static char *_keywords[] = {"status", NULL};
13561 int status;
13562 int _return_value;
Tim Peters5aa91602002-01-30 05:46:57 +000013563
Larry Hastings2f936352014-08-05 14:04:04 +100013564 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13565 "i:WSTOPSIG", _keywords,
13566 &status))
13567 goto exit;
13568 _return_value = os_WSTOPSIG_impl(module, status);
13569 if ((_return_value == -1) && PyErr_Occurred())
13570 goto exit;
13571 return_value = PyLong_FromLong((long)_return_value);
Tim Peters5aa91602002-01-30 05:46:57 +000013572
Larry Hastings2f936352014-08-05 14:04:04 +100013573exit:
13574 return return_value;
13575}
13576
13577static int
13578os_WSTOPSIG_impl(PyModuleDef *module, int status)
13579/*[clinic end generated code: output=92e1647d29ee0549 input=46ebf1d1b293c5c1]*/
13580{
13581 WAIT_TYPE wait_status;
13582 WAIT_STATUS_INT(wait_status) = status;
13583 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000013584}
13585#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000013586#endif /* HAVE_SYS_WAIT_H */
13587
13588
Larry Hastings2f936352014-08-05 14:04:04 +100013589#ifndef OS_WCOREDUMP_METHODDEF
13590#define OS_WCOREDUMP_METHODDEF
13591#endif /* OS_WCOREDUMP_METHODDEF */
13592
13593#ifndef OS_WIFCONTINUED_METHODDEF
13594#define OS_WIFCONTINUED_METHODDEF
13595#endif /* OS_WIFCONTINUED_METHODDEF */
13596
13597#ifndef OS_WIFSTOPPED_METHODDEF
13598#define OS_WIFSTOPPED_METHODDEF
13599#endif /* OS_WIFSTOPPED_METHODDEF */
13600
13601#ifndef OS_WIFSIGNALED_METHODDEF
13602#define OS_WIFSIGNALED_METHODDEF
13603#endif /* OS_WIFSIGNALED_METHODDEF */
13604
13605#ifndef OS_WIFEXITED_METHODDEF
13606#define OS_WIFEXITED_METHODDEF
13607#endif /* OS_WIFEXITED_METHODDEF */
13608
13609#ifndef OS_WEXITSTATUS_METHODDEF
13610#define OS_WEXITSTATUS_METHODDEF
13611#endif /* OS_WEXITSTATUS_METHODDEF */
13612
13613#ifndef OS_WTERMSIG_METHODDEF
13614#define OS_WTERMSIG_METHODDEF
13615#endif /* OS_WTERMSIG_METHODDEF */
13616
13617#ifndef OS_WSTOPSIG_METHODDEF
13618#define OS_WSTOPSIG_METHODDEF
13619#endif /* OS_WSTOPSIG_METHODDEF */
13620
13621
Thomas Wouters477c8d52006-05-27 19:21:47 +000013622#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000013623#ifdef _SCO_DS
13624/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
13625 needed definitions in sys/statvfs.h */
13626#define _SVID3
13627#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013628#include <sys/statvfs.h>
13629
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013630static PyObject*
13631_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +000013632 PyObject *v = PyStructSequence_New(&StatVFSResultType);
13633 if (v == NULL)
13634 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013635
13636#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000013637 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
13638 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
13639 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
13640 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
13641 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
13642 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
13643 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
13644 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
13645 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
13646 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013647#else
Victor Stinner8c62be82010-05-06 00:08:46 +000013648 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
13649 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
13650 PyStructSequence_SET_ITEM(v, 2,
13651 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
13652 PyStructSequence_SET_ITEM(v, 3,
13653 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
13654 PyStructSequence_SET_ITEM(v, 4,
13655 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
13656 PyStructSequence_SET_ITEM(v, 5,
13657 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
13658 PyStructSequence_SET_ITEM(v, 6,
13659 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
13660 PyStructSequence_SET_ITEM(v, 7,
13661 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
13662 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
13663 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013664#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010013665 if (PyErr_Occurred()) {
13666 Py_DECREF(v);
13667 return NULL;
13668 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013669
Victor Stinner8c62be82010-05-06 00:08:46 +000013670 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013671}
13672
Larry Hastings2f936352014-08-05 14:04:04 +100013673
13674/*[clinic input]
13675os.fstatvfs
13676 fd: int
13677 /
13678
13679Perform an fstatvfs system call on the given fd.
13680
13681Equivalent to statvfs(fd).
13682[clinic start generated code]*/
13683
13684PyDoc_STRVAR(os_fstatvfs__doc__,
13685"fstatvfs($module, fd, /)\n"
13686"--\n"
13687"\n"
13688"Perform an fstatvfs system call on the given fd.\n"
13689"\n"
13690"Equivalent to statvfs(fd).");
13691
13692#define OS_FSTATVFS_METHODDEF \
13693 {"fstatvfs", (PyCFunction)os_fstatvfs, METH_VARARGS, os_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000013694
13695static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013696os_fstatvfs_impl(PyModuleDef *module, int fd);
13697
13698static PyObject *
13699os_fstatvfs(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +000013700{
Larry Hastings2f936352014-08-05 14:04:04 +100013701 PyObject *return_value = NULL;
13702 int fd;
13703
13704 if (!PyArg_ParseTuple(args,
13705 "i:fstatvfs",
13706 &fd))
13707 goto exit;
13708 return_value = os_fstatvfs_impl(module, fd);
13709
13710exit:
13711 return return_value;
13712}
13713
13714static PyObject *
13715os_fstatvfs_impl(PyModuleDef *module, int fd)
13716/*[clinic end generated code: output=0e32bf07f946ec0d input=d8122243ac50975e]*/
13717{
13718 int result;
Victor Stinner8c62be82010-05-06 00:08:46 +000013719 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013720
Victor Stinner8c62be82010-05-06 00:08:46 +000013721 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100013722 result = fstatvfs(fd, &st);
Victor Stinner8c62be82010-05-06 00:08:46 +000013723 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100013724 if (result != 0)
Victor Stinner8c62be82010-05-06 00:08:46 +000013725 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013726
Victor Stinner8c62be82010-05-06 00:08:46 +000013727 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000013728}
Larry Hastings2f936352014-08-05 14:04:04 +100013729#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000013730
13731
Thomas Wouters477c8d52006-05-27 19:21:47 +000013732#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000013733#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100013734/*[clinic input]
13735os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000013736
Larry Hastings2f936352014-08-05 14:04:04 +100013737 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
13738
13739Perform a statvfs system call on the given path.
13740
13741path may always be specified as a string.
13742On some platforms, path may also be specified as an open file descriptor.
13743 If this functionality is unavailable, using it raises an exception.
13744[clinic start generated code]*/
13745
13746PyDoc_STRVAR(os_statvfs__doc__,
13747"statvfs($module, /, path)\n"
13748"--\n"
13749"\n"
13750"Perform a statvfs system call on the given path.\n"
13751"\n"
13752"path may always be specified as a string.\n"
13753"On some platforms, path may also be specified as an open file descriptor.\n"
13754" If this functionality is unavailable, using it raises an exception.");
13755
13756#define OS_STATVFS_METHODDEF \
13757 {"statvfs", (PyCFunction)os_statvfs, METH_VARARGS|METH_KEYWORDS, os_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000013758
13759static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013760os_statvfs_impl(PyModuleDef *module, path_t *path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013761
Larry Hastings2f936352014-08-05 14:04:04 +100013762static PyObject *
13763os_statvfs(PyModuleDef *module, PyObject *args, PyObject *kwargs)
13764{
13765 PyObject *return_value = NULL;
13766 static char *_keywords[] = {"path", NULL};
13767 path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS);
13768
13769 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13770 "O&:statvfs", _keywords,
13771 path_converter, &path))
13772 goto exit;
13773 return_value = os_statvfs_impl(module, &path);
13774
13775exit:
13776 /* Cleanup for path */
13777 path_cleanup(&path);
13778
13779 return return_value;
13780}
13781
13782static PyObject *
13783os_statvfs_impl(PyModuleDef *module, path_t *path)
13784/*[clinic end generated code: output=00ff54983360b446 input=3f5c35791c669bd9]*/
13785{
13786 int result;
13787 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013788
13789 Py_BEGIN_ALLOW_THREADS
13790#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100013791 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013792#ifdef __APPLE__
13793 /* handle weak-linking on Mac OS X 10.3 */
13794 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100013795 fd_specified("statvfs", path->fd);
13796 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013797 }
13798#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013799 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013800 }
13801 else
13802#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013803 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013804 Py_END_ALLOW_THREADS
13805
13806 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100013807 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013808 }
13809
Larry Hastings2f936352014-08-05 14:04:04 +100013810 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000013811}
Larry Hastings2f936352014-08-05 14:04:04 +100013812#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
13813
Guido van Rossum94f6f721999-01-06 18:42:14 +000013814
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013815#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013816/*[clinic input]
13817os._getdiskusage
13818
13819 path: Py_UNICODE
13820
13821Return disk usage statistics about the given path as a (total, free) tuple.
13822[clinic start generated code]*/
13823
13824PyDoc_STRVAR(os__getdiskusage__doc__,
13825"_getdiskusage($module, /, path)\n"
13826"--\n"
13827"\n"
13828"Return disk usage statistics about the given path as a (total, free) tuple.");
13829
13830#define OS__GETDISKUSAGE_METHODDEF \
13831 {"_getdiskusage", (PyCFunction)os__getdiskusage, METH_VARARGS|METH_KEYWORDS, os__getdiskusage__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013832
13833static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100013834os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path);
13835
13836static PyObject *
13837os__getdiskusage(PyModuleDef *module, PyObject *args, PyObject *kwargs)
13838{
13839 PyObject *return_value = NULL;
13840 static char *_keywords[] = {"path", NULL};
13841 Py_UNICODE *path;
13842
13843 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
13844 "u:_getdiskusage", _keywords,
13845 &path))
13846 goto exit;
13847 return_value = os__getdiskusage_impl(module, path);
13848
13849exit:
13850 return return_value;
13851}
13852
13853static PyObject *
13854os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
13855/*[clinic end generated code: output=054c972179b13708 input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013856{
13857 BOOL retval;
13858 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013859
13860 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +010013861 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013862 Py_END_ALLOW_THREADS
13863 if (retval == 0)
13864 return PyErr_SetFromWindowsErr(0);
13865
13866 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
13867}
Larry Hastings2f936352014-08-05 14:04:04 +100013868#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020013869
13870
Fred Drakec9680921999-12-13 16:37:25 +000013871/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
13872 * It maps strings representing configuration variable names to
13873 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000013874 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000013875 * rarely-used constants. There are three separate tables that use
13876 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000013877 *
13878 * This code is always included, even if none of the interfaces that
13879 * need it are included. The #if hackery needed to avoid it would be
13880 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000013881 */
13882struct constdef {
13883 char *name;
13884 long value;
13885};
13886
Fred Drake12c6e2d1999-12-14 21:25:03 +000013887static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000013888conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000013889 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000013890{
Christian Heimes217cfd12007-12-02 14:31:20 +000013891 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +000013892 *valuep = PyLong_AS_LONG(arg);
13893 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000013894 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000013895 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000013896 /* look up the value in the table using a binary search */
13897 size_t lo = 0;
13898 size_t mid;
13899 size_t hi = tablesize;
13900 int cmp;
13901 const char *confname;
13902 if (!PyUnicode_Check(arg)) {
13903 PyErr_SetString(PyExc_TypeError,
13904 "configuration names must be strings or integers");
13905 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000013906 }
Stefan Krah0e803b32010-11-26 16:16:47 +000013907 confname = _PyUnicode_AsString(arg);
13908 if (confname == NULL)
13909 return 0;
13910 while (lo < hi) {
13911 mid = (lo + hi) / 2;
13912 cmp = strcmp(confname, table[mid].name);
13913 if (cmp < 0)
13914 hi = mid;
13915 else if (cmp > 0)
13916 lo = mid + 1;
13917 else {
13918 *valuep = table[mid].value;
13919 return 1;
13920 }
13921 }
13922 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
13923 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000013924 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000013925}
13926
13927
13928#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
13929static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000013930#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013931 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000013932#endif
13933#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013934 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000013935#endif
Fred Drakec9680921999-12-13 16:37:25 +000013936#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013937 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013938#endif
13939#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000013940 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000013941#endif
13942#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000013943 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000013944#endif
13945#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000013946 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000013947#endif
13948#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013949 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013950#endif
13951#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000013952 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000013953#endif
13954#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000013955 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000013956#endif
13957#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013958 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013959#endif
13960#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013961 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000013962#endif
13963#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000013964 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000013965#endif
13966#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000013967 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000013968#endif
13969#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013970 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013971#endif
13972#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000013973 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000013974#endif
13975#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000013976 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000013977#endif
13978#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000013979 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000013980#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000013981#ifdef _PC_ACL_ENABLED
13982 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
13983#endif
13984#ifdef _PC_MIN_HOLE_SIZE
13985 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
13986#endif
13987#ifdef _PC_ALLOC_SIZE_MIN
13988 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
13989#endif
13990#ifdef _PC_REC_INCR_XFER_SIZE
13991 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
13992#endif
13993#ifdef _PC_REC_MAX_XFER_SIZE
13994 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
13995#endif
13996#ifdef _PC_REC_MIN_XFER_SIZE
13997 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
13998#endif
13999#ifdef _PC_REC_XFER_ALIGN
14000 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
14001#endif
14002#ifdef _PC_SYMLINK_MAX
14003 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
14004#endif
14005#ifdef _PC_XATTR_ENABLED
14006 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
14007#endif
14008#ifdef _PC_XATTR_EXISTS
14009 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
14010#endif
14011#ifdef _PC_TIMESTAMP_RESOLUTION
14012 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
14013#endif
Fred Drakec9680921999-12-13 16:37:25 +000014014};
14015
Fred Drakec9680921999-12-13 16:37:25 +000014016static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014017conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000014018{
14019 return conv_confname(arg, valuep, posix_constants_pathconf,
14020 sizeof(posix_constants_pathconf)
14021 / sizeof(struct constdef));
14022}
14023#endif
14024
Larry Hastings2f936352014-08-05 14:04:04 +100014025
Fred Drakec9680921999-12-13 16:37:25 +000014026#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100014027/*[clinic input]
14028os.fpathconf -> long
14029
14030 fd: int
14031 name: path_confname
14032 /
14033
14034Return the configuration limit name for the file descriptor fd.
14035
14036If there is no limit, return -1.
14037[clinic start generated code]*/
14038
14039PyDoc_STRVAR(os_fpathconf__doc__,
14040"fpathconf($module, fd, name, /)\n"
14041"--\n"
14042"\n"
14043"Return the configuration limit name for the file descriptor fd.\n"
14044"\n"
14045"If there is no limit, return -1.");
14046
14047#define OS_FPATHCONF_METHODDEF \
14048 {"fpathconf", (PyCFunction)os_fpathconf, METH_VARARGS, os_fpathconf__doc__},
14049
14050static long
14051os_fpathconf_impl(PyModuleDef *module, int fd, int name);
Fred Drakec9680921999-12-13 16:37:25 +000014052
14053static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014054os_fpathconf(PyModuleDef *module, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000014055{
Larry Hastings2f936352014-08-05 14:04:04 +100014056 PyObject *return_value = NULL;
14057 int fd;
14058 int name;
14059 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014060
Larry Hastings2f936352014-08-05 14:04:04 +100014061 if (!PyArg_ParseTuple(args,
14062 "iO&:fpathconf",
14063 &fd, conv_path_confname, &name))
14064 goto exit;
14065 _return_value = os_fpathconf_impl(module, fd, name);
14066 if ((_return_value == -1) && PyErr_Occurred())
14067 goto exit;
14068 return_value = PyLong_FromLong(_return_value);
Fred Drakec9680921999-12-13 16:37:25 +000014069
Larry Hastings2f936352014-08-05 14:04:04 +100014070exit:
14071 return return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014072}
Larry Hastings2f936352014-08-05 14:04:04 +100014073
14074static long
14075os_fpathconf_impl(PyModuleDef *module, int fd, int name)
14076/*[clinic end generated code: output=3bf04b40e0523a8c input=5942a024d3777810]*/
14077{
14078 long limit;
14079
14080 errno = 0;
14081 limit = fpathconf(fd, name);
14082 if (limit == -1 && errno != 0)
14083 posix_error();
14084
14085 return limit;
14086}
14087#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000014088
14089
14090#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100014091/*[clinic input]
14092os.pathconf -> long
14093 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
14094 name: path_confname
14095
14096Return the configuration limit name for the file or directory path.
14097
14098If there is no limit, return -1.
14099On some platforms, path may also be specified as an open file descriptor.
14100 If this functionality is unavailable, using it raises an exception.
14101[clinic start generated code]*/
14102
14103PyDoc_STRVAR(os_pathconf__doc__,
14104"pathconf($module, /, path, name)\n"
14105"--\n"
14106"\n"
14107"Return the configuration limit name for the file or directory path.\n"
14108"\n"
14109"If there is no limit, return -1.\n"
14110"On some platforms, path may also be specified as an open file descriptor.\n"
14111" If this functionality is unavailable, using it raises an exception.");
14112
14113#define OS_PATHCONF_METHODDEF \
14114 {"pathconf", (PyCFunction)os_pathconf, METH_VARARGS|METH_KEYWORDS, os_pathconf__doc__},
14115
14116static long
14117os_pathconf_impl(PyModuleDef *module, path_t *path, int name);
Fred Drakec9680921999-12-13 16:37:25 +000014118
14119static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014120os_pathconf(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +000014121{
Larry Hastings2f936352014-08-05 14:04:04 +100014122 PyObject *return_value = NULL;
14123 static char *_keywords[] = {"path", "name", NULL};
14124 path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF);
Fred Drakec9680921999-12-13 16:37:25 +000014125 int name;
Larry Hastings2f936352014-08-05 14:04:04 +100014126 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014127
Larry Hastings2f936352014-08-05 14:04:04 +100014128 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
14129 "O&O&:pathconf", _keywords,
14130 path_converter, &path, conv_path_confname, &name))
14131 goto exit;
14132 _return_value = os_pathconf_impl(module, &path, name);
14133 if ((_return_value == -1) && PyErr_Occurred())
14134 goto exit;
14135 return_value = PyLong_FromLong(_return_value);
14136
14137exit:
14138 /* Cleanup for path */
14139 path_cleanup(&path);
14140
14141 return return_value;
14142}
14143
14144static long
14145os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
14146/*[clinic end generated code: output=1a53e125b6cf63e4 input=bc3e2a985af27e5e]*/
14147{
Victor Stinner8c62be82010-05-06 00:08:46 +000014148 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000014149
Victor Stinner8c62be82010-05-06 00:08:46 +000014150 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020014151#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100014152 if (path->fd != -1)
14153 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020014154 else
14155#endif
Larry Hastings2f936352014-08-05 14:04:04 +100014156 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000014157 if (limit == -1 && errno != 0) {
14158 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000014159 /* could be a path or name problem */
14160 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000014161 else
Larry Hastings2f936352014-08-05 14:04:04 +100014162 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000014163 }
Larry Hastings2f936352014-08-05 14:04:04 +100014164
14165 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000014166}
Larry Hastings2f936352014-08-05 14:04:04 +100014167#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000014168
14169#ifdef HAVE_CONFSTR
14170static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000014171#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000014172 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000014173#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000014174#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014175 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000014176#endif
14177#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014178 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000014179#endif
Fred Draked86ed291999-12-15 15:34:33 +000014180#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014181 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000014182#endif
14183#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000014184 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000014185#endif
14186#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014187 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000014188#endif
14189#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014190 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014191#endif
Fred Drakec9680921999-12-13 16:37:25 +000014192#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014193 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014194#endif
14195#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014196 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014197#endif
14198#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014199 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014200#endif
14201#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014202 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014203#endif
14204#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014205 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014206#endif
14207#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014208 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014209#endif
14210#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014211 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014212#endif
14213#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014214 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014215#endif
Fred Draked86ed291999-12-15 15:34:33 +000014216#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000014217 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000014218#endif
Fred Drakec9680921999-12-13 16:37:25 +000014219#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000014220 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000014221#endif
Fred Draked86ed291999-12-15 15:34:33 +000014222#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000014223 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000014224#endif
14225#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014226 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000014227#endif
14228#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014229 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000014230#endif
14231#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014232 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000014233#endif
Fred Drakec9680921999-12-13 16:37:25 +000014234#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014235 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014236#endif
14237#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014238 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014239#endif
14240#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014241 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014242#endif
14243#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014244 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014245#endif
14246#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014247 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014248#endif
14249#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014250 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014251#endif
14252#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014253 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014254#endif
14255#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014256 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014257#endif
14258#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014259 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014260#endif
14261#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014262 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014263#endif
14264#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014265 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014266#endif
14267#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014268 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014269#endif
14270#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014271 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014272#endif
14273#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014274 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014275#endif
14276#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000014277 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000014278#endif
14279#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000014280 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000014281#endif
Fred Draked86ed291999-12-15 15:34:33 +000014282#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014283 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014284#endif
14285#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000014286 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000014287#endif
14288#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000014289 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000014290#endif
14291#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014292 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014293#endif
14294#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014295 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014296#endif
14297#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000014298 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000014299#endif
14300#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014301 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000014302#endif
14303#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000014304 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000014305#endif
14306#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000014307 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000014308#endif
14309#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000014310 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000014311#endif
14312#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000014313 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000014314#endif
14315#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014316 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000014317#endif
14318#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000014319 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000014320#endif
Fred Drakec9680921999-12-13 16:37:25 +000014321};
14322
14323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014324conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000014325{
14326 return conv_confname(arg, valuep, posix_constants_confstr,
14327 sizeof(posix_constants_confstr)
14328 / sizeof(struct constdef));
14329}
14330
Larry Hastings2f936352014-08-05 14:04:04 +100014331
14332/*[clinic input]
14333os.confstr
14334
14335 name: confstr_confname
14336 /
14337
14338Return a string-valued system configuration variable.
14339[clinic start generated code]*/
14340
14341PyDoc_STRVAR(os_confstr__doc__,
14342"confstr($module, name, /)\n"
14343"--\n"
14344"\n"
14345"Return a string-valued system configuration variable.");
14346
14347#define OS_CONFSTR_METHODDEF \
14348 {"confstr", (PyCFunction)os_confstr, METH_VARARGS, os_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000014349
14350static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014351os_confstr_impl(PyModuleDef *module, int name);
14352
14353static PyObject *
14354os_confstr(PyModuleDef *module, PyObject *args)
14355{
14356 PyObject *return_value = NULL;
14357 int name;
14358
14359 if (!PyArg_ParseTuple(args,
14360 "O&:confstr",
14361 conv_confstr_confname, &name))
14362 goto exit;
14363 return_value = os_confstr_impl(module, name);
14364
14365exit:
14366 return return_value;
14367}
14368
14369static PyObject *
14370os_confstr_impl(PyModuleDef *module, int name)
14371/*[clinic end generated code: output=3f5e8aba9f8e3174 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000014372{
14373 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000014374 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020014375 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000014376
Victor Stinnercb043522010-09-10 23:49:04 +000014377 errno = 0;
14378 len = confstr(name, buffer, sizeof(buffer));
14379 if (len == 0) {
14380 if (errno) {
14381 posix_error();
14382 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000014383 }
14384 else {
Victor Stinnercb043522010-09-10 23:49:04 +000014385 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000014386 }
14387 }
Victor Stinnercb043522010-09-10 23:49:04 +000014388
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020014389 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010014390 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000014391 char *buf = PyMem_Malloc(len);
14392 if (buf == NULL)
14393 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010014394 len2 = confstr(name, buf, len);
14395 assert(len == len2);
Victor Stinnercb043522010-09-10 23:49:04 +000014396 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
14397 PyMem_Free(buf);
14398 }
14399 else
14400 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000014401 return result;
14402}
Larry Hastings2f936352014-08-05 14:04:04 +100014403#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000014404
14405
14406#ifdef HAVE_SYSCONF
14407static struct constdef posix_constants_sysconf[] = {
14408#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000014409 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000014410#endif
14411#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000014412 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000014413#endif
14414#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014415 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014416#endif
14417#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014418 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014419#endif
14420#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014421 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014422#endif
14423#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000014424 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000014425#endif
14426#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014427 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000014428#endif
14429#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000014430 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000014431#endif
14432#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000014433 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000014434#endif
14435#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014436 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014437#endif
Fred Draked86ed291999-12-15 15:34:33 +000014438#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014439 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000014440#endif
14441#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000014442 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000014443#endif
Fred Drakec9680921999-12-13 16:37:25 +000014444#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014445 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014446#endif
Fred Drakec9680921999-12-13 16:37:25 +000014447#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014448 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014449#endif
14450#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014451 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014452#endif
14453#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014454 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014455#endif
14456#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014457 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014458#endif
14459#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014460 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014461#endif
Fred Draked86ed291999-12-15 15:34:33 +000014462#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014463 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000014464#endif
Fred Drakec9680921999-12-13 16:37:25 +000014465#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000014466 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000014467#endif
14468#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014469 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014470#endif
14471#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014472 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014473#endif
14474#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014475 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014476#endif
14477#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014478 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014479#endif
Fred Draked86ed291999-12-15 15:34:33 +000014480#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000014481 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000014482#endif
Fred Drakec9680921999-12-13 16:37:25 +000014483#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014484 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014485#endif
14486#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014487 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014488#endif
14489#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014490 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014491#endif
14492#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014493 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014494#endif
14495#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014496 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014497#endif
14498#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000014499 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000014500#endif
14501#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014502 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014503#endif
14504#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014505 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014506#endif
14507#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000014508 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000014509#endif
14510#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014511 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014512#endif
14513#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014514 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000014515#endif
14516#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014517 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000014518#endif
14519#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014520 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014521#endif
14522#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014523 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014524#endif
14525#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014526 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014527#endif
14528#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014529 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014530#endif
14531#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014532 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000014533#endif
14534#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014535 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014536#endif
14537#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014538 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014539#endif
14540#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000014541 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000014542#endif
14543#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014544 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000014545#endif
14546#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014547 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000014548#endif
14549#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000014550 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000014551#endif
Fred Draked86ed291999-12-15 15:34:33 +000014552#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000014553 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000014554#endif
Fred Drakec9680921999-12-13 16:37:25 +000014555#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014556 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014557#endif
14558#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014559 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014560#endif
14561#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014562 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014563#endif
Fred Draked86ed291999-12-15 15:34:33 +000014564#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014565 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000014566#endif
Fred Drakec9680921999-12-13 16:37:25 +000014567#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000014568 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000014569#endif
Fred Draked86ed291999-12-15 15:34:33 +000014570#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000014571 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000014572#endif
14573#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000014574 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000014575#endif
Fred Drakec9680921999-12-13 16:37:25 +000014576#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014577 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014578#endif
14579#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014580 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014581#endif
14582#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014583 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014584#endif
14585#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014586 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014587#endif
Fred Draked86ed291999-12-15 15:34:33 +000014588#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000014589 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000014590#endif
Fred Drakec9680921999-12-13 16:37:25 +000014591#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000014592 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000014593#endif
14594#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000014595 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000014596#endif
14597#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014598 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014599#endif
14600#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000014601 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000014602#endif
14603#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000014604 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000014605#endif
14606#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000014607 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000014608#endif
14609#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000014610 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000014611#endif
Fred Draked86ed291999-12-15 15:34:33 +000014612#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000014613 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000014614#endif
Fred Drakec9680921999-12-13 16:37:25 +000014615#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014616 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014617#endif
14618#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014619 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014620#endif
Fred Draked86ed291999-12-15 15:34:33 +000014621#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014622 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000014623#endif
Fred Drakec9680921999-12-13 16:37:25 +000014624#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014625 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014626#endif
14627#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014628 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014629#endif
14630#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014631 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014632#endif
14633#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014634 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014635#endif
14636#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014637 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014638#endif
14639#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014640 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014641#endif
14642#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014643 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000014644#endif
14645#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000014646 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000014647#endif
14648#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000014649 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000014650#endif
Fred Draked86ed291999-12-15 15:34:33 +000014651#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000014652 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000014653#endif
14654#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000014655 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000014656#endif
Fred Drakec9680921999-12-13 16:37:25 +000014657#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000014658 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000014659#endif
14660#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014661 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014662#endif
14663#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014664 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014665#endif
14666#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014667 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014668#endif
14669#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014670 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014671#endif
14672#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000014673 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000014674#endif
14675#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000014676 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000014677#endif
14678#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000014679 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000014680#endif
14681#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000014682 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000014683#endif
14684#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000014685 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000014686#endif
14687#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000014688 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000014689#endif
14690#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014691 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000014692#endif
14693#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014694 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000014695#endif
14696#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000014697 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000014698#endif
14699#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000014700 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000014701#endif
14702#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000014703 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000014704#endif
14705#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000014706 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000014707#endif
14708#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014709 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014710#endif
14711#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000014712 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000014713#endif
14714#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000014715 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000014716#endif
14717#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014718 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014719#endif
14720#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014721 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014722#endif
14723#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000014724 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000014725#endif
14726#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014727 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014728#endif
14729#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014730 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014731#endif
14732#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014733 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000014734#endif
14735#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000014736 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000014737#endif
14738#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014739 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014740#endif
14741#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014742 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014743#endif
14744#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000014745 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000014746#endif
14747#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014748 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014749#endif
14750#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014751 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014752#endif
14753#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014754 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014755#endif
14756#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014757 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014758#endif
14759#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014760 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014761#endif
Fred Draked86ed291999-12-15 15:34:33 +000014762#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000014763 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000014764#endif
Fred Drakec9680921999-12-13 16:37:25 +000014765#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000014766 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000014767#endif
14768#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014769 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014770#endif
14771#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000014772 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000014773#endif
14774#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014775 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014776#endif
14777#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000014778 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000014779#endif
14780#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000014781 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000014782#endif
14783#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000014784 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000014785#endif
14786#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000014787 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000014788#endif
14789#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000014790 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000014791#endif
14792#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014793 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014794#endif
14795#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000014796 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000014797#endif
14798#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014799 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000014800#endif
14801#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014802 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000014803#endif
14804#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000014805 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000014806#endif
14807#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000014808 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000014809#endif
14810#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000014811 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000014812#endif
14813#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014814 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014815#endif
14816#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000014817 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000014818#endif
14819#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014820 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014821#endif
14822#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014823 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014824#endif
14825#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014826 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014827#endif
14828#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014829 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014830#endif
14831#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014832 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014833#endif
14834#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014835 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014836#endif
14837#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000014838 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000014839#endif
14840#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014841 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014842#endif
14843#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000014844 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000014845#endif
14846#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014847 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014848#endif
14849#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014850 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000014851#endif
14852#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000014853 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000014854#endif
14855#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000014856 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000014857#endif
14858#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000014859 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000014860#endif
14861#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000014862 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000014863#endif
14864#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000014865 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000014866#endif
14867#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000014868 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000014869#endif
14870#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000014871 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000014872#endif
14873#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014874 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000014875#endif
14876#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000014877 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000014878#endif
14879#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000014880 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000014881#endif
14882#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000014883 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000014884#endif
14885#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014886 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014887#endif
14888#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000014889 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000014890#endif
14891#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000014892 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000014893#endif
14894#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000014895 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000014896#endif
14897#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000014898 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000014899#endif
14900};
14901
14902static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014903conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000014904{
14905 return conv_confname(arg, valuep, posix_constants_sysconf,
14906 sizeof(posix_constants_sysconf)
14907 / sizeof(struct constdef));
14908}
14909
Larry Hastings2f936352014-08-05 14:04:04 +100014910
14911/*[clinic input]
14912os.sysconf -> long
14913 name: sysconf_confname
14914 /
14915
14916Return an integer-valued system configuration variable.
14917[clinic start generated code]*/
14918
14919PyDoc_STRVAR(os_sysconf__doc__,
14920"sysconf($module, name, /)\n"
14921"--\n"
14922"\n"
14923"Return an integer-valued system configuration variable.");
14924
14925#define OS_SYSCONF_METHODDEF \
14926 {"sysconf", (PyCFunction)os_sysconf, METH_VARARGS, os_sysconf__doc__},
14927
14928static long
14929os_sysconf_impl(PyModuleDef *module, int name);
Fred Drakec9680921999-12-13 16:37:25 +000014930
14931static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100014932os_sysconf(PyModuleDef *module, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000014933{
Larry Hastings2f936352014-08-05 14:04:04 +100014934 PyObject *return_value = NULL;
Fred Drakec9680921999-12-13 16:37:25 +000014935 int name;
Larry Hastings2f936352014-08-05 14:04:04 +100014936 long _return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014937
Larry Hastings2f936352014-08-05 14:04:04 +100014938 if (!PyArg_ParseTuple(args,
14939 "O&:sysconf",
14940 conv_sysconf_confname, &name))
14941 goto exit;
14942 _return_value = os_sysconf_impl(module, name);
14943 if ((_return_value == -1) && PyErr_Occurred())
14944 goto exit;
14945 return_value = PyLong_FromLong(_return_value);
Fred Drakec9680921999-12-13 16:37:25 +000014946
Larry Hastings2f936352014-08-05 14:04:04 +100014947exit:
14948 return return_value;
Fred Drakec9680921999-12-13 16:37:25 +000014949}
Larry Hastings2f936352014-08-05 14:04:04 +100014950
14951static long
14952os_sysconf_impl(PyModuleDef *module, int name)
14953/*[clinic end generated code: output=7b06dfdc472431e4 input=279e3430a33f29e4]*/
14954{
14955 long value;
14956
14957 errno = 0;
14958 value = sysconf(name);
14959 if (value == -1 && errno != 0)
14960 posix_error();
14961 return value;
14962}
14963#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000014964
14965
Fred Drakebec628d1999-12-15 18:31:10 +000014966/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020014967 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000014968 * the exported dictionaries that are used to publish information about the
14969 * names available on the host platform.
14970 *
14971 * Sorting the table at runtime ensures that the table is properly ordered
14972 * when used, even for platforms we're not able to test on. It also makes
14973 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000014974 */
Fred Drakebec628d1999-12-15 18:31:10 +000014975
14976static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014977cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000014978{
14979 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000014980 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000014981 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000014982 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000014983
14984 return strcmp(c1->name, c2->name);
14985}
14986
14987static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000014988setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000014989 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000014990{
Fred Drakebec628d1999-12-15 18:31:10 +000014991 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000014992 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000014993
14994 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
14995 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000014996 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000014997 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000014998
Barry Warsaw3155db32000-04-13 15:20:40 +000014999 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000015000 PyObject *o = PyLong_FromLong(table[i].value);
15001 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
15002 Py_XDECREF(o);
15003 Py_DECREF(d);
15004 return -1;
15005 }
15006 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000015007 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000015008 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000015009}
15010
Fred Drakebec628d1999-12-15 18:31:10 +000015011/* Return -1 on failure, 0 on success. */
15012static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000015013setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000015014{
15015#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000015016 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000015017 sizeof(posix_constants_pathconf)
15018 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000015019 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000015020 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000015021#endif
15022#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000015023 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000015024 sizeof(posix_constants_confstr)
15025 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000015026 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000015027 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000015028#endif
15029#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000015030 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000015031 sizeof(posix_constants_sysconf)
15032 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000015033 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000015034 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000015035#endif
Fred Drakebec628d1999-12-15 18:31:10 +000015036 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000015037}
Fred Draked86ed291999-12-15 15:34:33 +000015038
15039
Larry Hastings2f936352014-08-05 14:04:04 +100015040/*[clinic input]
15041os.abort
15042
15043Abort the interpreter immediately.
15044
15045This function 'dumps core' or otherwise fails in the hardest way possible
15046on the hosting operating system. This function never returns.
15047[clinic start generated code]*/
15048
15049PyDoc_STRVAR(os_abort__doc__,
15050"abort($module, /)\n"
15051"--\n"
15052"\n"
15053"Abort the interpreter immediately.\n"
15054"\n"
15055"This function \'dumps core\' or otherwise fails in the hardest way possible\n"
15056"on the hosting operating system. This function never returns.");
15057
15058#define OS_ABORT_METHODDEF \
15059 {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000015060
15061static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015062os_abort_impl(PyModuleDef *module);
15063
15064static PyObject *
15065os_abort(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15066{
15067 return os_abort_impl(module);
15068}
15069
15070static PyObject *
15071os_abort_impl(PyModuleDef *module)
15072/*[clinic end generated code: output=cded2cc8c5453d3a input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000015073{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000015074 abort();
15075 /*NOTREACHED*/
15076 Py_FatalError("abort() called from Python code didn't abort!");
15077 return NULL;
15078}
Fred Drakebec628d1999-12-15 18:31:10 +000015079
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000015080#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100015081/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000015082PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100015083"startfile(filepath [, operation])\n\
15084\n\
15085Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000015086\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000015087When \"operation\" is not specified or \"open\", this acts like\n\
15088double-clicking the file in Explorer, or giving the file name as an\n\
15089argument to the DOS \"start\" command: the file is opened with whatever\n\
15090application (if any) its extension is associated.\n\
15091When another \"operation\" is given, it specifies what should be done with\n\
15092the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000015093\n\
15094startfile returns as soon as the associated application is launched.\n\
15095There is no option to wait for the application to close, and no way\n\
15096to retrieve the application's exit status.\n\
15097\n\
15098The filepath is relative to the current directory. If you want to use\n\
15099an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000015100the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000015101
15102static PyObject *
15103win32_startfile(PyObject *self, PyObject *args)
15104{
Victor Stinner8c62be82010-05-06 00:08:46 +000015105 PyObject *ofilepath;
15106 char *filepath;
15107 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020015108 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000015109 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000015110
Victor Stinnereb5657a2011-09-30 01:44:27 +020015111 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000015112 if (!PyArg_ParseTuple(args, "U|s:startfile",
15113 &unipath, &operation)) {
15114 PyErr_Clear();
15115 goto normal;
15116 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000015117
Victor Stinner8c62be82010-05-06 00:08:46 +000015118 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020015119 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000015120 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020015121 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000015122 PyErr_Clear();
15123 operation = NULL;
15124 goto normal;
15125 }
15126 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000015127
Victor Stinnereb5657a2011-09-30 01:44:27 +020015128 wpath = PyUnicode_AsUnicode(unipath);
15129 if (wpath == NULL)
15130 goto normal;
15131 if (uoperation) {
15132 woperation = PyUnicode_AsUnicode(uoperation);
15133 if (woperation == NULL)
15134 goto normal;
15135 }
15136 else
15137 woperation = NULL;
15138
Victor Stinner8c62be82010-05-06 00:08:46 +000015139 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020015140 rc = ShellExecuteW((HWND)0, woperation, wpath,
15141 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000015142 Py_END_ALLOW_THREADS
15143
Victor Stinnereb5657a2011-09-30 01:44:27 +020015144 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000015145 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020015146 win32_error_object("startfile", unipath);
15147 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000015148 }
15149 Py_INCREF(Py_None);
15150 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015151
15152normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000015153 if (!PyArg_ParseTuple(args, "O&|s:startfile",
15154 PyUnicode_FSConverter, &ofilepath,
15155 &operation))
15156 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010015157 if (win32_warn_bytes_api()) {
15158 Py_DECREF(ofilepath);
15159 return NULL;
15160 }
Victor Stinner8c62be82010-05-06 00:08:46 +000015161 filepath = PyBytes_AsString(ofilepath);
15162 Py_BEGIN_ALLOW_THREADS
15163 rc = ShellExecute((HWND)0, operation, filepath,
15164 NULL, NULL, SW_SHOWNORMAL);
15165 Py_END_ALLOW_THREADS
15166 if (rc <= (HINSTANCE)32) {
15167 PyObject *errval = win32_error("startfile", filepath);
15168 Py_DECREF(ofilepath);
15169 return errval;
15170 }
15171 Py_DECREF(ofilepath);
15172 Py_INCREF(Py_None);
15173 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000015174}
Larry Hastings2f936352014-08-05 14:04:04 +100015175#endif /* MS_WINDOWS */
15176
Fred Drake5ab8eaf1999-12-09 21:13:07 +000015177
Martin v. Löwis438b5342002-12-27 10:16:42 +000015178#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100015179/*[clinic input]
15180os.getloadavg
15181
15182Return average recent system load information.
15183
15184Return the number of processes in the system run queue averaged over
15185the last 1, 5, and 15 minutes as a tuple of three floats.
15186Raises OSError if the load average was unobtainable.
15187[clinic start generated code]*/
15188
15189PyDoc_STRVAR(os_getloadavg__doc__,
15190"getloadavg($module, /)\n"
15191"--\n"
15192"\n"
15193"Return average recent system load information.\n"
15194"\n"
15195"Return the number of processes in the system run queue averaged over\n"
15196"the last 1, 5, and 15 minutes as a tuple of three floats.\n"
15197"Raises OSError if the load average was unobtainable.");
15198
15199#define OS_GETLOADAVG_METHODDEF \
15200 {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000015201
15202static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015203os_getloadavg_impl(PyModuleDef *module);
15204
15205static PyObject *
15206os_getloadavg(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15207{
15208 return os_getloadavg_impl(module);
15209}
15210
15211static PyObject *
15212os_getloadavg_impl(PyModuleDef *module)
15213/*[clinic end generated code: output=67593a92457d55af input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000015214{
15215 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000015216 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000015217 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
15218 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000015219 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000015220 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000015221}
Larry Hastings2f936352014-08-05 14:04:04 +100015222#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000015223
Larry Hastings2f936352014-08-05 14:04:04 +100015224
15225/*[clinic input]
15226os.device_encoding
15227 fd: int
15228
15229Return a string describing the encoding of a terminal's file descriptor.
15230
15231The file descriptor must be attached to a terminal.
15232If the device is not a terminal, return None.
15233[clinic start generated code]*/
15234
15235PyDoc_STRVAR(os_device_encoding__doc__,
15236"device_encoding($module, /, fd)\n"
15237"--\n"
15238"\n"
15239"Return a string describing the encoding of a terminal\'s file descriptor.\n"
15240"\n"
15241"The file descriptor must be attached to a terminal.\n"
15242"If the device is not a terminal, return None.");
15243
15244#define OS_DEVICE_ENCODING_METHODDEF \
15245 {"device_encoding", (PyCFunction)os_device_encoding, METH_VARARGS|METH_KEYWORDS, os_device_encoding__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015246
15247static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015248os_device_encoding_impl(PyModuleDef *module, int fd);
15249
15250static PyObject *
15251os_device_encoding(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015252{
Larry Hastings2f936352014-08-05 14:04:04 +100015253 PyObject *return_value = NULL;
15254 static char *_keywords[] = {"fd", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +000015255 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050015256
Larry Hastings2f936352014-08-05 14:04:04 +100015257 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15258 "i:device_encoding", _keywords,
15259 &fd))
15260 goto exit;
15261 return_value = os_device_encoding_impl(module, fd);
Brett Cannonefb00c02012-02-29 18:31:31 -050015262
Larry Hastings2f936352014-08-05 14:04:04 +100015263exit:
15264 return return_value;
15265}
15266
15267static PyObject *
15268os_device_encoding_impl(PyModuleDef *module, int fd)
15269/*[clinic end generated code: output=e9f8274d42f5cce3 input=9e1d4a42b66df312]*/
15270{
Brett Cannonefb00c02012-02-29 18:31:31 -050015271 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000015272}
15273
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015274
Larry Hastings2f936352014-08-05 14:04:04 +100015275#ifdef HAVE_SETRESUID
15276/*[clinic input]
15277os.setresuid
15278
15279 ruid: uid_t
15280 euid: uid_t
15281 suid: uid_t
15282 /
15283
15284Set the current process's real, effective, and saved user ids.
15285[clinic start generated code]*/
15286
15287PyDoc_STRVAR(os_setresuid__doc__,
15288"setresuid($module, ruid, euid, suid, /)\n"
15289"--\n"
15290"\n"
15291"Set the current process\'s real, effective, and saved user ids.");
15292
15293#define OS_SETRESUID_METHODDEF \
15294 {"setresuid", (PyCFunction)os_setresuid, METH_VARARGS, os_setresuid__doc__},
15295
15296static PyObject *
15297os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid);
15298
15299static PyObject *
15300os_setresuid(PyModuleDef *module, PyObject *args)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015301{
Larry Hastings2f936352014-08-05 14:04:04 +100015302 PyObject *return_value = NULL;
15303 uid_t ruid;
15304 uid_t euid;
15305 uid_t suid;
15306
15307 if (!PyArg_ParseTuple(args,
15308 "O&O&O&:setresuid",
15309 _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid))
15310 goto exit;
15311 return_value = os_setresuid_impl(module, ruid, euid, suid);
15312
15313exit:
15314 return return_value;
15315}
15316
15317static PyObject *
15318os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
15319/*[clinic end generated code: output=2e3457cfe7cd1f94 input=9e33cb79a82792f3]*/
15320{
Victor Stinner8c62be82010-05-06 00:08:46 +000015321 if (setresuid(ruid, euid, suid) < 0)
15322 return posix_error();
15323 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015324}
Larry Hastings2f936352014-08-05 14:04:04 +100015325#endif /* HAVE_SETRESUID */
15326
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015327
15328#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100015329/*[clinic input]
15330os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015331
Larry Hastings2f936352014-08-05 14:04:04 +100015332 rgid: gid_t
15333 egid: gid_t
15334 sgid: gid_t
15335 /
15336
15337Set the current process's real, effective, and saved group ids.
15338[clinic start generated code]*/
15339
15340PyDoc_STRVAR(os_setresgid__doc__,
15341"setresgid($module, rgid, egid, sgid, /)\n"
15342"--\n"
15343"\n"
15344"Set the current process\'s real, effective, and saved group ids.");
15345
15346#define OS_SETRESGID_METHODDEF \
15347 {"setresgid", (PyCFunction)os_setresgid, METH_VARARGS, os_setresgid__doc__},
15348
15349static PyObject *
15350os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid);
15351
15352static PyObject *
15353os_setresgid(PyModuleDef *module, PyObject *args)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015354{
Larry Hastings2f936352014-08-05 14:04:04 +100015355 PyObject *return_value = NULL;
15356 gid_t rgid;
15357 gid_t egid;
15358 gid_t sgid;
15359
15360 if (!PyArg_ParseTuple(args,
15361 "O&O&O&:setresgid",
15362 _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid))
15363 goto exit;
15364 return_value = os_setresgid_impl(module, rgid, egid, sgid);
15365
15366exit:
15367 return return_value;
15368}
15369
15370static PyObject *
15371os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
15372/*[clinic end generated code: output=8a7ee6c1f2482362 input=33e9e0785ef426b1]*/
15373{
Victor Stinner8c62be82010-05-06 00:08:46 +000015374 if (setresgid(rgid, egid, sgid) < 0)
15375 return posix_error();
15376 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015377}
Larry Hastings2f936352014-08-05 14:04:04 +100015378#endif /* HAVE_SETRESGID */
15379
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015380
15381#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100015382/*[clinic input]
15383os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015384
Larry Hastings2f936352014-08-05 14:04:04 +100015385Return a tuple of the current process's real, effective, and saved user ids.
15386[clinic start generated code]*/
15387
15388PyDoc_STRVAR(os_getresuid__doc__,
15389"getresuid($module, /)\n"
15390"--\n"
15391"\n"
15392"Return a tuple of the current process\'s real, effective, and saved user ids.");
15393
15394#define OS_GETRESUID_METHODDEF \
15395 {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__},
15396
15397static PyObject *
15398os_getresuid_impl(PyModuleDef *module);
15399
15400static PyObject *
15401os_getresuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
15402{
15403 return os_getresuid_impl(module);
15404}
15405
15406static PyObject *
15407os_getresuid_impl(PyModuleDef *module)
15408/*[clinic end generated code: output=d0786686a6ef1320 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015409{
Victor Stinner8c62be82010-05-06 00:08:46 +000015410 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000015411 if (getresuid(&ruid, &euid, &suid) < 0)
15412 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020015413 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
15414 _PyLong_FromUid(euid),
15415 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015416}
Larry Hastings2f936352014-08-05 14:04:04 +100015417#endif /* HAVE_GETRESUID */
15418
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015419
15420#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100015421/*[clinic input]
15422os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015423
Larry Hastings2f936352014-08-05 14:04:04 +100015424Return a tuple of the current process's real, effective, and saved group ids.
15425[clinic start generated code]*/
15426
15427PyDoc_STRVAR(os_getresgid__doc__,
15428"getresgid($module, /)\n"
15429"--\n"
15430"\n"
15431"Return a tuple of the current process\'s real, effective, and saved group ids.");
15432
15433#define OS_GETRESGID_METHODDEF \
15434 {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__},
15435
15436static PyObject *
15437os_getresgid_impl(PyModuleDef *module);
15438
15439static PyObject *
15440os_getresgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015441{
Larry Hastings2f936352014-08-05 14:04:04 +100015442 return os_getresgid_impl(module);
15443}
15444
15445static PyObject *
15446os_getresgid_impl(PyModuleDef *module)
15447/*[clinic end generated code: output=05249ac795fa759f input=517e68db9ca32df6]*/
15448{
15449 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000015450 if (getresgid(&rgid, &egid, &sgid) < 0)
15451 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020015452 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
15453 _PyLong_FromGid(egid),
15454 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015455}
Larry Hastings2f936352014-08-05 14:04:04 +100015456#endif /* HAVE_GETRESGID */
15457
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000015458
Benjamin Peterson9428d532011-09-14 11:45:52 -040015459#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100015460/*[clinic input]
15461os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040015462
Larry Hastings2f936352014-08-05 14:04:04 +100015463 path: path_t(allow_fd=True)
15464 attribute: path_t
15465 *
15466 follow_symlinks: bool = True
15467
15468Return the value of extended attribute attribute on path.
15469
15470path may be either a string or an open file descriptor.
15471If follow_symlinks is False, and the last element of the path is a symbolic
15472 link, getxattr will examine the symbolic link itself instead of the file
15473 the link points to.
15474
15475[clinic start generated code]*/
15476
15477PyDoc_STRVAR(os_getxattr__doc__,
15478"getxattr($module, /, path, attribute, *, follow_symlinks=True)\n"
15479"--\n"
15480"\n"
15481"Return the value of extended attribute attribute on path.\n"
15482"\n"
15483"path may be either a string or an open file descriptor.\n"
15484"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15485" link, getxattr will examine the symbolic link itself instead of the file\n"
15486" the link points to.");
15487
15488#define OS_GETXATTR_METHODDEF \
15489 {"getxattr", (PyCFunction)os_getxattr, METH_VARARGS|METH_KEYWORDS, os_getxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015490
15491static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015492os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks);
15493
15494static PyObject *
15495os_getxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015496{
Larry Hastings2f936352014-08-05 14:04:04 +100015497 PyObject *return_value = NULL;
15498 static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL};
15499 path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1);
15500 path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015501 int follow_symlinks = 1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015502
Larry Hastings2f936352014-08-05 14:04:04 +100015503 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15504 "O&O&|$p:getxattr", _keywords,
15505 path_converter, &path, path_converter, &attribute, &follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015506 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +100015507 return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks);
15508
15509exit:
15510 /* Cleanup for path */
15511 path_cleanup(&path);
15512 /* Cleanup for attribute */
15513 path_cleanup(&attribute);
15514
15515 return return_value;
15516}
15517
15518static PyObject *
15519os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
15520/*[clinic end generated code: output=bbc9454fe2b9ea86 input=8c8ea3bab78d89c2]*/
15521{
15522 Py_ssize_t i;
15523 PyObject *buffer = NULL;
15524
15525 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
15526 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015527
Larry Hastings9cf065c2012-06-22 16:30:09 -070015528 for (i = 0; ; i++) {
15529 void *ptr;
15530 ssize_t result;
15531 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
15532 Py_ssize_t buffer_size = buffer_sizes[i];
15533 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100015534 path_error(path);
15535 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015536 }
15537 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
15538 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100015539 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015540 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015541
Larry Hastings9cf065c2012-06-22 16:30:09 -070015542 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015543 if (path->fd >= 0)
15544 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015545 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100015546 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015547 else
Larry Hastings2f936352014-08-05 14:04:04 +100015548 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015549 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015550
Larry Hastings9cf065c2012-06-22 16:30:09 -070015551 if (result < 0) {
15552 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015553 if (errno == ERANGE)
15554 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100015555 path_error(path);
15556 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015557 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015558
Larry Hastings9cf065c2012-06-22 16:30:09 -070015559 if (result != buffer_size) {
15560 /* Can only shrink. */
15561 _PyBytes_Resize(&buffer, result);
15562 }
15563 break;
15564 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015565
Larry Hastings9cf065c2012-06-22 16:30:09 -070015566 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015567}
15568
Larry Hastings2f936352014-08-05 14:04:04 +100015569
15570/*[clinic input]
15571os.setxattr
15572
15573 path: path_t(allow_fd=True)
15574 attribute: path_t
15575 value: Py_buffer
15576 flags: int = 0
15577 *
15578 follow_symlinks: bool = True
15579
15580Set extended attribute attribute on path to value.
15581
15582path may be either a string or an open file descriptor.
15583If follow_symlinks is False, and the last element of the path is a symbolic
15584 link, setxattr will modify the symbolic link itself instead of the file
15585 the link points to.
15586
15587[clinic start generated code]*/
15588
15589PyDoc_STRVAR(os_setxattr__doc__,
15590"setxattr($module, /, path, attribute, value, flags=0, *,\n"
15591" follow_symlinks=True)\n"
15592"--\n"
15593"\n"
15594"Set extended attribute attribute on path to value.\n"
15595"\n"
15596"path may be either a string or an open file descriptor.\n"
15597"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15598" link, setxattr will modify the symbolic link itself instead of the file\n"
15599" the link points to.");
15600
15601#define OS_SETXATTR_METHODDEF \
15602 {"setxattr", (PyCFunction)os_setxattr, METH_VARARGS|METH_KEYWORDS, os_setxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015603
15604static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015605os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks);
15606
15607static PyObject *
15608os_setxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015609{
Larry Hastings2f936352014-08-05 14:04:04 +100015610 PyObject *return_value = NULL;
15611 static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL};
15612 path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1);
15613 path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0);
15614 Py_buffer value = {NULL, NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -070015615 int flags = 0;
15616 int follow_symlinks = 1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015617
Larry Hastings2f936352014-08-05 14:04:04 +100015618 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15619 "O&O&y*|i$p:setxattr", _keywords,
15620 path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015621 goto exit;
Larry Hastings2f936352014-08-05 14:04:04 +100015622 return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015623
Larry Hastings9cf065c2012-06-22 16:30:09 -070015624exit:
Larry Hastings2f936352014-08-05 14:04:04 +100015625 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015626 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +100015627 /* Cleanup for attribute */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015628 path_cleanup(&attribute);
Larry Hastings2f936352014-08-05 14:04:04 +100015629 /* Cleanup for value */
15630 if (value.obj)
15631 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015632
Larry Hastings9cf065c2012-06-22 16:30:09 -070015633 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015634}
15635
Benjamin Peterson799bd802011-08-31 22:15:17 -040015636static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015637os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks)
15638/*[clinic end generated code: output=2ff845d8e024b218 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040015639{
Larry Hastings2f936352014-08-05 14:04:04 +100015640 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015641
Larry Hastings2f936352014-08-05 14:04:04 +100015642 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040015643 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015644
Benjamin Peterson799bd802011-08-31 22:15:17 -040015645 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015646 if (path->fd > -1)
15647 result = fsetxattr(path->fd, attribute->narrow,
15648 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015649 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100015650 result = setxattr(path->narrow, attribute->narrow,
15651 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015652 else
Larry Hastings2f936352014-08-05 14:04:04 +100015653 result = lsetxattr(path->narrow, attribute->narrow,
15654 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015655 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015656
Larry Hastings9cf065c2012-06-22 16:30:09 -070015657 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100015658 path_error(path);
15659 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015660 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015661
Larry Hastings2f936352014-08-05 14:04:04 +100015662 Py_RETURN_NONE;
15663}
15664
15665
15666/*[clinic input]
15667os.removexattr
15668
15669 path: path_t(allow_fd=True)
15670 attribute: path_t
15671 *
15672 follow_symlinks: bool = True
15673
15674Remove extended attribute attribute on path.
15675
15676path may be either a string or an open file descriptor.
15677If follow_symlinks is False, and the last element of the path is a symbolic
15678 link, removexattr will modify the symbolic link itself instead of the file
15679 the link points to.
15680
15681[clinic start generated code]*/
15682
15683PyDoc_STRVAR(os_removexattr__doc__,
15684"removexattr($module, /, path, attribute, *, follow_symlinks=True)\n"
15685"--\n"
15686"\n"
15687"Remove extended attribute attribute on path.\n"
15688"\n"
15689"path may be either a string or an open file descriptor.\n"
15690"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15691" link, removexattr will modify the symbolic link itself instead of the file\n"
15692" the link points to.");
15693
15694#define OS_REMOVEXATTR_METHODDEF \
15695 {"removexattr", (PyCFunction)os_removexattr, METH_VARARGS|METH_KEYWORDS, os_removexattr__doc__},
15696
15697static PyObject *
15698os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks);
15699
15700static PyObject *
15701os_removexattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
15702{
15703 PyObject *return_value = NULL;
15704 static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL};
15705 path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1);
15706 path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0);
15707 int follow_symlinks = 1;
15708
15709 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15710 "O&O&|$p:removexattr", _keywords,
15711 path_converter, &path, path_converter, &attribute, &follow_symlinks))
15712 goto exit;
15713 return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks);
Benjamin Peterson799bd802011-08-31 22:15:17 -040015714
Larry Hastings9cf065c2012-06-22 16:30:09 -070015715exit:
Larry Hastings2f936352014-08-05 14:04:04 +100015716 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015717 path_cleanup(&path);
Larry Hastings2f936352014-08-05 14:04:04 +100015718 /* Cleanup for attribute */
Larry Hastings9cf065c2012-06-22 16:30:09 -070015719 path_cleanup(&attribute);
15720
15721 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015722}
15723
Larry Hastings2f936352014-08-05 14:04:04 +100015724static PyObject *
15725os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
15726/*[clinic end generated code: output=8dfc715bf607c4cf input=cdb54834161e3329]*/
15727{
15728 ssize_t result;
15729
15730 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
15731 return NULL;
15732
15733 Py_BEGIN_ALLOW_THREADS;
15734 if (path->fd > -1)
15735 result = fremovexattr(path->fd, attribute->narrow);
15736 else if (follow_symlinks)
15737 result = removexattr(path->narrow, attribute->narrow);
15738 else
15739 result = lremovexattr(path->narrow, attribute->narrow);
15740 Py_END_ALLOW_THREADS;
15741
15742 if (result) {
15743 return path_error(path);
15744 }
15745
15746 Py_RETURN_NONE;
15747}
15748
15749
15750/*[clinic input]
15751os.listxattr
15752
15753 path: path_t(allow_fd=True, nullable=True) = None
15754 *
15755 follow_symlinks: bool = True
15756
15757Return a list of extended attributes on path.
15758
15759path may be either None, a string, or an open file descriptor.
15760if path is None, listxattr will examine the current directory.
15761If follow_symlinks is False, and the last element of the path is a symbolic
15762 link, listxattr will examine the symbolic link itself instead of the file
15763 the link points to.
15764[clinic start generated code]*/
15765
15766PyDoc_STRVAR(os_listxattr__doc__,
15767"listxattr($module, /, path=None, *, follow_symlinks=True)\n"
15768"--\n"
15769"\n"
15770"Return a list of extended attributes on path.\n"
15771"\n"
15772"path may be either None, a string, or an open file descriptor.\n"
15773"if path is None, listxattr will examine the current directory.\n"
15774"If follow_symlinks is False, and the last element of the path is a symbolic\n"
15775" link, listxattr will examine the symbolic link itself instead of the file\n"
15776" the link points to.");
15777
15778#define OS_LISTXATTR_METHODDEF \
15779 {"listxattr", (PyCFunction)os_listxattr, METH_VARARGS|METH_KEYWORDS, os_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040015780
15781static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015782os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks);
15783
15784static PyObject *
15785os_listxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040015786{
Larry Hastings2f936352014-08-05 14:04:04 +100015787 PyObject *return_value = NULL;
15788 static char *_keywords[] = {"path", "follow_symlinks", NULL};
15789 path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015790 int follow_symlinks = 1;
Larry Hastings2f936352014-08-05 14:04:04 +100015791
15792 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
15793 "|O&$p:listxattr", _keywords,
15794 path_converter, &path, &follow_symlinks))
15795 goto exit;
15796 return_value = os_listxattr_impl(module, &path, follow_symlinks);
15797
15798exit:
15799 /* Cleanup for path */
15800 path_cleanup(&path);
15801
15802 return return_value;
15803}
15804
15805static PyObject *
15806os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
15807/*[clinic end generated code: output=3104cafda1a3d887 input=08cca53ac0b07c13]*/
15808{
Larry Hastings9cf065c2012-06-22 16:30:09 -070015809 Py_ssize_t i;
15810 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100015811 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015812 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015813
Larry Hastings2f936352014-08-05 14:04:04 +100015814 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070015815 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015816
Larry Hastings2f936352014-08-05 14:04:04 +100015817 name = path->narrow ? path->narrow : ".";
15818
Larry Hastings9cf065c2012-06-22 16:30:09 -070015819 for (i = 0; ; i++) {
15820 char *start, *trace, *end;
15821 ssize_t length;
15822 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
15823 Py_ssize_t buffer_size = buffer_sizes[i];
15824 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020015825 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100015826 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015827 break;
15828 }
15829 buffer = PyMem_MALLOC(buffer_size);
15830 if (!buffer) {
15831 PyErr_NoMemory();
15832 break;
15833 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015834
Larry Hastings9cf065c2012-06-22 16:30:09 -070015835 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100015836 if (path->fd > -1)
15837 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015838 else if (follow_symlinks)
15839 length = listxattr(name, buffer, buffer_size);
15840 else
15841 length = llistxattr(name, buffer, buffer_size);
15842 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015843
Larry Hastings9cf065c2012-06-22 16:30:09 -070015844 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020015845 if (errno == ERANGE) {
15846 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050015847 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015848 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020015849 }
Larry Hastings2f936352014-08-05 14:04:04 +100015850 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015851 break;
15852 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015853
Larry Hastings9cf065c2012-06-22 16:30:09 -070015854 result = PyList_New(0);
15855 if (!result) {
15856 goto exit;
15857 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040015858
Larry Hastings9cf065c2012-06-22 16:30:09 -070015859 end = buffer + length;
15860 for (trace = start = buffer; trace != end; trace++) {
15861 if (!*trace) {
15862 int error;
15863 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
15864 trace - start);
15865 if (!attribute) {
15866 Py_DECREF(result);
15867 result = NULL;
15868 goto exit;
15869 }
15870 error = PyList_Append(result, attribute);
15871 Py_DECREF(attribute);
15872 if (error) {
15873 Py_DECREF(result);
15874 result = NULL;
15875 goto exit;
15876 }
15877 start = trace + 1;
15878 }
15879 }
15880 break;
15881 }
15882exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070015883 if (buffer)
15884 PyMem_FREE(buffer);
15885 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015886}
Benjamin Peterson9428d532011-09-14 11:45:52 -040015887#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040015888
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015889
Larry Hastings2f936352014-08-05 14:04:04 +100015890/*[clinic input]
15891os.urandom
15892
15893 size: Py_ssize_t
15894 /
15895
15896Return a bytes object containing random bytes suitable for cryptographic use.
15897[clinic start generated code]*/
15898
15899PyDoc_STRVAR(os_urandom__doc__,
15900"urandom($module, size, /)\n"
15901"--\n"
15902"\n"
15903"Return a bytes object containing random bytes suitable for cryptographic use.");
15904
15905#define OS_URANDOM_METHODDEF \
15906 {"urandom", (PyCFunction)os_urandom, METH_VARARGS, os_urandom__doc__},
Georg Brandl2fb477c2012-02-21 00:33:36 +010015907
15908static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100015909os_urandom_impl(PyModuleDef *module, Py_ssize_t size);
Georg Brandl2fb477c2012-02-21 00:33:36 +010015910
Larry Hastings2f936352014-08-05 14:04:04 +100015911static PyObject *
15912os_urandom(PyModuleDef *module, PyObject *args)
15913{
15914 PyObject *return_value = NULL;
15915 Py_ssize_t size;
15916
15917 if (!PyArg_ParseTuple(args,
15918 "n:urandom",
15919 &size))
15920 goto exit;
15921 return_value = os_urandom_impl(module, size);
15922
15923exit:
15924 return return_value;
15925}
15926
15927static PyObject *
15928os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
15929/*[clinic end generated code: output=5dbff582cab94cb9 input=4067cdb1b6776c29]*/
15930{
15931 PyObject *bytes;
15932 int result;
15933
Georg Brandl2fb477c2012-02-21 00:33:36 +010015934 if (size < 0)
15935 return PyErr_Format(PyExc_ValueError,
15936 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100015937 bytes = PyBytes_FromStringAndSize(NULL, size);
15938 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010015939 return NULL;
15940
Larry Hastings2f936352014-08-05 14:04:04 +100015941 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
15942 PyBytes_GET_SIZE(bytes));
15943 if (result == -1) {
15944 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010015945 return NULL;
15946 }
Larry Hastings2f936352014-08-05 14:04:04 +100015947 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010015948}
15949
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015950/* Terminal size querying */
15951
15952static PyTypeObject TerminalSizeType;
15953
15954PyDoc_STRVAR(TerminalSize_docstring,
15955 "A tuple of (columns, lines) for holding terminal window size");
15956
15957static PyStructSequence_Field TerminalSize_fields[] = {
15958 {"columns", "width of the terminal window in characters"},
15959 {"lines", "height of the terminal window in characters"},
15960 {NULL, NULL}
15961};
15962
15963static PyStructSequence_Desc TerminalSize_desc = {
15964 "os.terminal_size",
15965 TerminalSize_docstring,
15966 TerminalSize_fields,
15967 2,
15968};
15969
15970#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100015971/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010015972PyDoc_STRVAR(termsize__doc__,
15973 "Return the size of the terminal window as (columns, lines).\n" \
15974 "\n" \
15975 "The optional argument fd (default standard output) specifies\n" \
15976 "which file descriptor should be queried.\n" \
15977 "\n" \
15978 "If the file descriptor is not connected to a terminal, an OSError\n" \
15979 "is thrown.\n" \
15980 "\n" \
15981 "This function will only be defined if an implementation is\n" \
15982 "available for this system.\n" \
15983 "\n" \
15984 "shutil.get_terminal_size is the high-level function which should \n" \
15985 "normally be used, os.get_terminal_size is the low-level implementation.");
15986
15987static PyObject*
15988get_terminal_size(PyObject *self, PyObject *args)
15989{
15990 int columns, lines;
15991 PyObject *termsize;
15992
15993 int fd = fileno(stdout);
15994 /* Under some conditions stdout may not be connected and
15995 * fileno(stdout) may point to an invalid file descriptor. For example
15996 * GUI apps don't have valid standard streams by default.
15997 *
15998 * If this happens, and the optional fd argument is not present,
15999 * the ioctl below will fail returning EBADF. This is what we want.
16000 */
16001
16002 if (!PyArg_ParseTuple(args, "|i", &fd))
16003 return NULL;
16004
16005#ifdef TERMSIZE_USE_IOCTL
16006 {
16007 struct winsize w;
16008 if (ioctl(fd, TIOCGWINSZ, &w))
16009 return PyErr_SetFromErrno(PyExc_OSError);
16010 columns = w.ws_col;
16011 lines = w.ws_row;
16012 }
16013#endif /* TERMSIZE_USE_IOCTL */
16014
16015#ifdef TERMSIZE_USE_CONIO
16016 {
16017 DWORD nhandle;
16018 HANDLE handle;
16019 CONSOLE_SCREEN_BUFFER_INFO csbi;
16020 switch (fd) {
16021 case 0: nhandle = STD_INPUT_HANDLE;
16022 break;
16023 case 1: nhandle = STD_OUTPUT_HANDLE;
16024 break;
16025 case 2: nhandle = STD_ERROR_HANDLE;
16026 break;
16027 default:
16028 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
16029 }
16030 handle = GetStdHandle(nhandle);
16031 if (handle == NULL)
16032 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
16033 if (handle == INVALID_HANDLE_VALUE)
16034 return PyErr_SetFromWindowsErr(0);
16035
16036 if (!GetConsoleScreenBufferInfo(handle, &csbi))
16037 return PyErr_SetFromWindowsErr(0);
16038
16039 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
16040 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
16041 }
16042#endif /* TERMSIZE_USE_CONIO */
16043
16044 termsize = PyStructSequence_New(&TerminalSizeType);
16045 if (termsize == NULL)
16046 return NULL;
16047 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
16048 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
16049 if (PyErr_Occurred()) {
16050 Py_DECREF(termsize);
16051 return NULL;
16052 }
16053 return termsize;
16054}
16055#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
16056
Larry Hastings2f936352014-08-05 14:04:04 +100016057
16058/*[clinic input]
16059os.cpu_count
16060
16061Return the number of CPUs in the system; return None if indeterminable.
16062[clinic start generated code]*/
16063
16064PyDoc_STRVAR(os_cpu_count__doc__,
16065"cpu_count($module, /)\n"
16066"--\n"
16067"\n"
16068"Return the number of CPUs in the system; return None if indeterminable.");
16069
16070#define OS_CPU_COUNT_METHODDEF \
16071 {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__},
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016072
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016073static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100016074os_cpu_count_impl(PyModuleDef *module);
16075
16076static PyObject *
16077os_cpu_count(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
16078{
16079 return os_cpu_count_impl(module);
16080}
16081
16082static PyObject *
16083os_cpu_count_impl(PyModuleDef *module)
16084/*[clinic end generated code: output=92e2a4a729eb7740 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016085{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020016086 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016087#ifdef MS_WINDOWS
16088 SYSTEM_INFO sysinfo;
16089 GetSystemInfo(&sysinfo);
16090 ncpu = sysinfo.dwNumberOfProcessors;
16091#elif defined(__hpux)
16092 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
16093#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
16094 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016095#elif defined(__DragonFly__) || \
16096 defined(__OpenBSD__) || \
16097 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020016098 defined(__NetBSD__) || \
16099 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020016100 int mib[2];
16101 size_t len = sizeof(ncpu);
16102 mib[0] = CTL_HW;
16103 mib[1] = HW_NCPU;
16104 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
16105 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020016106#endif
16107 if (ncpu >= 1)
16108 return PyLong_FromLong(ncpu);
16109 else
16110 Py_RETURN_NONE;
16111}
16112
Victor Stinnerdaf45552013-08-28 00:53:59 +020016113
Larry Hastings2f936352014-08-05 14:04:04 +100016114/*[clinic input]
16115os.get_inheritable -> bool
16116
16117 fd: int
16118 /
16119
16120Get the close-on-exe flag of the specified file descriptor.
16121[clinic start generated code]*/
16122
16123PyDoc_STRVAR(os_get_inheritable__doc__,
16124"get_inheritable($module, fd, /)\n"
16125"--\n"
16126"\n"
16127"Get the close-on-exe flag of the specified file descriptor.");
16128
16129#define OS_GET_INHERITABLE_METHODDEF \
16130 {"get_inheritable", (PyCFunction)os_get_inheritable, METH_VARARGS, os_get_inheritable__doc__},
16131
16132static int
16133os_get_inheritable_impl(PyModuleDef *module, int fd);
16134
16135static PyObject *
16136os_get_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016137{
Larry Hastings2f936352014-08-05 14:04:04 +100016138 PyObject *return_value = NULL;
16139 int fd;
16140 int _return_value;
16141
16142 if (!PyArg_ParseTuple(args,
16143 "i:get_inheritable",
16144 &fd))
16145 goto exit;
16146 _return_value = os_get_inheritable_impl(module, fd);
16147 if ((_return_value == -1) && PyErr_Occurred())
16148 goto exit;
16149 return_value = PyBool_FromLong((long)_return_value);
16150
16151exit:
16152 return return_value;
16153}
16154
16155static int
16156os_get_inheritable_impl(PyModuleDef *module, int fd)
16157/*[clinic end generated code: output=261d1dd2b0dbdc35 input=89ac008dc9ab6b95]*/
16158{
16159 if (!_PyVerify_fd(fd)){
16160 posix_error();
16161 return -1;
16162 }
16163
16164 return _Py_get_inheritable(fd);
16165}
16166
16167
16168/*[clinic input]
16169os.set_inheritable
16170 fd: int
16171 inheritable: int
16172 /
16173
16174Set the inheritable flag of the specified file descriptor.
16175[clinic start generated code]*/
16176
16177PyDoc_STRVAR(os_set_inheritable__doc__,
16178"set_inheritable($module, fd, inheritable, /)\n"
16179"--\n"
16180"\n"
16181"Set the inheritable flag of the specified file descriptor.");
16182
16183#define OS_SET_INHERITABLE_METHODDEF \
16184 {"set_inheritable", (PyCFunction)os_set_inheritable, METH_VARARGS, os_set_inheritable__doc__},
16185
16186static PyObject *
16187os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable);
16188
16189static PyObject *
16190os_set_inheritable(PyModuleDef *module, PyObject *args)
16191{
16192 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016193 int fd;
16194 int inheritable;
16195
Larry Hastings2f936352014-08-05 14:04:04 +100016196 if (!PyArg_ParseTuple(args,
16197 "ii:set_inheritable",
16198 &fd, &inheritable))
16199 goto exit;
16200 return_value = os_set_inheritable_impl(module, fd, inheritable);
Victor Stinnerdaf45552013-08-28 00:53:59 +020016201
Larry Hastings2f936352014-08-05 14:04:04 +100016202exit:
16203 return return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016204}
16205
Larry Hastings2f936352014-08-05 14:04:04 +100016206static PyObject *
16207os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
16208/*[clinic end generated code: output=64dfe5e15c906539 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020016209{
Victor Stinnerdaf45552013-08-28 00:53:59 +020016210 if (!_PyVerify_fd(fd))
16211 return posix_error();
16212
16213 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
16214 return NULL;
16215 Py_RETURN_NONE;
16216}
16217
16218
16219#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100016220/*[clinic input]
16221os.get_handle_inheritable -> bool
16222 handle: Py_intptr_t
16223 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020016224
Larry Hastings2f936352014-08-05 14:04:04 +100016225Get the close-on-exe flag of the specified file descriptor.
16226[clinic start generated code]*/
16227
16228PyDoc_STRVAR(os_get_handle_inheritable__doc__,
16229"get_handle_inheritable($module, handle, /)\n"
16230"--\n"
16231"\n"
16232"Get the close-on-exe flag of the specified file descriptor.");
16233
16234#define OS_GET_HANDLE_INHERITABLE_METHODDEF \
16235 {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_VARARGS, os_get_handle_inheritable__doc__},
16236
16237static int
16238os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle);
16239
16240static PyObject *
16241os_get_handle_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016242{
Larry Hastings2f936352014-08-05 14:04:04 +100016243 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016244 Py_intptr_t handle;
Larry Hastings2f936352014-08-05 14:04:04 +100016245 int _return_value;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016246
Larry Hastings2f936352014-08-05 14:04:04 +100016247 if (!PyArg_ParseTuple(args,
16248 "" _Py_PARSE_INTPTR ":get_handle_inheritable",
16249 &handle))
16250 goto exit;
16251 _return_value = os_get_handle_inheritable_impl(module, handle);
16252 if ((_return_value == -1) && PyErr_Occurred())
16253 goto exit;
16254 return_value = PyBool_FromLong((long)_return_value);
16255
16256exit:
16257 return return_value;
16258}
16259
16260static int
16261os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
16262/*[clinic end generated code: output=d5bf9d86900bf457 input=5f7759443aae3dc5]*/
16263{
16264 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016265
16266 if (!GetHandleInformation((HANDLE)handle, &flags)) {
16267 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100016268 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016269 }
16270
Larry Hastings2f936352014-08-05 14:04:04 +100016271 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016272}
16273
Victor Stinnerdaf45552013-08-28 00:53:59 +020016274
Larry Hastings2f936352014-08-05 14:04:04 +100016275/*[clinic input]
16276os.set_handle_inheritable
16277 handle: Py_intptr_t
16278 inheritable: bool
16279 /
16280
16281Set the inheritable flag of the specified handle.
16282[clinic start generated code]*/
16283
16284PyDoc_STRVAR(os_set_handle_inheritable__doc__,
16285"set_handle_inheritable($module, handle, inheritable, /)\n"
16286"--\n"
16287"\n"
16288"Set the inheritable flag of the specified handle.");
16289
16290#define OS_SET_HANDLE_INHERITABLE_METHODDEF \
16291 {"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__},
16292
16293static PyObject *
16294os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable);
16295
16296static PyObject *
16297os_set_handle_inheritable(PyModuleDef *module, PyObject *args)
Victor Stinnerdaf45552013-08-28 00:53:59 +020016298{
Larry Hastings2f936352014-08-05 14:04:04 +100016299 PyObject *return_value = NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016300 Py_intptr_t handle;
Larry Hastings2f936352014-08-05 14:04:04 +100016301 int inheritable;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016302
Larry Hastings2f936352014-08-05 14:04:04 +100016303 if (!PyArg_ParseTuple(args,
16304 "" _Py_PARSE_INTPTR "p:set_handle_inheritable",
16305 &handle, &inheritable))
16306 goto exit;
16307 return_value = os_set_handle_inheritable_impl(module, handle, inheritable);
Victor Stinnerdaf45552013-08-28 00:53:59 +020016308
Larry Hastings2f936352014-08-05 14:04:04 +100016309exit:
16310 return return_value;
16311}
16312
16313static PyObject *
16314os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable)
16315/*[clinic end generated code: output=ee5fcc6d9f0d4f8b input=e64b2b2730469def]*/
16316{
16317 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020016318 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
16319 PyErr_SetFromWindowsErr(0);
16320 return NULL;
16321 }
16322 Py_RETURN_NONE;
16323}
Larry Hastings2f936352014-08-05 14:04:04 +100016324#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010016325
Victor Stinner1db9e7b2014-07-29 22:32:47 +020016326#ifndef MS_WINDOWS
16327PyDoc_STRVAR(get_blocking__doc__,
16328 "get_blocking(fd) -> bool\n" \
16329 "\n" \
16330 "Get the blocking mode of the file descriptor:\n" \
16331 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
16332
16333static PyObject*
16334posix_get_blocking(PyObject *self, PyObject *args)
16335{
16336 int fd;
16337 int blocking;
16338
16339 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
16340 return NULL;
16341
16342 if (!_PyVerify_fd(fd))
16343 return posix_error();
16344
16345 blocking = _Py_get_blocking(fd);
16346 if (blocking < 0)
16347 return NULL;
16348 return PyBool_FromLong(blocking);
16349}
16350
16351PyDoc_STRVAR(set_blocking__doc__,
16352 "set_blocking(fd, blocking)\n" \
16353 "\n" \
16354 "Set the blocking mode of the specified file descriptor.\n" \
16355 "Set the O_NONBLOCK flag if blocking is False,\n" \
16356 "clear the O_NONBLOCK flag otherwise.");
16357
16358static PyObject*
16359posix_set_blocking(PyObject *self, PyObject *args)
16360{
16361 int fd, blocking;
16362
16363 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
16364 return NULL;
16365
16366 if (!_PyVerify_fd(fd))
16367 return posix_error();
16368
16369 if (_Py_set_blocking(fd, blocking) < 0)
16370 return NULL;
16371 Py_RETURN_NONE;
16372}
16373#endif /* !MS_WINDOWS */
16374
16375
Larry Hastings7726ac92014-01-31 22:03:12 -080016376/*[clinic input]
16377dump buffer
16378[clinic start generated code]*/
16379
16380#ifndef OS_TTYNAME_METHODDEF
16381 #define OS_TTYNAME_METHODDEF
16382#endif /* !defined(OS_TTYNAME_METHODDEF) */
Larry Hastings2f936352014-08-05 14:04:04 +100016383
16384#ifndef OS_CTERMID_METHODDEF
16385 #define OS_CTERMID_METHODDEF
16386#endif /* !defined(OS_CTERMID_METHODDEF) */
16387
16388#ifndef OS_FCHDIR_METHODDEF
16389 #define OS_FCHDIR_METHODDEF
16390#endif /* !defined(OS_FCHDIR_METHODDEF) */
16391
16392#ifndef OS_FCHMOD_METHODDEF
16393 #define OS_FCHMOD_METHODDEF
16394#endif /* !defined(OS_FCHMOD_METHODDEF) */
16395
16396#ifndef OS_LCHMOD_METHODDEF
16397 #define OS_LCHMOD_METHODDEF
16398#endif /* !defined(OS_LCHMOD_METHODDEF) */
16399
16400#ifndef OS_CHFLAGS_METHODDEF
16401 #define OS_CHFLAGS_METHODDEF
16402#endif /* !defined(OS_CHFLAGS_METHODDEF) */
16403
16404#ifndef OS_LCHFLAGS_METHODDEF
16405 #define OS_LCHFLAGS_METHODDEF
16406#endif /* !defined(OS_LCHFLAGS_METHODDEF) */
16407
16408#ifndef OS_CHROOT_METHODDEF
16409 #define OS_CHROOT_METHODDEF
16410#endif /* !defined(OS_CHROOT_METHODDEF) */
16411
16412#ifndef OS_FSYNC_METHODDEF
16413 #define OS_FSYNC_METHODDEF
16414#endif /* !defined(OS_FSYNC_METHODDEF) */
16415
16416#ifndef OS_SYNC_METHODDEF
16417 #define OS_SYNC_METHODDEF
16418#endif /* !defined(OS_SYNC_METHODDEF) */
16419
16420#ifndef OS_FDATASYNC_METHODDEF
16421 #define OS_FDATASYNC_METHODDEF
16422#endif /* !defined(OS_FDATASYNC_METHODDEF) */
16423
16424#ifndef OS_CHOWN_METHODDEF
16425 #define OS_CHOWN_METHODDEF
16426#endif /* !defined(OS_CHOWN_METHODDEF) */
16427
16428#ifndef OS_FCHOWN_METHODDEF
16429 #define OS_FCHOWN_METHODDEF
16430#endif /* !defined(OS_FCHOWN_METHODDEF) */
16431
16432#ifndef OS_LCHOWN_METHODDEF
16433 #define OS_LCHOWN_METHODDEF
16434#endif /* !defined(OS_LCHOWN_METHODDEF) */
16435
16436#ifndef OS_LINK_METHODDEF
16437 #define OS_LINK_METHODDEF
16438#endif /* !defined(OS_LINK_METHODDEF) */
16439
16440#ifndef OS__GETFINALPATHNAME_METHODDEF
16441 #define OS__GETFINALPATHNAME_METHODDEF
16442#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */
16443
16444#ifndef OS__GETVOLUMEPATHNAME_METHODDEF
16445 #define OS__GETVOLUMEPATHNAME_METHODDEF
16446#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */
16447
16448#ifndef OS_NICE_METHODDEF
16449 #define OS_NICE_METHODDEF
16450#endif /* !defined(OS_NICE_METHODDEF) */
16451
16452#ifndef OS_GETPRIORITY_METHODDEF
16453 #define OS_GETPRIORITY_METHODDEF
16454#endif /* !defined(OS_GETPRIORITY_METHODDEF) */
16455
16456#ifndef OS_SETPRIORITY_METHODDEF
16457 #define OS_SETPRIORITY_METHODDEF
16458#endif /* !defined(OS_SETPRIORITY_METHODDEF) */
16459
16460#ifndef OS_SYSTEM_METHODDEF
16461 #define OS_SYSTEM_METHODDEF
16462#endif /* !defined(OS_SYSTEM_METHODDEF) */
16463
16464#ifndef OS_SYSTEM_METHODDEF
16465 #define OS_SYSTEM_METHODDEF
16466#endif /* !defined(OS_SYSTEM_METHODDEF) */
16467
16468#ifndef OS_UNAME_METHODDEF
16469 #define OS_UNAME_METHODDEF
16470#endif /* !defined(OS_UNAME_METHODDEF) */
16471
16472#ifndef OS_EXECV_METHODDEF
16473 #define OS_EXECV_METHODDEF
16474#endif /* !defined(OS_EXECV_METHODDEF) */
16475
16476#ifndef OS_EXECVE_METHODDEF
16477 #define OS_EXECVE_METHODDEF
16478#endif /* !defined(OS_EXECVE_METHODDEF) */
16479
16480#ifndef OS_SPAWNV_METHODDEF
16481 #define OS_SPAWNV_METHODDEF
16482#endif /* !defined(OS_SPAWNV_METHODDEF) */
16483
16484#ifndef OS_SPAWNVE_METHODDEF
16485 #define OS_SPAWNVE_METHODDEF
16486#endif /* !defined(OS_SPAWNVE_METHODDEF) */
16487
16488#ifndef OS_FORK1_METHODDEF
16489 #define OS_FORK1_METHODDEF
16490#endif /* !defined(OS_FORK1_METHODDEF) */
16491
16492#ifndef OS_FORK_METHODDEF
16493 #define OS_FORK_METHODDEF
16494#endif /* !defined(OS_FORK_METHODDEF) */
16495
16496#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF
16497 #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF
16498#endif /* !defined(OS_SCHED_GET_PRIORITY_MAX_METHODDEF) */
16499
16500#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF
16501 #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF
16502#endif /* !defined(OS_SCHED_GET_PRIORITY_MIN_METHODDEF) */
16503
16504#ifndef OS_SCHED_GETSCHEDULER_METHODDEF
16505 #define OS_SCHED_GETSCHEDULER_METHODDEF
16506#endif /* !defined(OS_SCHED_GETSCHEDULER_METHODDEF) */
16507
16508#ifndef OS_SCHED_SETSCHEDULER_METHODDEF
16509 #define OS_SCHED_SETSCHEDULER_METHODDEF
16510#endif /* !defined(OS_SCHED_SETSCHEDULER_METHODDEF) */
16511
16512#ifndef OS_SCHED_GETPARAM_METHODDEF
16513 #define OS_SCHED_GETPARAM_METHODDEF
16514#endif /* !defined(OS_SCHED_GETPARAM_METHODDEF) */
16515
16516#ifndef OS_SCHED_SETPARAM_METHODDEF
16517 #define OS_SCHED_SETPARAM_METHODDEF
16518#endif /* !defined(OS_SCHED_SETPARAM_METHODDEF) */
16519
16520#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF
16521 #define OS_SCHED_RR_GET_INTERVAL_METHODDEF
16522#endif /* !defined(OS_SCHED_RR_GET_INTERVAL_METHODDEF) */
16523
16524#ifndef OS_SCHED_YIELD_METHODDEF
16525 #define OS_SCHED_YIELD_METHODDEF
16526#endif /* !defined(OS_SCHED_YIELD_METHODDEF) */
16527
16528#ifndef OS_SCHED_SETAFFINITY_METHODDEF
16529 #define OS_SCHED_SETAFFINITY_METHODDEF
16530#endif /* !defined(OS_SCHED_SETAFFINITY_METHODDEF) */
16531
16532#ifndef OS_SCHED_GETAFFINITY_METHODDEF
16533 #define OS_SCHED_GETAFFINITY_METHODDEF
16534#endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */
16535
16536#ifndef OS_OPENPTY_METHODDEF
16537 #define OS_OPENPTY_METHODDEF
16538#endif /* !defined(OS_OPENPTY_METHODDEF) */
16539
16540#ifndef OS_FORKPTY_METHODDEF
16541 #define OS_FORKPTY_METHODDEF
16542#endif /* !defined(OS_FORKPTY_METHODDEF) */
16543
16544#ifndef OS_GETEGID_METHODDEF
16545 #define OS_GETEGID_METHODDEF
16546#endif /* !defined(OS_GETEGID_METHODDEF) */
16547
16548#ifndef OS_GETEUID_METHODDEF
16549 #define OS_GETEUID_METHODDEF
16550#endif /* !defined(OS_GETEUID_METHODDEF) */
16551
16552#ifndef OS_GETGID_METHODDEF
16553 #define OS_GETGID_METHODDEF
16554#endif /* !defined(OS_GETGID_METHODDEF) */
16555
16556#ifndef OS_GETGROUPS_METHODDEF
16557 #define OS_GETGROUPS_METHODDEF
16558#endif /* !defined(OS_GETGROUPS_METHODDEF) */
16559
16560#ifndef OS_GETPGID_METHODDEF
16561 #define OS_GETPGID_METHODDEF
16562#endif /* !defined(OS_GETPGID_METHODDEF) */
16563
16564#ifndef OS_GETPGRP_METHODDEF
16565 #define OS_GETPGRP_METHODDEF
16566#endif /* !defined(OS_GETPGRP_METHODDEF) */
16567
16568#ifndef OS_SETPGRP_METHODDEF
16569 #define OS_SETPGRP_METHODDEF
16570#endif /* !defined(OS_SETPGRP_METHODDEF) */
16571
16572#ifndef OS_GETPPID_METHODDEF
16573 #define OS_GETPPID_METHODDEF
16574#endif /* !defined(OS_GETPPID_METHODDEF) */
16575
16576#ifndef OS_GETLOGIN_METHODDEF
16577 #define OS_GETLOGIN_METHODDEF
16578#endif /* !defined(OS_GETLOGIN_METHODDEF) */
16579
16580#ifndef OS_GETUID_METHODDEF
16581 #define OS_GETUID_METHODDEF
16582#endif /* !defined(OS_GETUID_METHODDEF) */
16583
16584#ifndef OS_KILL_METHODDEF
16585 #define OS_KILL_METHODDEF
16586#endif /* !defined(OS_KILL_METHODDEF) */
16587
16588#ifndef OS_KILLPG_METHODDEF
16589 #define OS_KILLPG_METHODDEF
16590#endif /* !defined(OS_KILLPG_METHODDEF) */
16591
16592#ifndef OS_PLOCK_METHODDEF
16593 #define OS_PLOCK_METHODDEF
16594#endif /* !defined(OS_PLOCK_METHODDEF) */
16595
16596#ifndef OS_SETUID_METHODDEF
16597 #define OS_SETUID_METHODDEF
16598#endif /* !defined(OS_SETUID_METHODDEF) */
16599
16600#ifndef OS_SETEUID_METHODDEF
16601 #define OS_SETEUID_METHODDEF
16602#endif /* !defined(OS_SETEUID_METHODDEF) */
16603
16604#ifndef OS_SETEGID_METHODDEF
16605 #define OS_SETEGID_METHODDEF
16606#endif /* !defined(OS_SETEGID_METHODDEF) */
16607
16608#ifndef OS_SETREUID_METHODDEF
16609 #define OS_SETREUID_METHODDEF
16610#endif /* !defined(OS_SETREUID_METHODDEF) */
16611
16612#ifndef OS_SETREGID_METHODDEF
16613 #define OS_SETREGID_METHODDEF
16614#endif /* !defined(OS_SETREGID_METHODDEF) */
16615
16616#ifndef OS_SETGID_METHODDEF
16617 #define OS_SETGID_METHODDEF
16618#endif /* !defined(OS_SETGID_METHODDEF) */
16619
16620#ifndef OS_SETGROUPS_METHODDEF
16621 #define OS_SETGROUPS_METHODDEF
16622#endif /* !defined(OS_SETGROUPS_METHODDEF) */
16623
16624#ifndef OS_WAIT3_METHODDEF
16625 #define OS_WAIT3_METHODDEF
16626#endif /* !defined(OS_WAIT3_METHODDEF) */
16627
16628#ifndef OS_WAIT4_METHODDEF
16629 #define OS_WAIT4_METHODDEF
16630#endif /* !defined(OS_WAIT4_METHODDEF) */
16631
16632#ifndef OS_WAITID_METHODDEF
16633 #define OS_WAITID_METHODDEF
16634#endif /* !defined(OS_WAITID_METHODDEF) */
16635
16636#ifndef OS_WAITPID_METHODDEF
16637 #define OS_WAITPID_METHODDEF
16638#endif /* !defined(OS_WAITPID_METHODDEF) */
16639
16640#ifndef OS_WAITPID_METHODDEF
16641 #define OS_WAITPID_METHODDEF
16642#endif /* !defined(OS_WAITPID_METHODDEF) */
16643
16644#ifndef OS_WAIT_METHODDEF
16645 #define OS_WAIT_METHODDEF
16646#endif /* !defined(OS_WAIT_METHODDEF) */
16647
16648#ifndef OS_SYMLINK_METHODDEF
16649 #define OS_SYMLINK_METHODDEF
16650#endif /* !defined(OS_SYMLINK_METHODDEF) */
16651
16652#ifndef OS_TIMES_METHODDEF
16653 #define OS_TIMES_METHODDEF
16654#endif /* !defined(OS_TIMES_METHODDEF) */
16655
16656#ifndef OS_GETSID_METHODDEF
16657 #define OS_GETSID_METHODDEF
16658#endif /* !defined(OS_GETSID_METHODDEF) */
16659
16660#ifndef OS_SETSID_METHODDEF
16661 #define OS_SETSID_METHODDEF
16662#endif /* !defined(OS_SETSID_METHODDEF) */
16663
16664#ifndef OS_SETPGID_METHODDEF
16665 #define OS_SETPGID_METHODDEF
16666#endif /* !defined(OS_SETPGID_METHODDEF) */
16667
16668#ifndef OS_TCGETPGRP_METHODDEF
16669 #define OS_TCGETPGRP_METHODDEF
16670#endif /* !defined(OS_TCGETPGRP_METHODDEF) */
16671
16672#ifndef OS_TCSETPGRP_METHODDEF
16673 #define OS_TCSETPGRP_METHODDEF
16674#endif /* !defined(OS_TCSETPGRP_METHODDEF) */
16675
16676#ifndef OS_LOCKF_METHODDEF
16677 #define OS_LOCKF_METHODDEF
16678#endif /* !defined(OS_LOCKF_METHODDEF) */
16679
16680#ifndef OS_READV_METHODDEF
16681 #define OS_READV_METHODDEF
16682#endif /* !defined(OS_READV_METHODDEF) */
16683
16684#ifndef OS_PREAD_METHODDEF
16685 #define OS_PREAD_METHODDEF
16686#endif /* !defined(OS_PREAD_METHODDEF) */
16687
16688#ifndef OS_PIPE_METHODDEF
16689 #define OS_PIPE_METHODDEF
16690#endif /* !defined(OS_PIPE_METHODDEF) */
16691
16692#ifndef OS_PIPE2_METHODDEF
16693 #define OS_PIPE2_METHODDEF
16694#endif /* !defined(OS_PIPE2_METHODDEF) */
16695
16696#ifndef OS_WRITEV_METHODDEF
16697 #define OS_WRITEV_METHODDEF
16698#endif /* !defined(OS_WRITEV_METHODDEF) */
16699
16700#ifndef OS_PWRITE_METHODDEF
16701 #define OS_PWRITE_METHODDEF
16702#endif /* !defined(OS_PWRITE_METHODDEF) */
16703
16704#ifndef OS_MKFIFO_METHODDEF
16705 #define OS_MKFIFO_METHODDEF
16706#endif /* !defined(OS_MKFIFO_METHODDEF) */
16707
16708#ifndef OS_MKNOD_METHODDEF
16709 #define OS_MKNOD_METHODDEF
16710#endif /* !defined(OS_MKNOD_METHODDEF) */
16711
16712#ifndef OS_MAJOR_METHODDEF
16713 #define OS_MAJOR_METHODDEF
16714#endif /* !defined(OS_MAJOR_METHODDEF) */
16715
16716#ifndef OS_MINOR_METHODDEF
16717 #define OS_MINOR_METHODDEF
16718#endif /* !defined(OS_MINOR_METHODDEF) */
16719
16720#ifndef OS_MAKEDEV_METHODDEF
16721 #define OS_MAKEDEV_METHODDEF
16722#endif /* !defined(OS_MAKEDEV_METHODDEF) */
16723
16724#ifndef OS_FTRUNCATE_METHODDEF
16725 #define OS_FTRUNCATE_METHODDEF
16726#endif /* !defined(OS_FTRUNCATE_METHODDEF) */
16727
16728#ifndef OS_TRUNCATE_METHODDEF
16729 #define OS_TRUNCATE_METHODDEF
16730#endif /* !defined(OS_TRUNCATE_METHODDEF) */
16731
16732#ifndef OS_POSIX_FALLOCATE_METHODDEF
16733 #define OS_POSIX_FALLOCATE_METHODDEF
16734#endif /* !defined(OS_POSIX_FALLOCATE_METHODDEF) */
16735
16736#ifndef OS_POSIX_FADVISE_METHODDEF
16737 #define OS_POSIX_FADVISE_METHODDEF
16738#endif /* !defined(OS_POSIX_FADVISE_METHODDEF) */
16739
16740#ifndef OS_PUTENV_METHODDEF
16741 #define OS_PUTENV_METHODDEF
16742#endif /* !defined(OS_PUTENV_METHODDEF) */
16743
16744#ifndef OS_PUTENV_METHODDEF
16745 #define OS_PUTENV_METHODDEF
16746#endif /* !defined(OS_PUTENV_METHODDEF) */
16747
16748#ifndef OS_UNSETENV_METHODDEF
16749 #define OS_UNSETENV_METHODDEF
16750#endif /* !defined(OS_UNSETENV_METHODDEF) */
16751
16752#ifndef OS_WCOREDUMP_METHODDEF
16753 #define OS_WCOREDUMP_METHODDEF
16754#endif /* !defined(OS_WCOREDUMP_METHODDEF) */
16755
16756#ifndef OS_WIFCONTINUED_METHODDEF
16757 #define OS_WIFCONTINUED_METHODDEF
16758#endif /* !defined(OS_WIFCONTINUED_METHODDEF) */
16759
16760#ifndef OS_WIFSTOPPED_METHODDEF
16761 #define OS_WIFSTOPPED_METHODDEF
16762#endif /* !defined(OS_WIFSTOPPED_METHODDEF) */
16763
16764#ifndef OS_WIFSIGNALED_METHODDEF
16765 #define OS_WIFSIGNALED_METHODDEF
16766#endif /* !defined(OS_WIFSIGNALED_METHODDEF) */
16767
16768#ifndef OS_WIFEXITED_METHODDEF
16769 #define OS_WIFEXITED_METHODDEF
16770#endif /* !defined(OS_WIFEXITED_METHODDEF) */
16771
16772#ifndef OS_WEXITSTATUS_METHODDEF
16773 #define OS_WEXITSTATUS_METHODDEF
16774#endif /* !defined(OS_WEXITSTATUS_METHODDEF) */
16775
16776#ifndef OS_WTERMSIG_METHODDEF
16777 #define OS_WTERMSIG_METHODDEF
16778#endif /* !defined(OS_WTERMSIG_METHODDEF) */
16779
16780#ifndef OS_WSTOPSIG_METHODDEF
16781 #define OS_WSTOPSIG_METHODDEF
16782#endif /* !defined(OS_WSTOPSIG_METHODDEF) */
16783
16784#ifndef OS_FSTATVFS_METHODDEF
16785 #define OS_FSTATVFS_METHODDEF
16786#endif /* !defined(OS_FSTATVFS_METHODDEF) */
16787
16788#ifndef OS_STATVFS_METHODDEF
16789 #define OS_STATVFS_METHODDEF
16790#endif /* !defined(OS_STATVFS_METHODDEF) */
16791
16792#ifndef OS__GETDISKUSAGE_METHODDEF
16793 #define OS__GETDISKUSAGE_METHODDEF
16794#endif /* !defined(OS__GETDISKUSAGE_METHODDEF) */
16795
16796#ifndef OS_FPATHCONF_METHODDEF
16797 #define OS_FPATHCONF_METHODDEF
16798#endif /* !defined(OS_FPATHCONF_METHODDEF) */
16799
16800#ifndef OS_PATHCONF_METHODDEF
16801 #define OS_PATHCONF_METHODDEF
16802#endif /* !defined(OS_PATHCONF_METHODDEF) */
16803
16804#ifndef OS_CONFSTR_METHODDEF
16805 #define OS_CONFSTR_METHODDEF
16806#endif /* !defined(OS_CONFSTR_METHODDEF) */
16807
16808#ifndef OS_SYSCONF_METHODDEF
16809 #define OS_SYSCONF_METHODDEF
16810#endif /* !defined(OS_SYSCONF_METHODDEF) */
16811
16812#ifndef OS_GETLOADAVG_METHODDEF
16813 #define OS_GETLOADAVG_METHODDEF
16814#endif /* !defined(OS_GETLOADAVG_METHODDEF) */
16815
16816#ifndef OS_SETRESUID_METHODDEF
16817 #define OS_SETRESUID_METHODDEF
16818#endif /* !defined(OS_SETRESUID_METHODDEF) */
16819
16820#ifndef OS_SETRESGID_METHODDEF
16821 #define OS_SETRESGID_METHODDEF
16822#endif /* !defined(OS_SETRESGID_METHODDEF) */
16823
16824#ifndef OS_GETRESUID_METHODDEF
16825 #define OS_GETRESUID_METHODDEF
16826#endif /* !defined(OS_GETRESUID_METHODDEF) */
16827
16828#ifndef OS_GETRESGID_METHODDEF
16829 #define OS_GETRESGID_METHODDEF
16830#endif /* !defined(OS_GETRESGID_METHODDEF) */
16831
16832#ifndef OS_GETXATTR_METHODDEF
16833 #define OS_GETXATTR_METHODDEF
16834#endif /* !defined(OS_GETXATTR_METHODDEF) */
16835
16836#ifndef OS_SETXATTR_METHODDEF
16837 #define OS_SETXATTR_METHODDEF
16838#endif /* !defined(OS_SETXATTR_METHODDEF) */
16839
16840#ifndef OS_REMOVEXATTR_METHODDEF
16841 #define OS_REMOVEXATTR_METHODDEF
16842#endif /* !defined(OS_REMOVEXATTR_METHODDEF) */
16843
16844#ifndef OS_LISTXATTR_METHODDEF
16845 #define OS_LISTXATTR_METHODDEF
16846#endif /* !defined(OS_LISTXATTR_METHODDEF) */
16847
16848#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF
16849 #define OS_GET_HANDLE_INHERITABLE_METHODDEF
16850#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */
16851
16852#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF
16853 #define OS_SET_HANDLE_INHERITABLE_METHODDEF
16854#endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */
16855/*[clinic end generated code: output=52a6140b0b052ce6 input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080016856
Larry Hastings31826802013-10-19 00:09:25 -070016857
Fred Drake5ab8eaf1999-12-09 21:13:07 +000016858static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070016859
16860 OS_STAT_METHODDEF
16861 OS_ACCESS_METHODDEF
16862 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100016863 OS_CHDIR_METHODDEF
16864 OS_CHFLAGS_METHODDEF
16865 OS_CHMOD_METHODDEF
16866 OS_FCHMOD_METHODDEF
16867 OS_LCHMOD_METHODDEF
16868 OS_CHOWN_METHODDEF
16869 OS_FCHOWN_METHODDEF
16870 OS_LCHOWN_METHODDEF
16871 OS_LCHFLAGS_METHODDEF
16872 OS_CHROOT_METHODDEF
16873 OS_CTERMID_METHODDEF
16874 OS_GETCWD_METHODDEF
16875 OS_GETCWDB_METHODDEF
16876 OS_LINK_METHODDEF
16877 OS_LISTDIR_METHODDEF
16878 OS_LSTAT_METHODDEF
16879 OS_MKDIR_METHODDEF
16880 OS_NICE_METHODDEF
16881 OS_GETPRIORITY_METHODDEF
16882 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000016883#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070016884 {"readlink", (PyCFunction)posix_readlink,
16885 METH_VARARGS | METH_KEYWORDS,
16886 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000016887#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000016888#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070016889 {"readlink", (PyCFunction)win_readlink,
16890 METH_VARARGS | METH_KEYWORDS,
16891 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000016892#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100016893 OS_RENAME_METHODDEF
16894 OS_REPLACE_METHODDEF
16895 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000016896 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100016897 OS_SYMLINK_METHODDEF
16898 OS_SYSTEM_METHODDEF
16899 OS_UMASK_METHODDEF
16900 OS_UNAME_METHODDEF
16901 OS_UNLINK_METHODDEF
16902 OS_REMOVE_METHODDEF
16903 OS_UTIME_METHODDEF
16904 OS_TIMES_METHODDEF
16905 OS__EXIT_METHODDEF
16906 OS_EXECV_METHODDEF
16907 OS_EXECVE_METHODDEF
16908 OS_SPAWNV_METHODDEF
16909 OS_SPAWNVE_METHODDEF
16910 OS_FORK1_METHODDEF
16911 OS_FORK_METHODDEF
16912 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
16913 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
16914 OS_SCHED_GETPARAM_METHODDEF
16915 OS_SCHED_GETSCHEDULER_METHODDEF
16916 OS_SCHED_RR_GET_INTERVAL_METHODDEF
16917 OS_SCHED_SETPARAM_METHODDEF
16918 OS_SCHED_SETSCHEDULER_METHODDEF
16919 OS_SCHED_YIELD_METHODDEF
16920 OS_SCHED_SETAFFINITY_METHODDEF
16921 OS_SCHED_GETAFFINITY_METHODDEF
16922 OS_OPENPTY_METHODDEF
16923 OS_FORKPTY_METHODDEF
16924 OS_GETEGID_METHODDEF
16925 OS_GETEUID_METHODDEF
16926 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020016927#ifdef HAVE_GETGROUPLIST
16928 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
16929#endif
Larry Hastings2f936352014-08-05 14:04:04 +100016930 OS_GETGROUPS_METHODDEF
16931 OS_GETPID_METHODDEF
16932 OS_GETPGRP_METHODDEF
16933 OS_GETPPID_METHODDEF
16934 OS_GETUID_METHODDEF
16935 OS_GETLOGIN_METHODDEF
16936 OS_KILL_METHODDEF
16937 OS_KILLPG_METHODDEF
16938 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000016939#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000016940 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000016941#endif
Larry Hastings2f936352014-08-05 14:04:04 +100016942 OS_SETUID_METHODDEF
16943 OS_SETEUID_METHODDEF
16944 OS_SETREUID_METHODDEF
16945 OS_SETGID_METHODDEF
16946 OS_SETEGID_METHODDEF
16947 OS_SETREGID_METHODDEF
16948 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000016949#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000016950 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000016951#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100016952 OS_GETPGID_METHODDEF
16953 OS_SETPGRP_METHODDEF
16954 OS_WAIT_METHODDEF
16955 OS_WAIT3_METHODDEF
16956 OS_WAIT4_METHODDEF
16957 OS_WAITID_METHODDEF
16958 OS_WAITPID_METHODDEF
16959 OS_GETSID_METHODDEF
16960 OS_SETSID_METHODDEF
16961 OS_SETPGID_METHODDEF
16962 OS_TCGETPGRP_METHODDEF
16963 OS_TCSETPGRP_METHODDEF
16964 OS_OPEN_METHODDEF
16965 OS_CLOSE_METHODDEF
16966 OS_CLOSERANGE_METHODDEF
16967 OS_DEVICE_ENCODING_METHODDEF
16968 OS_DUP_METHODDEF
16969 OS_DUP2_METHODDEF
16970 OS_LOCKF_METHODDEF
16971 OS_LSEEK_METHODDEF
16972 OS_READ_METHODDEF
16973 OS_READV_METHODDEF
16974 OS_PREAD_METHODDEF
16975 OS_WRITE_METHODDEF
16976 OS_WRITEV_METHODDEF
16977 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000016978#ifdef HAVE_SENDFILE
16979 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
16980 posix_sendfile__doc__},
16981#endif
Larry Hastings2f936352014-08-05 14:04:04 +100016982 OS_FSTAT_METHODDEF
16983 OS_ISATTY_METHODDEF
16984 OS_PIPE_METHODDEF
16985 OS_PIPE2_METHODDEF
16986 OS_MKFIFO_METHODDEF
16987 OS_MKNOD_METHODDEF
16988 OS_MAJOR_METHODDEF
16989 OS_MINOR_METHODDEF
16990 OS_MAKEDEV_METHODDEF
16991 OS_FTRUNCATE_METHODDEF
16992 OS_TRUNCATE_METHODDEF
16993 OS_POSIX_FALLOCATE_METHODDEF
16994 OS_POSIX_FADVISE_METHODDEF
16995 OS_PUTENV_METHODDEF
16996 OS_UNSETENV_METHODDEF
16997 OS_STRERROR_METHODDEF
16998 OS_FCHDIR_METHODDEF
16999 OS_FSYNC_METHODDEF
17000 OS_SYNC_METHODDEF
17001 OS_FDATASYNC_METHODDEF
17002 OS_WCOREDUMP_METHODDEF
17003 OS_WIFCONTINUED_METHODDEF
17004 OS_WIFSTOPPED_METHODDEF
17005 OS_WIFSIGNALED_METHODDEF
17006 OS_WIFEXITED_METHODDEF
17007 OS_WEXITSTATUS_METHODDEF
17008 OS_WTERMSIG_METHODDEF
17009 OS_WSTOPSIG_METHODDEF
17010 OS_FSTATVFS_METHODDEF
17011 OS_STATVFS_METHODDEF
17012 OS_CONFSTR_METHODDEF
17013 OS_SYSCONF_METHODDEF
17014 OS_FPATHCONF_METHODDEF
17015 OS_PATHCONF_METHODDEF
17016 OS_ABORT_METHODDEF
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000017017#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000017018 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050017019 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000017020#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017021 OS__GETDISKUSAGE_METHODDEF
17022 OS__GETFINALPATHNAME_METHODDEF
17023 OS__GETVOLUMEPATHNAME_METHODDEF
17024 OS_GETLOADAVG_METHODDEF
17025 OS_URANDOM_METHODDEF
17026 OS_SETRESUID_METHODDEF
17027 OS_SETRESGID_METHODDEF
17028 OS_GETRESUID_METHODDEF
17029 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000017030
Larry Hastings2f936352014-08-05 14:04:04 +100017031 OS_GETXATTR_METHODDEF
17032 OS_SETXATTR_METHODDEF
17033 OS_REMOVEXATTR_METHODDEF
17034 OS_LISTXATTR_METHODDEF
17035
Antoine Pitroubcf2b592012-02-08 23:28:36 +010017036#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
17037 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
17038#endif
Larry Hastings2f936352014-08-05 14:04:04 +100017039 OS_CPU_COUNT_METHODDEF
17040 OS_GET_INHERITABLE_METHODDEF
17041 OS_SET_INHERITABLE_METHODDEF
17042 OS_GET_HANDLE_INHERITABLE_METHODDEF
17043 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020017044#ifndef MS_WINDOWS
17045 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
17046 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
17047#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000017048 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000017049};
17050
17051
Brian Curtin52173d42010-12-02 18:29:18 +000017052#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000017053static int
Brian Curtin52173d42010-12-02 18:29:18 +000017054enable_symlink()
17055{
17056 HANDLE tok;
17057 TOKEN_PRIVILEGES tok_priv;
17058 LUID luid;
17059 int meth_idx = 0;
17060
17061 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017062 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017063
17064 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017065 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017066
17067 tok_priv.PrivilegeCount = 1;
17068 tok_priv.Privileges[0].Luid = luid;
17069 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
17070
17071 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
17072 sizeof(TOKEN_PRIVILEGES),
17073 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000017074 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000017075
Brian Curtin3b4499c2010-12-28 14:31:47 +000017076 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
17077 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000017078}
17079#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
17080
Barry Warsaw4a342091996-12-19 23:50:02 +000017081static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017082all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000017083{
Guido van Rossum94f6f721999-01-06 18:42:14 +000017084#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017085 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017086#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017087#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017088 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017089#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017090#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017091 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017092#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000017093#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017094 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017095#endif
Fred Drakec9680921999-12-13 16:37:25 +000017096#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017097 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000017098#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000017099#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017100 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000017101#endif
Fred Drake106c1a02002-04-23 15:58:02 +000017102#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017103 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000017104#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000017105#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017106 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017107#endif
Fred Drake106c1a02002-04-23 15:58:02 +000017108#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017109 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000017110#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000017111#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017112 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017113#endif
17114#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017115 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017116#endif
17117#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017118 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017119#endif
17120#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017121 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017122#endif
17123#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017124 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017125#endif
17126#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017127 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017128#endif
17129#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017130 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017131#endif
17132#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017133 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017134#endif
17135#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017136 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017137#endif
17138#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017139 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017140#endif
17141#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017142 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017143#endif
17144#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017145 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017146#endif
17147#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017148 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000017149#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000017150#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017151 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000017152#endif
17153#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017154 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000017155#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017156#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017157 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017158#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017159#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017160 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017161#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000017162#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017163 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000017164#endif
17165#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017166 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000017167#endif
Jesus Ceacf381202012-04-24 20:44:40 +020017168#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017169 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017170#endif
17171#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017172 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017173#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050017174#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017175 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050017176#endif
Jesus Ceacf381202012-04-24 20:44:40 +020017177#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017178 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020017179#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020017180#ifdef O_TMPFILE
17181 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
17182#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017183#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017184 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017185#endif
17186#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017187 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017188#endif
17189#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017190 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017191#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020017192#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017193 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020017194#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017195#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017196 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017197#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000017198
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017199
Jesus Cea94363612012-06-22 18:32:07 +020017200#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017201 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020017202#endif
17203#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017204 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020017205#endif
17206
Tim Peters5aa91602002-01-30 05:46:57 +000017207/* MS Windows */
17208#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000017209 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017210 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017211#endif
17212#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000017213 /* Optimize for short life (keep in memory). */
17214 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017215 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017216#endif
17217#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000017218 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017219 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017220#endif
17221#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000017222 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017223 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017224#endif
17225#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000017226 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017227 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000017228#endif
17229
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017230/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000017231#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000017232 /* Send a SIGIO signal whenever input or output
17233 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017234 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000017235#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017236#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000017237 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017238 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017239#endif
17240#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000017241 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017242 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017243#endif
17244#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000017245 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017246 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000017247#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020017248#ifdef O_NOLINKS
17249 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017250 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020017251#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000017252#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000017253 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017254 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000017255#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000017256
Victor Stinner8c62be82010-05-06 00:08:46 +000017257 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017258#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017259 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017260#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017261#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017262 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017263#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017264#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017265 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017266#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017267#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017268 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017269#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017270#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017271 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017272#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017273#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017274 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017275#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017276#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017277 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017278#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017279#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017280 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017281#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017282#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017283 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017284#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017285#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017286 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017287#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017288#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017289 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017290#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017291#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017292 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017293#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017294#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017295 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017296#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017297#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017298 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017299#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017300#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017301 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017302#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017303#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017304 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017305#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017306#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017307 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000017308#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000017309
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000017310 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017311#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017312 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017313#endif /* ST_RDONLY */
17314#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017315 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000017316#endif /* ST_NOSUID */
17317
doko@ubuntu.comca616a22013-12-08 15:23:07 +010017318 /* GNU extensions */
17319#ifdef ST_NODEV
17320 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
17321#endif /* ST_NODEV */
17322#ifdef ST_NOEXEC
17323 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
17324#endif /* ST_NOEXEC */
17325#ifdef ST_SYNCHRONOUS
17326 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
17327#endif /* ST_SYNCHRONOUS */
17328#ifdef ST_MANDLOCK
17329 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
17330#endif /* ST_MANDLOCK */
17331#ifdef ST_WRITE
17332 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
17333#endif /* ST_WRITE */
17334#ifdef ST_APPEND
17335 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
17336#endif /* ST_APPEND */
17337#ifdef ST_NOATIME
17338 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
17339#endif /* ST_NOATIME */
17340#ifdef ST_NODIRATIME
17341 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
17342#endif /* ST_NODIRATIME */
17343#ifdef ST_RELATIME
17344 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
17345#endif /* ST_RELATIME */
17346
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000017347 /* FreeBSD sendfile() constants */
17348#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017349 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000017350#endif
17351#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017352 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000017353#endif
17354#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017355 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000017356#endif
17357
Ross Lagerwall7807c352011-03-17 20:20:30 +020017358 /* constants for posix_fadvise */
17359#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017360 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017361#endif
17362#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017363 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017364#endif
17365#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017366 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017367#endif
17368#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017369 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017370#endif
17371#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017372 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017373#endif
17374#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017375 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017376#endif
17377
17378 /* constants for waitid */
17379#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017380 if (PyModule_AddIntMacro(m, P_PID)) return -1;
17381 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
17382 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017383#endif
17384#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017385 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017386#endif
17387#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017388 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017389#endif
17390#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017391 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017392#endif
17393#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017394 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017395#endif
17396#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017397 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017398#endif
17399#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017400 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017401#endif
17402#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017403 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017404#endif
17405
17406 /* constants for lockf */
17407#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017408 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017409#endif
17410#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017411 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017412#endif
17413#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017414 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017415#endif
17416#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017417 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017418#endif
17419
Guido van Rossum246bc171999-02-01 23:54:31 +000017420#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017421 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
17422 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
17423 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
17424 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
17425 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000017426#endif
17427
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017428#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017429 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
17430 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
17431 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017432#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017433 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017434#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017435#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017436 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017437#endif
17438#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017439 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017440#endif
17441#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017442 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017443#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020017444#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017445 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020017446#endif
17447#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017448 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020017449#endif
17450#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017451 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020017452#endif
17453#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017454 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020017455#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017456#endif
17457
Benjamin Peterson9428d532011-09-14 11:45:52 -040017458#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017459 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
17460 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
17461 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040017462#endif
17463
Victor Stinner8b905bd2011-10-25 13:34:04 +020017464#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017465 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017466#endif
17467#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017468 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017469#endif
17470#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017471 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017472#endif
17473#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017474 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017475#endif
17476#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017477 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017478#endif
17479#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017480 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017481#endif
17482#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020017483 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020017484#endif
17485
Victor Stinner8c62be82010-05-06 00:08:46 +000017486 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000017487}
17488
17489
Victor Stinnerd42c4282014-10-10 00:09:47 +020017490#ifdef MS_WINDOWS
Martin v. Löwis1a214512008-06-11 05:26:20 +000017491#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000017492#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000017493
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000017494#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000017495#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000017496#define MODNAME "posix"
17497#endif
17498
Martin v. Löwis1a214512008-06-11 05:26:20 +000017499static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000017500 PyModuleDef_HEAD_INIT,
17501 MODNAME,
17502 posix__doc__,
17503 -1,
17504 posix_methods,
17505 NULL,
17506 NULL,
17507 NULL,
17508 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000017509};
17510
17511
Larry Hastings9cf065c2012-06-22 16:30:09 -070017512static char *have_functions[] = {
17513
17514#ifdef HAVE_FACCESSAT
17515 "HAVE_FACCESSAT",
17516#endif
17517
17518#ifdef HAVE_FCHDIR
17519 "HAVE_FCHDIR",
17520#endif
17521
17522#ifdef HAVE_FCHMOD
17523 "HAVE_FCHMOD",
17524#endif
17525
17526#ifdef HAVE_FCHMODAT
17527 "HAVE_FCHMODAT",
17528#endif
17529
17530#ifdef HAVE_FCHOWN
17531 "HAVE_FCHOWN",
17532#endif
17533
Larry Hastings00964ed2013-08-12 13:49:30 -040017534#ifdef HAVE_FCHOWNAT
17535 "HAVE_FCHOWNAT",
17536#endif
17537
Larry Hastings9cf065c2012-06-22 16:30:09 -070017538#ifdef HAVE_FEXECVE
17539 "HAVE_FEXECVE",
17540#endif
17541
17542#ifdef HAVE_FDOPENDIR
17543 "HAVE_FDOPENDIR",
17544#endif
17545
Georg Brandl306336b2012-06-24 12:55:33 +020017546#ifdef HAVE_FPATHCONF
17547 "HAVE_FPATHCONF",
17548#endif
17549
Larry Hastings9cf065c2012-06-22 16:30:09 -070017550#ifdef HAVE_FSTATAT
17551 "HAVE_FSTATAT",
17552#endif
17553
17554#ifdef HAVE_FSTATVFS
17555 "HAVE_FSTATVFS",
17556#endif
17557
Georg Brandl306336b2012-06-24 12:55:33 +020017558#ifdef HAVE_FTRUNCATE
17559 "HAVE_FTRUNCATE",
17560#endif
17561
Larry Hastings9cf065c2012-06-22 16:30:09 -070017562#ifdef HAVE_FUTIMENS
17563 "HAVE_FUTIMENS",
17564#endif
17565
17566#ifdef HAVE_FUTIMES
17567 "HAVE_FUTIMES",
17568#endif
17569
17570#ifdef HAVE_FUTIMESAT
17571 "HAVE_FUTIMESAT",
17572#endif
17573
17574#ifdef HAVE_LINKAT
17575 "HAVE_LINKAT",
17576#endif
17577
17578#ifdef HAVE_LCHFLAGS
17579 "HAVE_LCHFLAGS",
17580#endif
17581
17582#ifdef HAVE_LCHMOD
17583 "HAVE_LCHMOD",
17584#endif
17585
17586#ifdef HAVE_LCHOWN
17587 "HAVE_LCHOWN",
17588#endif
17589
17590#ifdef HAVE_LSTAT
17591 "HAVE_LSTAT",
17592#endif
17593
17594#ifdef HAVE_LUTIMES
17595 "HAVE_LUTIMES",
17596#endif
17597
17598#ifdef HAVE_MKDIRAT
17599 "HAVE_MKDIRAT",
17600#endif
17601
17602#ifdef HAVE_MKFIFOAT
17603 "HAVE_MKFIFOAT",
17604#endif
17605
17606#ifdef HAVE_MKNODAT
17607 "HAVE_MKNODAT",
17608#endif
17609
17610#ifdef HAVE_OPENAT
17611 "HAVE_OPENAT",
17612#endif
17613
17614#ifdef HAVE_READLINKAT
17615 "HAVE_READLINKAT",
17616#endif
17617
17618#ifdef HAVE_RENAMEAT
17619 "HAVE_RENAMEAT",
17620#endif
17621
17622#ifdef HAVE_SYMLINKAT
17623 "HAVE_SYMLINKAT",
17624#endif
17625
17626#ifdef HAVE_UNLINKAT
17627 "HAVE_UNLINKAT",
17628#endif
17629
17630#ifdef HAVE_UTIMENSAT
17631 "HAVE_UTIMENSAT",
17632#endif
17633
17634#ifdef MS_WINDOWS
17635 "MS_WINDOWS",
17636#endif
17637
17638 NULL
17639};
17640
17641
Mark Hammondfe51c6d2002-08-02 02:27:13 +000017642PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000017643INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000017644{
Victor Stinner8c62be82010-05-06 00:08:46 +000017645 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070017646 PyObject *list;
17647 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000017648
Brian Curtin52173d42010-12-02 18:29:18 +000017649#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000017650 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000017651#endif
17652
Victor Stinner8c62be82010-05-06 00:08:46 +000017653 m = PyModule_Create(&posixmodule);
17654 if (m == NULL)
17655 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000017656
Victor Stinner8c62be82010-05-06 00:08:46 +000017657 /* Initialize environ dictionary */
17658 v = convertenviron();
17659 Py_XINCREF(v);
17660 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
17661 return NULL;
17662 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000017663
Victor Stinner8c62be82010-05-06 00:08:46 +000017664 if (all_ins(m))
17665 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000017666
Victor Stinner8c62be82010-05-06 00:08:46 +000017667 if (setup_confname_tables(m))
17668 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000017669
Victor Stinner8c62be82010-05-06 00:08:46 +000017670 Py_INCREF(PyExc_OSError);
17671 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000017672
Guido van Rossumb3d39562000-01-31 18:41:26 +000017673#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000017674 if (posix_putenv_garbage == NULL)
17675 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000017676#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000017677
Victor Stinner8c62be82010-05-06 00:08:46 +000017678 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020017679#if defined(HAVE_WAITID) && !defined(__APPLE__)
17680 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020017681 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
17682 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020017683#endif
17684
Christian Heimes25827622013-10-12 01:27:08 +020017685 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000017686 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
17687 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
17688 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020017689 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
17690 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000017691 structseq_new = StatResultType.tp_new;
17692 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000017693
Christian Heimes25827622013-10-12 01:27:08 +020017694 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020017695 if (PyStructSequence_InitType2(&StatVFSResultType,
17696 &statvfs_result_desc) < 0)
17697 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000017698#ifdef NEED_TICKS_PER_SECOND
17699# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000017700 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000017701# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000017702 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000017703# else
Victor Stinner8c62be82010-05-06 00:08:46 +000017704 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000017705# endif
17706#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017707
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050017708#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017709 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020017710 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
17711 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100017712 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017713#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010017714
17715 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020017716 if (PyStructSequence_InitType2(&TerminalSizeType,
17717 &TerminalSize_desc) < 0)
17718 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000017719 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020017720#if defined(HAVE_WAITID) && !defined(__APPLE__)
17721 Py_INCREF((PyObject*) &WaitidResultType);
17722 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
17723#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000017724 Py_INCREF((PyObject*) &StatResultType);
17725 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
17726 Py_INCREF((PyObject*) &StatVFSResultType);
17727 PyModule_AddObject(m, "statvfs_result",
17728 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050017729
17730#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050017731 Py_INCREF(&SchedParamType);
17732 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050017733#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000017734
Larry Hastings605a62d2012-06-24 04:33:36 -070017735 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020017736 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
17737 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070017738 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
17739
17740 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020017741 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
17742 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070017743 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
17744
Thomas Wouters477c8d52006-05-27 19:21:47 +000017745#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000017746 /*
17747 * Step 2 of weak-linking support on Mac OS X.
17748 *
17749 * The code below removes functions that are not available on the
17750 * currently active platform.
17751 *
17752 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070017753 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000017754 * OSX 10.4.
17755 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000017756#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000017757 if (fstatvfs == NULL) {
17758 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
17759 return NULL;
17760 }
17761 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000017762#endif /* HAVE_FSTATVFS */
17763
17764#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000017765 if (statvfs == NULL) {
17766 if (PyObject_DelAttrString(m, "statvfs") == -1) {
17767 return NULL;
17768 }
17769 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000017770#endif /* HAVE_STATVFS */
17771
17772# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000017773 if (lchown == NULL) {
17774 if (PyObject_DelAttrString(m, "lchown") == -1) {
17775 return NULL;
17776 }
17777 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000017778#endif /* HAVE_LCHOWN */
17779
17780
17781#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010017782
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020017783 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010017784 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
17785
Larry Hastings6fe20b32012-04-19 15:07:49 -070017786 billion = PyLong_FromLong(1000000000);
17787 if (!billion)
17788 return NULL;
17789
Larry Hastings9cf065c2012-06-22 16:30:09 -070017790 /* suppress "function not used" warnings */
17791 {
17792 int ignored;
17793 fd_specified("", -1);
17794 follow_symlinks_specified("", 1);
17795 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
17796 dir_fd_converter(Py_None, &ignored);
17797 dir_fd_unavailable(Py_None, &ignored);
17798 }
17799
17800 /*
17801 * provide list of locally available functions
17802 * so os.py can populate support_* lists
17803 */
17804 list = PyList_New(0);
17805 if (!list)
17806 return NULL;
17807 for (trace = have_functions; *trace; trace++) {
17808 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
17809 if (!unicode)
17810 return NULL;
17811 if (PyList_Append(list, unicode))
17812 return NULL;
17813 Py_DECREF(unicode);
17814 }
17815 PyModule_AddObject(m, "_have_functions", list);
17816
17817 initialized = 1;
17818
Victor Stinner8c62be82010-05-06 00:08:46 +000017819 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000017820}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000017821
17822#ifdef __cplusplus
17823}
17824#endif