blob: 916be81e431619729babb3876135cb42027a7e35 [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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_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 __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_WAIT 1
152#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000154#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000155#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000156#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#define HAVE_EXECV 1
158#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
160#define HAVE_CWAIT 1
161#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000162#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000163#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164/* Unix functions that the configure script doesn't check for */
165#define HAVE_EXECV 1
166#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000168#define HAVE_FORK1 1
169#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#define HAVE_GETEGID 1
171#define HAVE_GETEUID 1
172#define HAVE_GETGID 1
173#define HAVE_GETPPID 1
174#define HAVE_GETUID 1
175#define HAVE_KILL 1
176#define HAVE_OPENDIR 1
177#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif /* _MSC_VER */
182#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000183#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000184
Victor Stinnera2f7c002012-02-08 03:36:25 +0100185
Larry Hastings61272b72014-01-07 12:41:53 -0800186/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800187module os
Larry Hastings61272b72014-01-07 12:41:53 -0800188[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800189/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100190
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000192
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000193#if defined(__sgi)&&_COMPILER_VERSION>=700
194/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
195 (default) */
196extern char *ctermid_r(char *);
197#endif
198
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000199#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000200#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#endif
209#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chdir(char *);
211extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000212#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int chdir(const char *);
214extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000215#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000216#ifdef __BORLANDC__
217extern int chmod(const char *, int);
218#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000220#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000221/*#ifdef HAVE_FCHMOD
222extern int fchmod(int, mode_t);
223#endif*/
224/*#ifdef HAVE_LCHMOD
225extern int lchmod(const char *, mode_t);
226#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chown(const char *, uid_t, gid_t);
228extern char *getcwd(char *, int);
229extern char *strerror(int);
230extern int link(const char *, const char *);
231extern int rename(const char *, const char *);
232extern int stat(const char *, struct stat *);
233extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000235extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000236#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000238extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000239#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000241
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000242#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_UTIME_H
245#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000248#ifdef HAVE_SYS_UTIME_H
249#include <sys/utime.h>
250#define HAVE_UTIME_H /* pretend we do for the rest of this file */
251#endif /* HAVE_SYS_UTIME_H */
252
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#ifdef HAVE_SYS_TIMES_H
254#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000255#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
257#ifdef HAVE_SYS_PARAM_H
258#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_UTSNAME_H
262#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#define NAMLEN(dirent) strlen((dirent)->d_name)
268#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000269#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000270#include <direct.h>
271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#endif
279#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#endif
282#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000284#endif
285#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000287#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#endif
291#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#endif
294#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000298#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#endif
300#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000301#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000302#endif
303#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000304#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000305#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100306#ifndef IO_REPARSE_TAG_MOUNT_POINT
307#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
308#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000309#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000310#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000311#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000312#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000313#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000314#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
315#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000316static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000317#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000318#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000319
Tim Petersbc2e10e2002-03-03 23:17:02 +0000320#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321#if defined(PATH_MAX) && PATH_MAX > 1024
322#define MAXPATHLEN PATH_MAX
323#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000326#endif /* MAXPATHLEN */
327
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000328#ifdef UNION_WAIT
329/* Emulate some macros on systems that have a union instead of macros */
330
331#ifndef WIFEXITED
332#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333#endif
334
335#ifndef WEXITSTATUS
336#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
337#endif
338
339#ifndef WTERMSIG
340#define WTERMSIG(u_wait) ((u_wait).w_termsig)
341#endif
342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343#define WAIT_TYPE union wait
344#define WAIT_STATUS_INT(s) (s.w_status)
345
346#else /* !UNION_WAIT */
347#define WAIT_TYPE int
348#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000349#endif /* UNION_WAIT */
350
Greg Wardb48bc172000-03-01 21:51:56 +0000351/* Don't use the "_r" form if we don't need it (also, won't have a
352 prototype for it, at least on Solaris -- maybe others as well?). */
353#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
354#define USE_CTERMID_R
355#endif
356
Fred Drake699f3522000-06-29 21:12:41 +0000357/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000358#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000359#undef FSTAT
360#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200361#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT win32_fstat
365# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700368# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define FSTAT fstat
370# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000371#endif
372
Tim Peters11b23062003-04-23 02:39:17 +0000373#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000374#include <sys/mkdev.h>
375#else
376#if defined(MAJOR_IN_SYSMACROS)
377#include <sys/sysmacros.h>
378#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000379#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
380#include <sys/mkdev.h>
381#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000382#endif
Fred Drake699f3522000-06-29 21:12:41 +0000383
Victor Stinner6edddfa2013-11-24 19:22:57 +0100384#define DWORD_MAX 4294967295U
385
Larry Hastings9cf065c2012-06-22 16:30:09 -0700386
387#ifdef MS_WINDOWS
388static int
389win32_warn_bytes_api()
390{
391 return PyErr_WarnEx(PyExc_DeprecationWarning,
392 "The Windows bytes API has been deprecated, "
393 "use Unicode filenames instead",
394 1);
395}
396#endif
397
398
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200399#ifndef MS_WINDOWS
400PyObject *
401_PyLong_FromUid(uid_t uid)
402{
403 if (uid == (uid_t)-1)
404 return PyLong_FromLong(-1);
405 return PyLong_FromUnsignedLong(uid);
406}
407
408PyObject *
409_PyLong_FromGid(gid_t gid)
410{
411 if (gid == (gid_t)-1)
412 return PyLong_FromLong(-1);
413 return PyLong_FromUnsignedLong(gid);
414}
415
416int
417_Py_Uid_Converter(PyObject *obj, void *p)
418{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700419 uid_t uid;
420 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200421 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200422 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700423 unsigned long uresult;
424
425 index = PyNumber_Index(obj);
426 if (index == NULL) {
427 PyErr_Format(PyExc_TypeError,
428 "uid should be integer, not %.200s",
429 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200430 return 0;
431 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700432
433 /*
434 * Handling uid_t is complicated for two reasons:
435 * * Although uid_t is (always?) unsigned, it still
436 * accepts -1.
437 * * We don't know its size in advance--it may be
438 * bigger than an int, or it may be smaller than
439 * a long.
440 *
441 * So a bit of defensive programming is in order.
442 * Start with interpreting the value passed
443 * in as a signed long and see if it works.
444 */
445
446 result = PyLong_AsLongAndOverflow(index, &overflow);
447
448 if (!overflow) {
449 uid = (uid_t)result;
450
451 if (result == -1) {
452 if (PyErr_Occurred())
453 goto fail;
454 /* It's a legitimate -1, we're done. */
455 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200456 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700457
458 /* Any other negative number is disallowed. */
459 if (result < 0)
460 goto underflow;
461
462 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200463 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700464 (long)uid != result)
465 goto underflow;
466 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200467 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700468
469 if (overflow < 0)
470 goto underflow;
471
472 /*
473 * Okay, the value overflowed a signed long. If it
474 * fits in an *unsigned* long, it may still be okay,
475 * as uid_t may be unsigned long on this platform.
476 */
477 uresult = PyLong_AsUnsignedLong(index);
478 if (PyErr_Occurred()) {
479 if (PyErr_ExceptionMatches(PyExc_OverflowError))
480 goto overflow;
481 goto fail;
482 }
483
484 uid = (uid_t)uresult;
485
486 /*
487 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
488 * but this value would get interpreted as (uid_t)-1 by chown
489 * and its siblings. That's not what the user meant! So we
490 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100491 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700492 */
493 if (uid == (uid_t)-1)
494 goto overflow;
495
496 /* Ensure the value wasn't truncated. */
497 if (sizeof(uid_t) < sizeof(long) &&
498 (unsigned long)uid != uresult)
499 goto overflow;
500 /* fallthrough */
501
502success:
503 Py_DECREF(index);
504 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200505 return 1;
506
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700507underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 "uid is less than minimum");
510 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200511
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700512overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200513 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700514 "uid is greater than maximum");
515 /* fallthrough */
516
517fail:
518 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200519 return 0;
520}
521
522int
523_Py_Gid_Converter(PyObject *obj, void *p)
524{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700525 gid_t gid;
526 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200527 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200528 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529 unsigned long uresult;
530
531 index = PyNumber_Index(obj);
532 if (index == NULL) {
533 PyErr_Format(PyExc_TypeError,
534 "gid should be integer, not %.200s",
535 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200536 return 0;
537 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700538
539 /*
540 * Handling gid_t is complicated for two reasons:
541 * * Although gid_t is (always?) unsigned, it still
542 * accepts -1.
543 * * We don't know its size in advance--it may be
544 * bigger than an int, or it may be smaller than
545 * a long.
546 *
547 * So a bit of defensive programming is in order.
548 * Start with interpreting the value passed
549 * in as a signed long and see if it works.
550 */
551
552 result = PyLong_AsLongAndOverflow(index, &overflow);
553
554 if (!overflow) {
555 gid = (gid_t)result;
556
557 if (result == -1) {
558 if (PyErr_Occurred())
559 goto fail;
560 /* It's a legitimate -1, we're done. */
561 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200562 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700563
564 /* Any other negative number is disallowed. */
565 if (result < 0) {
566 goto underflow;
567 }
568
569 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200570 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700571 (long)gid != result)
572 goto underflow;
573 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575
576 if (overflow < 0)
577 goto underflow;
578
579 /*
580 * Okay, the value overflowed a signed long. If it
581 * fits in an *unsigned* long, it may still be okay,
582 * as gid_t may be unsigned long on this platform.
583 */
584 uresult = PyLong_AsUnsignedLong(index);
585 if (PyErr_Occurred()) {
586 if (PyErr_ExceptionMatches(PyExc_OverflowError))
587 goto overflow;
588 goto fail;
589 }
590
591 gid = (gid_t)uresult;
592
593 /*
594 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
595 * but this value would get interpreted as (gid_t)-1 by chown
596 * and its siblings. That's not what the user meant! So we
597 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100598 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700599 */
600 if (gid == (gid_t)-1)
601 goto overflow;
602
603 /* Ensure the value wasn't truncated. */
604 if (sizeof(gid_t) < sizeof(long) &&
605 (unsigned long)gid != uresult)
606 goto overflow;
607 /* fallthrough */
608
609success:
610 Py_DECREF(index);
611 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612 return 1;
613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "gid is less than minimum");
617 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621 "gid is greater than maximum");
622 /* fallthrough */
623
624fail:
625 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 return 0;
627}
628#endif /* MS_WINDOWS */
629
630
Larry Hastings9cf065c2012-06-22 16:30:09 -0700631#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400632/*
633 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
634 * without the int cast, the value gets interpreted as uint (4291925331),
635 * which doesn't play nicely with all the initializer lines in this file that
636 * look like this:
637 * int dir_fd = DEFAULT_DIR_FD;
638 */
639#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700640#else
641#define DEFAULT_DIR_FD (-100)
642#endif
643
644static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200645_fd_converter(PyObject *o, int *p, const char *allowed)
646{
647 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700648 long long_value;
649
650 PyObject *index = PyNumber_Index(o);
651 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200652 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700653 "argument should be %s, not %.200s",
654 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700655 return 0;
656 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700657
658 long_value = PyLong_AsLongAndOverflow(index, &overflow);
659 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200660 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700661 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700662 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663 return 0;
664 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200665 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700667 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700668 return 0;
669 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700670
Larry Hastings9cf065c2012-06-22 16:30:09 -0700671 *p = (int)long_value;
672 return 1;
673}
674
675static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200676dir_fd_converter(PyObject *o, void *p)
677{
678 if (o == Py_None) {
679 *(int *)p = DEFAULT_DIR_FD;
680 return 1;
681 }
682 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700683}
684
685
686
687/*
688 * A PyArg_ParseTuple "converter" function
689 * that handles filesystem paths in the manner
690 * preferred by the os module.
691 *
692 * path_converter accepts (Unicode) strings and their
693 * subclasses, and bytes and their subclasses. What
694 * it does with the argument depends on the platform:
695 *
696 * * On Windows, if we get a (Unicode) string we
697 * extract the wchar_t * and return it; if we get
698 * bytes we extract the char * and return that.
699 *
700 * * On all other platforms, strings are encoded
701 * to bytes using PyUnicode_FSConverter, then we
702 * extract the char * from the bytes object and
703 * return that.
704 *
705 * path_converter also optionally accepts signed
706 * integers (representing open file descriptors) instead
707 * of path strings.
708 *
709 * Input fields:
710 * path.nullable
711 * If nonzero, the path is permitted to be None.
712 * path.allow_fd
713 * If nonzero, the path is permitted to be a file handle
714 * (a signed int) instead of a string.
715 * path.function_name
716 * If non-NULL, path_converter will use that as the name
717 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700718 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700719 * path.argument_name
720 * If non-NULL, path_converter will use that as the name
721 * of the parameter in error messages.
722 * (If path.argument_name is NULL it uses "path".)
723 *
724 * Output fields:
725 * path.wide
726 * Points to the path if it was expressed as Unicode
727 * and was not encoded. (Only used on Windows.)
728 * path.narrow
729 * Points to the path if it was expressed as bytes,
730 * or it was Unicode and was encoded to bytes.
731 * path.fd
732 * Contains a file descriptor if path.accept_fd was true
733 * and the caller provided a signed integer instead of any
734 * sort of string.
735 *
736 * WARNING: if your "path" parameter is optional, and is
737 * unspecified, path_converter will never get called.
738 * So if you set allow_fd, you *MUST* initialize path.fd = -1
739 * yourself!
740 * path.length
741 * The length of the path in characters, if specified as
742 * a string.
743 * path.object
744 * The original object passed in.
745 * path.cleanup
746 * For internal use only. May point to a temporary object.
747 * (Pay no attention to the man behind the curtain.)
748 *
749 * At most one of path.wide or path.narrow will be non-NULL.
750 * If path was None and path.nullable was set,
751 * or if path was an integer and path.allow_fd was set,
752 * both path.wide and path.narrow will be NULL
753 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200754 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755 * path_converter takes care to not write to the path_t
756 * unless it's successful. However it must reset the
757 * "cleanup" field each time it's called.
758 *
759 * Use as follows:
760 * path_t path;
761 * memset(&path, 0, sizeof(path));
762 * PyArg_ParseTuple(args, "O&", path_converter, &path);
763 * // ... use values from path ...
764 * path_cleanup(&path);
765 *
766 * (Note that if PyArg_Parse fails you don't need to call
767 * path_cleanup(). However it is safe to do so.)
768 */
769typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100770 const char *function_name;
771 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700772 int nullable;
773 int allow_fd;
774 wchar_t *wide;
775 char *narrow;
776 int fd;
777 Py_ssize_t length;
778 PyObject *object;
779 PyObject *cleanup;
780} path_t;
781
Larry Hastings31826802013-10-19 00:09:25 -0700782#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
783 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
784
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785static void
786path_cleanup(path_t *path) {
787 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200788 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 }
790}
791
792static int
793path_converter(PyObject *o, void *p) {
794 path_t *path = (path_t *)p;
795 PyObject *unicode, *bytes;
796 Py_ssize_t length;
797 char *narrow;
798
799#define FORMAT_EXCEPTION(exc, fmt) \
800 PyErr_Format(exc, "%s%s" fmt, \
801 path->function_name ? path->function_name : "", \
802 path->function_name ? ": " : "", \
803 path->argument_name ? path->argument_name : "path")
804
805 /* Py_CLEANUP_SUPPORTED support */
806 if (o == NULL) {
807 path_cleanup(path);
808 return 1;
809 }
810
811 /* ensure it's always safe to call path_cleanup() */
812 path->cleanup = NULL;
813
814 if (o == Py_None) {
815 if (!path->nullable) {
816 FORMAT_EXCEPTION(PyExc_TypeError,
817 "can't specify None for %s argument");
818 return 0;
819 }
820 path->wide = NULL;
821 path->narrow = NULL;
822 path->length = 0;
823 path->object = o;
824 path->fd = -1;
825 return 1;
826 }
827
828 unicode = PyUnicode_FromObject(o);
829 if (unicode) {
830#ifdef MS_WINDOWS
831 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100832
833 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
834 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700835 Py_DECREF(unicode);
836 return 0;
837 }
Victor Stinner59799a82013-11-13 14:17:30 +0100838 if (length > 32767) {
839 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840 Py_DECREF(unicode);
841 return 0;
842 }
843
844 path->wide = wide;
845 path->narrow = NULL;
846 path->length = length;
847 path->object = o;
848 path->fd = -1;
849 path->cleanup = unicode;
850 return Py_CLEANUP_SUPPORTED;
851#else
852 int converted = PyUnicode_FSConverter(unicode, &bytes);
853 Py_DECREF(unicode);
854 if (!converted)
855 bytes = NULL;
856#endif
857 }
858 else {
859 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200860 if (PyObject_CheckBuffer(o))
861 bytes = PyBytes_FromObject(o);
862 else
863 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700864 if (!bytes) {
865 PyErr_Clear();
866 if (path->allow_fd) {
867 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200868 int result = _fd_converter(o, &fd,
869 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700870 if (result) {
871 path->wide = NULL;
872 path->narrow = NULL;
873 path->length = 0;
874 path->object = o;
875 path->fd = fd;
876 return result;
877 }
878 }
879 }
880 }
881
882 if (!bytes) {
883 if (!PyErr_Occurred())
884 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
885 return 0;
886 }
887
888#ifdef MS_WINDOWS
889 if (win32_warn_bytes_api()) {
890 Py_DECREF(bytes);
891 return 0;
892 }
893#endif
894
895 length = PyBytes_GET_SIZE(bytes);
896#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100897 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
899 Py_DECREF(bytes);
900 return 0;
901 }
902#endif
903
904 narrow = PyBytes_AS_STRING(bytes);
905 if (length != strlen(narrow)) {
906 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
907 Py_DECREF(bytes);
908 return 0;
909 }
910
911 path->wide = NULL;
912 path->narrow = narrow;
913 path->length = length;
914 path->object = o;
915 path->fd = -1;
916 path->cleanup = bytes;
917 return Py_CLEANUP_SUPPORTED;
918}
919
920static void
921argument_unavailable_error(char *function_name, char *argument_name) {
922 PyErr_Format(PyExc_NotImplementedError,
923 "%s%s%s unavailable on this platform",
924 (function_name != NULL) ? function_name : "",
925 (function_name != NULL) ? ": ": "",
926 argument_name);
927}
928
929static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200930dir_fd_unavailable(PyObject *o, void *p)
931{
932 int dir_fd;
933 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200935 if (dir_fd != DEFAULT_DIR_FD) {
936 argument_unavailable_error(NULL, "dir_fd");
937 return 0;
938 }
939 *(int *)p = dir_fd;
940 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941}
942
943static int
944fd_specified(char *function_name, int fd) {
945 if (fd == -1)
946 return 0;
947
948 argument_unavailable_error(function_name, "fd");
949 return 1;
950}
951
952static int
953follow_symlinks_specified(char *function_name, int follow_symlinks) {
954 if (follow_symlinks)
955 return 0;
956
957 argument_unavailable_error(function_name, "follow_symlinks");
958 return 1;
959}
960
961static int
962path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
963 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
964 PyErr_Format(PyExc_ValueError,
965 "%s: can't specify dir_fd without matching path",
966 function_name);
967 return 1;
968 }
969 return 0;
970}
971
972static int
973dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
974 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
975 PyErr_Format(PyExc_ValueError,
976 "%s: can't specify both dir_fd and fd",
977 function_name);
978 return 1;
979 }
980 return 0;
981}
982
983static int
984fd_and_follow_symlinks_invalid(char *function_name, int fd,
985 int follow_symlinks) {
986 if ((fd > 0) && (!follow_symlinks)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: cannot use fd and follow_symlinks together",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
995static int
996dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
997 int follow_symlinks) {
998 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
999 PyErr_Format(PyExc_ValueError,
1000 "%s: cannot use dir_fd and follow_symlinks together",
1001 function_name);
1002 return 1;
1003 }
1004 return 0;
1005}
1006
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001007/* A helper used by a number of POSIX-only functions */
1008#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001009static int
1010_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001011{
1012#if !defined(HAVE_LARGEFILE_SUPPORT)
1013 *((off_t*)addr) = PyLong_AsLong(arg);
1014#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001015 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001016#endif
1017 if (PyErr_Occurred())
1018 return 0;
1019 return 1;
1020}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001021#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001022
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001023#if defined _MSC_VER && _MSC_VER >= 1400
1024/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001025 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001026 * Normally, an invalid fd is likely to be a C program error and therefore
1027 * an assertion can be useful, but it does contradict the POSIX standard
1028 * which for write(2) states:
1029 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1030 * "[EBADF] The fildes argument is not a valid file descriptor open for
1031 * writing."
1032 * Furthermore, python allows the user to enter any old integer
1033 * as a fd and should merely raise a python exception on error.
1034 * The Microsoft CRT doesn't provide an official way to check for the
1035 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001036 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001037 * internal structures involved.
1038 * The structures below must be updated for each version of visual studio
1039 * according to the file internal.h in the CRT source, until MS comes
1040 * up with a less hacky way to do this.
1041 * (all of this is to avoid globally modifying the CRT behaviour using
1042 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1043 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001044/* The actual size of the structure is determined at runtime.
1045 * Only the first items must be present.
1046 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001047typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001048 intptr_t osfhnd;
1049 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001050} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001051
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001052extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001053#define IOINFO_L2E 5
1054#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1055#define IOINFO_ARRAYS 64
1056#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1057#define FOPEN 0x01
1058#define _NO_CONSOLE_FILENO (intptr_t)-2
1059
1060/* This function emulates what the windows CRT does to validate file handles */
1061int
1062_PyVerify_fd(int fd)
1063{
Victor Stinner8c62be82010-05-06 00:08:46 +00001064 const int i1 = fd >> IOINFO_L2E;
1065 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001066
Antoine Pitrou22e41552010-08-15 18:07:50 +00001067 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 /* Determine the actual size of the ioinfo structure,
1070 * as used by the CRT loaded in memory
1071 */
1072 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1073 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1074 }
1075 if (sizeof_ioinfo == 0) {
1076 /* This should not happen... */
1077 goto fail;
1078 }
1079
1080 /* See that it isn't a special CLEAR fileno */
1081 if (fd != _NO_CONSOLE_FILENO) {
1082 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1083 * we check pointer validity and other info
1084 */
1085 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1086 /* finally, check that the file is open */
1087 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1088 if (info->osfile & FOPEN) {
1089 return 1;
1090 }
1091 }
1092 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001093 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001094 errno = EBADF;
1095 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001096}
1097
1098/* the special case of checking dup2. The target fd must be in a sensible range */
1099static int
1100_PyVerify_fd_dup2(int fd1, int fd2)
1101{
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 if (!_PyVerify_fd(fd1))
1103 return 0;
1104 if (fd2 == _NO_CONSOLE_FILENO)
1105 return 0;
1106 if ((unsigned)fd2 < _NHANDLE_)
1107 return 1;
1108 else
1109 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001110}
1111#else
1112/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1113#define _PyVerify_fd_dup2(A, B) (1)
1114#endif
1115
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001116#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001117
1118static int
Brian Curtind25aef52011-06-13 15:16:04 -05001119win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001120{
1121 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1122 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1123 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001124
1125 if (0 == DeviceIoControl(
1126 reparse_point_handle,
1127 FSCTL_GET_REPARSE_POINT,
1128 NULL, 0, /* in buffer */
1129 target_buffer, sizeof(target_buffer),
1130 &n_bytes_returned,
1131 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001132 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001133
1134 if (reparse_tag)
1135 *reparse_tag = rdb->ReparseTag;
1136
Brian Curtind25aef52011-06-13 15:16:04 -05001137 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001138}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001139
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001140#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001141
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001143#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001144/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001145** environ directly, we must obtain it with _NSGetEnviron(). See also
1146** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001147*/
1148#include <crt_externs.h>
1149static char **environ;
1150#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001151extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001152#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153
Barry Warsaw53699e91996-12-10 23:23:01 +00001154static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001155convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156{
Victor Stinner8c62be82010-05-06 00:08:46 +00001157 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001158#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001159 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001160#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001161 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001162#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001163
Victor Stinner8c62be82010-05-06 00:08:46 +00001164 d = PyDict_New();
1165 if (d == NULL)
1166 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001167#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001168 if (environ == NULL)
1169 environ = *_NSGetEnviron();
1170#endif
1171#ifdef MS_WINDOWS
1172 /* _wenviron must be initialized in this way if the program is started
1173 through main() instead of wmain(). */
1174 _wgetenv(L"");
1175 if (_wenviron == NULL)
1176 return d;
1177 /* This part ignores errors */
1178 for (e = _wenviron; *e != NULL; e++) {
1179 PyObject *k;
1180 PyObject *v;
1181 wchar_t *p = wcschr(*e, L'=');
1182 if (p == NULL)
1183 continue;
1184 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1185 if (k == NULL) {
1186 PyErr_Clear();
1187 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001188 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001189 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1190 if (v == NULL) {
1191 PyErr_Clear();
1192 Py_DECREF(k);
1193 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001194 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 if (PyDict_GetItem(d, k) == NULL) {
1196 if (PyDict_SetItem(d, k, v) != 0)
1197 PyErr_Clear();
1198 }
1199 Py_DECREF(k);
1200 Py_DECREF(v);
1201 }
1202#else
1203 if (environ == NULL)
1204 return d;
1205 /* This part ignores errors */
1206 for (e = environ; *e != NULL; e++) {
1207 PyObject *k;
1208 PyObject *v;
1209 char *p = strchr(*e, '=');
1210 if (p == NULL)
1211 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001212 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001213 if (k == NULL) {
1214 PyErr_Clear();
1215 continue;
1216 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001217 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001218 if (v == NULL) {
1219 PyErr_Clear();
1220 Py_DECREF(k);
1221 continue;
1222 }
1223 if (PyDict_GetItem(d, k) == NULL) {
1224 if (PyDict_SetItem(d, k, v) != 0)
1225 PyErr_Clear();
1226 }
1227 Py_DECREF(k);
1228 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001229 }
1230#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001232}
1233
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234/* Set a POSIX-specific error from errno, and return NULL */
1235
Barry Warsawd58d7641998-07-23 16:14:40 +00001236static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001237posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001238{
Victor Stinner8c62be82010-05-06 00:08:46 +00001239 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001240}
Mark Hammondef8b6542001-05-13 08:04:26 +00001241
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001242#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001243static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001244win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001245{
Victor Stinner8c62be82010-05-06 00:08:46 +00001246 /* XXX We should pass the function name along in the future.
1247 (winreg.c also wants to pass the function name.)
1248 This would however require an additional param to the
1249 Windows error object, which is non-trivial.
1250 */
1251 errno = GetLastError();
1252 if (filename)
1253 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1254 else
1255 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001256}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001257
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001258static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001259win32_error_object(char* function, PyObject* filename)
1260{
1261 /* XXX - see win32_error for comments on 'function' */
1262 errno = GetLastError();
1263 if (filename)
1264 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001265 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001266 errno,
1267 filename);
1268 else
1269 return PyErr_SetFromWindowsErr(errno);
1270}
1271
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001272#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273
Larry Hastings9cf065c2012-06-22 16:30:09 -07001274static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001275path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001276{
1277#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001278 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1279 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001280#else
Victor Stinner292c8352012-10-30 02:17:38 +01001281 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001282#endif
1283}
1284
Larry Hastings31826802013-10-19 00:09:25 -07001285
Larry Hastingsb0827312014-02-09 22:05:19 -08001286static PyObject *
1287path_error2(path_t *path, path_t *path2)
1288{
1289#ifdef MS_WINDOWS
1290 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1291 0, path->object, path2->object);
1292#else
1293 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1294 path->object, path2->object);
1295#endif
1296}
1297
1298
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299/* POSIX generic methods */
1300
Barry Warsaw53699e91996-12-10 23:23:01 +00001301static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001302posix_fildes(PyObject *fdobj, int (*func)(int))
1303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 int fd;
1305 int res;
1306 fd = PyObject_AsFileDescriptor(fdobj);
1307 if (fd < 0)
1308 return NULL;
1309 if (!_PyVerify_fd(fd))
1310 return posix_error();
1311 Py_BEGIN_ALLOW_THREADS
1312 res = (*func)(fd);
1313 Py_END_ALLOW_THREADS
1314 if (res < 0)
1315 return posix_error();
1316 Py_INCREF(Py_None);
1317 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001318}
Guido van Rossum21142a01999-01-08 21:05:37 +00001319
1320static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001321posix_1str(const char *func_name, PyObject *args, char *format,
1322 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323{
Victor Stinner292c8352012-10-30 02:17:38 +01001324 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001325 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001326 memset(&path, 0, sizeof(path));
1327 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001328 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001329 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001332 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001333 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001334 if (res < 0) {
1335 path_error(&path);
1336 path_cleanup(&path);
1337 return NULL;
1338 }
1339 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001340 Py_INCREF(Py_None);
1341 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342}
1343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001345#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346/* This is a reimplementation of the C library's chdir function,
1347 but one that produces Win32 errors instead of DOS error codes.
1348 chdir is essentially a wrapper around SetCurrentDirectory; however,
1349 it also needs to set "magic" environment variables indicating
1350 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001351static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352win32_chdir(LPCSTR path)
1353{
Victor Stinner75875072013-11-24 19:23:25 +01001354 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 int result;
1356 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 if(!SetCurrentDirectoryA(path))
1359 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001360 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if (!result)
1362 return FALSE;
1363 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001364 than MAX_PATH-1 (not including the final null character). */
1365 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (strncmp(new_path, "\\\\", 2) == 0 ||
1367 strncmp(new_path, "//", 2) == 0)
1368 /* UNC path, nothing to do. */
1369 return TRUE;
1370 env[1] = new_path[0];
1371 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373
1374/* The Unicode version differs from the ANSI version
1375 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001376static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377win32_wchdir(LPCWSTR path)
1378{
Victor Stinner75875072013-11-24 19:23:25 +01001379 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 int result;
1381 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001382
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 if(!SetCurrentDirectoryW(path))
1384 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001385 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 if (!result)
1387 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001388 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001389 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001390 if (!new_path) {
1391 SetLastError(ERROR_OUTOFMEMORY);
1392 return FALSE;
1393 }
1394 result = GetCurrentDirectoryW(result, new_path);
1395 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001396 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001397 return FALSE;
1398 }
1399 }
1400 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1401 wcsncmp(new_path, L"//", 2) == 0)
1402 /* UNC path, nothing to do. */
1403 return TRUE;
1404 env[1] = new_path[0];
1405 result = SetEnvironmentVariableW(env, new_path);
1406 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001407 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409}
1410#endif
1411
Martin v. Löwis14694662006-02-03 12:54:16 +00001412#ifdef MS_WINDOWS
1413/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1414 - time stamps are restricted to second resolution
1415 - file modification times suffer from forth-and-back conversions between
1416 UTC and local time
1417 Therefore, we implement our own stat, based on the Win32 API directly.
1418*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001419#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001420
1421struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001422 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001423 __int64 st_ino;
1424 unsigned short st_mode;
1425 int st_nlink;
1426 int st_uid;
1427 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001428 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001429 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001430 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001431 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001432 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001433 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001434 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001435 int st_ctime_nsec;
1436};
1437
1438static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1439
1440static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001441FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001442{
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1444 /* Cannot simply cast and dereference in_ptr,
1445 since it might not be aligned properly */
1446 __int64 in;
1447 memcpy(&in, in_ptr, sizeof(in));
1448 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001449 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001450}
1451
Thomas Wouters477c8d52006-05-27 19:21:47 +00001452static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001453time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001454{
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 /* XXX endianness */
1456 __int64 out;
1457 out = time_in + secs_between_epochs;
1458 out = out * 10000000 + nsec_in / 100;
1459 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460}
1461
Martin v. Löwis14694662006-02-03 12:54:16 +00001462/* Below, we *know* that ugo+r is 0444 */
1463#if _S_IREAD != 0400
1464#error Unsupported C library
1465#endif
1466static int
1467attributes_to_mode(DWORD attr)
1468{
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 int m = 0;
1470 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1471 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1472 else
1473 m |= _S_IFREG;
1474 if (attr & FILE_ATTRIBUTE_READONLY)
1475 m |= 0444;
1476 else
1477 m |= 0666;
1478 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001479}
1480
1481static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001482attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 memset(result, 0, sizeof(*result));
1485 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1486 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001487 result->st_dev = info->dwVolumeSerialNumber;
1488 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001489 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1490 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1491 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001492 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001493 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001494 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1495 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001496 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001497 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001498 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001499 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001500
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001502}
1503
Guido van Rossumd8faa362007-04-27 19:54:29 +00001504static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001505attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001506{
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 HANDLE hFindFile;
1508 WIN32_FIND_DATAA FileData;
1509 hFindFile = FindFirstFileA(pszFile, &FileData);
1510 if (hFindFile == INVALID_HANDLE_VALUE)
1511 return FALSE;
1512 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001513 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515 info->dwFileAttributes = FileData.dwFileAttributes;
1516 info->ftCreationTime = FileData.ftCreationTime;
1517 info->ftLastAccessTime = FileData.ftLastAccessTime;
1518 info->ftLastWriteTime = FileData.ftLastWriteTime;
1519 info->nFileSizeHigh = FileData.nFileSizeHigh;
1520 info->nFileSizeLow = FileData.nFileSizeLow;
1521/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001522 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1523 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001525}
1526
1527static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001529{
Victor Stinner8c62be82010-05-06 00:08:46 +00001530 HANDLE hFindFile;
1531 WIN32_FIND_DATAW FileData;
1532 hFindFile = FindFirstFileW(pszFile, &FileData);
1533 if (hFindFile == INVALID_HANDLE_VALUE)
1534 return FALSE;
1535 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001537 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 info->dwFileAttributes = FileData.dwFileAttributes;
1539 info->ftCreationTime = FileData.ftCreationTime;
1540 info->ftLastAccessTime = FileData.ftLastAccessTime;
1541 info->ftLastWriteTime = FileData.ftLastWriteTime;
1542 info->nFileSizeHigh = FileData.nFileSizeHigh;
1543 info->nFileSizeLow = FileData.nFileSizeLow;
1544/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001545 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1546 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001548}
1549
Brian Curtind25aef52011-06-13 15:16:04 -05001550/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001551static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001552static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1553 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001554static int
Brian Curtind25aef52011-06-13 15:16:04 -05001555check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556{
Brian Curtind25aef52011-06-13 15:16:04 -05001557 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001558 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1559 DWORD);
1560
Brian Curtind25aef52011-06-13 15:16:04 -05001561 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001562 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001563 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001564 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001565 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1566 "GetFinalPathNameByHandleA");
1567 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1568 "GetFinalPathNameByHandleW");
1569 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1570 Py_GetFinalPathNameByHandleW;
1571 }
1572 return has_GetFinalPathNameByHandle;
1573}
1574
1575static BOOL
1576get_target_path(HANDLE hdl, wchar_t **target_path)
1577{
1578 int buf_size, result_length;
1579 wchar_t *buf;
1580
1581 /* We have a good handle to the target, use it to determine
1582 the target path name (then we'll call lstat on it). */
1583 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1584 VOLUME_NAME_DOS);
1585 if(!buf_size)
1586 return FALSE;
1587
Victor Stinnerb6404912013-07-07 16:21:41 +02001588 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 if (!buf) {
1590 SetLastError(ERROR_OUTOFMEMORY);
1591 return FALSE;
1592 }
1593
Brian Curtind25aef52011-06-13 15:16:04 -05001594 result_length = Py_GetFinalPathNameByHandleW(hdl,
1595 buf, buf_size, VOLUME_NAME_DOS);
1596
1597 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001598 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001599 return FALSE;
1600 }
1601
1602 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001603 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001604 return FALSE;
1605 }
1606
1607 buf[result_length] = 0;
1608
1609 *target_path = buf;
1610 return TRUE;
1611}
1612
1613static int
1614win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1615 BOOL traverse);
1616static int
1617win32_xstat_impl(const char *path, struct win32_stat *result,
1618 BOOL traverse)
1619{
Victor Stinner26de69d2011-06-17 15:15:38 +02001620 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001621 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001624 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 const char *dot;
1626
Brian Curtind25aef52011-06-13 15:16:04 -05001627 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001628 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1629 traverse reparse point. */
1630 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001631 }
1632
Brian Curtinf5e76d02010-11-24 13:14:05 +00001633 hFile = CreateFileA(
1634 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001635 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636 0, /* share mode */
1637 NULL, /* security attributes */
1638 OPEN_EXISTING,
1639 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001640 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1641 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001642 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001643 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1644 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645 NULL);
1646
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001647 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 /* Either the target doesn't exist, or we don't have access to
1649 get a handle to it. If the former, we need to return an error.
1650 If the latter, we can use attributes_from_dir. */
1651 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001652 return -1;
1653 /* Could not get attributes on open file. Fall back to
1654 reading the directory. */
1655 if (!attributes_from_dir(path, &info, &reparse_tag))
1656 /* Very strange. This should not fail now */
1657 return -1;
1658 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1659 if (traverse) {
1660 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001661 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001662 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001664 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 } else {
1666 if (!GetFileInformationByHandle(hFile, &info)) {
1667 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001668 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 }
1670 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001671 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1672 return -1;
1673
1674 /* Close the outer open file handle now that we're about to
1675 reopen it with different flags. */
1676 if (!CloseHandle(hFile))
1677 return -1;
1678
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001680 /* In order to call GetFinalPathNameByHandle we need to open
1681 the file without the reparse handling flag set. */
1682 hFile2 = CreateFileA(
1683 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1684 NULL, OPEN_EXISTING,
1685 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1686 NULL);
1687 if (hFile2 == INVALID_HANDLE_VALUE)
1688 return -1;
1689
1690 if (!get_target_path(hFile2, &target_path))
1691 return -1;
1692
1693 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001694 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 return code;
1696 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001697 } else
1698 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701
1702 /* Set S_IEXEC if it is an .exe, .bat, ... */
1703 dot = strrchr(path, '.');
1704 if (dot) {
1705 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1706 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1707 result->st_mode |= 0111;
1708 }
1709 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710}
1711
1712static int
Brian Curtind25aef52011-06-13 15:16:04 -05001713win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1714 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001715{
1716 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001717 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001720 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 const wchar_t *dot;
1722
Brian Curtind25aef52011-06-13 15:16:04 -05001723 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001724 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1725 traverse reparse point. */
1726 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 }
1728
Brian Curtinf5e76d02010-11-24 13:14:05 +00001729 hFile = CreateFileW(
1730 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001731 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732 0, /* share mode */
1733 NULL, /* security attributes */
1734 OPEN_EXISTING,
1735 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001736 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1737 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001738 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001739 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001740 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001741 NULL);
1742
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744 /* Either the target doesn't exist, or we don't have access to
1745 get a handle to it. If the former, we need to return an error.
1746 If the latter, we can use attributes_from_dir. */
1747 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001748 return -1;
1749 /* Could not get attributes on open file. Fall back to
1750 reading the directory. */
1751 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1752 /* Very strange. This should not fail now */
1753 return -1;
1754 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1755 if (traverse) {
1756 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001760 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001761 } else {
1762 if (!GetFileInformationByHandle(hFile, &info)) {
1763 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001764 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 }
1766 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001767 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1768 return -1;
1769
1770 /* Close the outer open file handle now that we're about to
1771 reopen it with different flags. */
1772 if (!CloseHandle(hFile))
1773 return -1;
1774
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001776 /* In order to call GetFinalPathNameByHandle we need to open
1777 the file without the reparse handling flag set. */
1778 hFile2 = CreateFileW(
1779 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1780 NULL, OPEN_EXISTING,
1781 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1782 NULL);
1783 if (hFile2 == INVALID_HANDLE_VALUE)
1784 return -1;
1785
1786 if (!get_target_path(hFile2, &target_path))
1787 return -1;
1788
1789 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001790 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001791 return code;
1792 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001793 } else
1794 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001795 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001796 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001797
1798 /* Set S_IEXEC if it is an .exe, .bat, ... */
1799 dot = wcsrchr(path, '.');
1800 if (dot) {
1801 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1802 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1803 result->st_mode |= 0111;
1804 }
1805 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001806}
1807
1808static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001810{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001811 /* Protocol violation: we explicitly clear errno, instead of
1812 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001813 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001814 errno = 0;
1815 return code;
1816}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001817
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818static int
1819win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1820{
1821 /* Protocol violation: we explicitly clear errno, instead of
1822 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001823 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001824 errno = 0;
1825 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001826}
Brian Curtind25aef52011-06-13 15:16:04 -05001827/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001828
1829 In Posix, stat automatically traverses symlinks and returns the stat
1830 structure for the target. In Windows, the equivalent GetFileAttributes by
1831 default does not traverse symlinks and instead returns attributes for
1832 the symlink.
1833
1834 Therefore, win32_lstat will get the attributes traditionally, and
1835 win32_stat will first explicitly resolve the symlink target and then will
1836 call win32_lstat on that result.
1837
Ezio Melotti4969f702011-03-15 05:59:46 +02001838 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001839
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001840static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001841win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001842{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001843 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001844}
1845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001847win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001848{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001849 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001850}
1851
1852static int
1853win32_stat(const char* path, struct win32_stat *result)
1854{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001855 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001856}
1857
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001858static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001859win32_stat_w(const wchar_t* path, struct win32_stat *result)
1860{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001861 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001862}
1863
1864static int
1865win32_fstat(int file_number, struct win32_stat *result)
1866{
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 BY_HANDLE_FILE_INFORMATION info;
1868 HANDLE h;
1869 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001870
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001871 if (!_PyVerify_fd(file_number))
1872 h = INVALID_HANDLE_VALUE;
1873 else
1874 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001875
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 /* Protocol violation: we explicitly clear errno, instead of
1877 setting it to a POSIX error. Callers should use GetLastError. */
1878 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001879
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 if (h == INVALID_HANDLE_VALUE) {
1881 /* This is really a C library error (invalid file handle).
1882 We set the Win32 error to the closes one matching. */
1883 SetLastError(ERROR_INVALID_HANDLE);
1884 return -1;
1885 }
1886 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001887
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 type = GetFileType(h);
1889 if (type == FILE_TYPE_UNKNOWN) {
1890 DWORD error = GetLastError();
1891 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001892 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 }
1894 /* else: valid but unknown file */
1895 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 if (type != FILE_TYPE_DISK) {
1898 if (type == FILE_TYPE_CHAR)
1899 result->st_mode = _S_IFCHR;
1900 else if (type == FILE_TYPE_PIPE)
1901 result->st_mode = _S_IFIFO;
1902 return 0;
1903 }
1904
1905 if (!GetFileInformationByHandle(h, &info)) {
1906 return -1;
1907 }
1908
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001909 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1912 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001913}
1914
1915#endif /* MS_WINDOWS */
1916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001917PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001918"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001919This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001920 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1922\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001923Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1924or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001926See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927
1928static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 {"st_mode", "protection bits"},
1930 {"st_ino", "inode"},
1931 {"st_dev", "device"},
1932 {"st_nlink", "number of hard links"},
1933 {"st_uid", "user ID of owner"},
1934 {"st_gid", "group ID of owner"},
1935 {"st_size", "total size, in bytes"},
1936 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1937 {NULL, "integer time of last access"},
1938 {NULL, "integer time of last modification"},
1939 {NULL, "integer time of last change"},
1940 {"st_atime", "time of last access"},
1941 {"st_mtime", "time of last modification"},
1942 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001943 {"st_atime_ns", "time of last access in nanoseconds"},
1944 {"st_mtime_ns", "time of last modification in nanoseconds"},
1945 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001946#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001949#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001951#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001952#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001954#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001955#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001957#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001958#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001960#endif
1961#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001963#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965};
1966
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001967#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001968#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001970#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001971#endif
1972
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1975#else
1976#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1977#endif
1978
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1981#else
1982#define ST_RDEV_IDX ST_BLOCKS_IDX
1983#endif
1984
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001985#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1986#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1987#else
1988#define ST_FLAGS_IDX ST_RDEV_IDX
1989#endif
1990
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001991#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001992#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001993#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001994#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001995#endif
1996
1997#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1998#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1999#else
2000#define ST_BIRTHTIME_IDX ST_GEN_IDX
2001#endif
2002
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002004 "stat_result", /* name */
2005 stat_result__doc__, /* doc */
2006 stat_result_fields,
2007 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002008};
2009
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002010PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002011"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2012This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002013 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002014or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002017
2018static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 {"f_bsize", },
2020 {"f_frsize", },
2021 {"f_blocks", },
2022 {"f_bfree", },
2023 {"f_bavail", },
2024 {"f_files", },
2025 {"f_ffree", },
2026 {"f_favail", },
2027 {"f_flag", },
2028 {"f_namemax",},
2029 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030};
2031
2032static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 "statvfs_result", /* name */
2034 statvfs_result__doc__, /* doc */
2035 statvfs_result_fields,
2036 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002037};
2038
Ross Lagerwall7807c352011-03-17 20:20:30 +02002039#if defined(HAVE_WAITID) && !defined(__APPLE__)
2040PyDoc_STRVAR(waitid_result__doc__,
2041"waitid_result: Result from waitid.\n\n\
2042This object may be accessed either as a tuple of\n\
2043 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2044or via the attributes si_pid, si_uid, and so on.\n\
2045\n\
2046See os.waitid for more information.");
2047
2048static PyStructSequence_Field waitid_result_fields[] = {
2049 {"si_pid", },
2050 {"si_uid", },
2051 {"si_signo", },
2052 {"si_status", },
2053 {"si_code", },
2054 {0}
2055};
2056
2057static PyStructSequence_Desc waitid_result_desc = {
2058 "waitid_result", /* name */
2059 waitid_result__doc__, /* doc */
2060 waitid_result_fields,
2061 5
2062};
2063static PyTypeObject WaitidResultType;
2064#endif
2065
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002066static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002067static PyTypeObject StatResultType;
2068static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002069#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002070static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002071#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002072static newfunc structseq_new;
2073
2074static PyObject *
2075statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2076{
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 PyStructSequence *result;
2078 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002079
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 result = (PyStructSequence*)structseq_new(type, args, kwds);
2081 if (!result)
2082 return NULL;
2083 /* If we have been initialized from a tuple,
2084 st_?time might be set to None. Initialize it
2085 from the int slots. */
2086 for (i = 7; i <= 9; i++) {
2087 if (result->ob_item[i+3] == Py_None) {
2088 Py_DECREF(Py_None);
2089 Py_INCREF(result->ob_item[i]);
2090 result->ob_item[i+3] = result->ob_item[i];
2091 }
2092 }
2093 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002094}
2095
2096
2097
2098/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002099static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002100
2101PyDoc_STRVAR(stat_float_times__doc__,
2102"stat_float_times([newval]) -> oldval\n\n\
2103Determine whether os.[lf]stat represents time stamps as float objects.\n\
2104If newval is True, future calls to stat() return floats, if it is False,\n\
2105future calls return ints. \n\
2106If newval is omitted, return the current setting.\n");
2107
2108static PyObject*
2109stat_float_times(PyObject* self, PyObject *args)
2110{
Victor Stinner8c62be82010-05-06 00:08:46 +00002111 int newval = -1;
2112 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2113 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002114 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2115 "stat_float_times() is deprecated",
2116 1))
2117 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 if (newval == -1)
2119 /* Return old value */
2120 return PyBool_FromLong(_stat_float_times);
2121 _stat_float_times = newval;
2122 Py_INCREF(Py_None);
2123 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002124}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125
Larry Hastings6fe20b32012-04-19 15:07:49 -07002126static PyObject *billion = NULL;
2127
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002128static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002129fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002130{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002131 PyObject *s = _PyLong_FromTime_t(sec);
2132 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2133 PyObject *s_in_ns = NULL;
2134 PyObject *ns_total = NULL;
2135 PyObject *float_s = NULL;
2136
2137 if (!(s && ns_fractional))
2138 goto exit;
2139
2140 s_in_ns = PyNumber_Multiply(s, billion);
2141 if (!s_in_ns)
2142 goto exit;
2143
2144 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2145 if (!ns_total)
2146 goto exit;
2147
Victor Stinner4195b5c2012-02-08 23:03:19 +01002148 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002149 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2150 if (!float_s)
2151 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002152 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002153 else {
2154 float_s = s;
2155 Py_INCREF(float_s);
2156 }
2157
2158 PyStructSequence_SET_ITEM(v, index, s);
2159 PyStructSequence_SET_ITEM(v, index+3, float_s);
2160 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2161 s = NULL;
2162 float_s = NULL;
2163 ns_total = NULL;
2164exit:
2165 Py_XDECREF(s);
2166 Py_XDECREF(ns_fractional);
2167 Py_XDECREF(s_in_ns);
2168 Py_XDECREF(ns_total);
2169 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002170}
2171
Tim Peters5aa91602002-01-30 05:46:57 +00002172/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002173 (used by posix_stat() and posix_fstat()) */
2174static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002175_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002176{
Victor Stinner8c62be82010-05-06 00:08:46 +00002177 unsigned long ansec, mnsec, cnsec;
2178 PyObject *v = PyStructSequence_New(&StatResultType);
2179 if (v == NULL)
2180 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002181
Victor Stinner8c62be82010-05-06 00:08:46 +00002182 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002183#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002184 PyStructSequence_SET_ITEM(v, 1,
2185 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002186#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002188#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002189#ifdef MS_WINDOWS
2190 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2191#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002192 PyStructSequence_SET_ITEM(v, 2,
2193 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002194#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002195 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002196#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002198#if defined(MS_WINDOWS)
2199 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2200 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2201#else
2202 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2203 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2204#endif
Fred Drake699f3522000-06-29 21:12:41 +00002205#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 PyStructSequence_SET_ITEM(v, 6,
2207 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002208#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002210#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002211
Martin v. Löwis14694662006-02-03 12:54:16 +00002212#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002213 ansec = st->st_atim.tv_nsec;
2214 mnsec = st->st_mtim.tv_nsec;
2215 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002216#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002217 ansec = st->st_atimespec.tv_nsec;
2218 mnsec = st->st_mtimespec.tv_nsec;
2219 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002220#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002221 ansec = st->st_atime_nsec;
2222 mnsec = st->st_mtime_nsec;
2223 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002224#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002225 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002226#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002227 fill_time(v, 7, st->st_atime, ansec);
2228 fill_time(v, 8, st->st_mtime, mnsec);
2229 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002230
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002231#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002232 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2233 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002234#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002235#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2237 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002238#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002239#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2241 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002242#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002243#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2245 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002246#endif
2247#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002249 PyObject *val;
2250 unsigned long bsec,bnsec;
2251 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002252#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002253 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002254#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002255 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002256#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002257 if (_stat_float_times) {
2258 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2259 } else {
2260 val = PyLong_FromLong((long)bsec);
2261 }
2262 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2263 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002264 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002265#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002266#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2268 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002269#endif
Fred Drake699f3522000-06-29 21:12:41 +00002270
Victor Stinner8c62be82010-05-06 00:08:46 +00002271 if (PyErr_Occurred()) {
2272 Py_DECREF(v);
2273 return NULL;
2274 }
Fred Drake699f3522000-06-29 21:12:41 +00002275
Victor Stinner8c62be82010-05-06 00:08:46 +00002276 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002277}
2278
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002279/* POSIX methods */
2280
Guido van Rossum94f6f721999-01-06 18:42:14 +00002281
2282static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002283posix_do_stat(char *function_name, path_t *path,
2284 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002285{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002286 STRUCT_STAT st;
2287 int result;
2288
2289#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2290 if (follow_symlinks_specified(function_name, follow_symlinks))
2291 return NULL;
2292#endif
2293
2294 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2295 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2296 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2297 return NULL;
2298
2299 Py_BEGIN_ALLOW_THREADS
2300 if (path->fd != -1)
2301 result = FSTAT(path->fd, &st);
2302 else
2303#ifdef MS_WINDOWS
2304 if (path->wide) {
2305 if (follow_symlinks)
2306 result = win32_stat_w(path->wide, &st);
2307 else
2308 result = win32_lstat_w(path->wide, &st);
2309 }
2310 else
2311#endif
2312#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2313 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2314 result = LSTAT(path->narrow, &st);
2315 else
2316#endif
2317#ifdef HAVE_FSTATAT
2318 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2319 result = fstatat(dir_fd, path->narrow, &st,
2320 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2321 else
2322#endif
2323 result = STAT(path->narrow, &st);
2324 Py_END_ALLOW_THREADS
2325
Victor Stinner292c8352012-10-30 02:17:38 +01002326 if (result != 0) {
2327 return path_error(path);
2328 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002329
2330 return _pystat_fromstructstat(&st);
2331}
2332
Larry Hastings31826802013-10-19 00:09:25 -07002333#ifdef HAVE_FSTATAT
2334 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2335#else
2336 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2337#endif
2338
2339
Larry Hastings61272b72014-01-07 12:41:53 -08002340/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002341
2342class path_t_converter(CConverter):
2343
2344 type = "path_t"
2345 impl_by_reference = True
2346 parse_by_reference = True
2347
2348 converter = 'path_converter'
2349
2350 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002351 # right now path_t doesn't support default values.
2352 # to support a default value, you'll need to override initialize().
Larry Hastings7726ac92014-01-31 22:03:12 -08002353 if self.default is not unspecified:
2354 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002355
Larry Hastings7726ac92014-01-31 22:03:12 -08002356 if self.c_default is not None:
2357 fail("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002358
2359 self.nullable = nullable
2360 self.allow_fd = allow_fd
2361
Larry Hastings7726ac92014-01-31 22:03:12 -08002362 def pre_render(self):
2363 def strify(value):
2364 return str(int(bool(value)))
2365
2366 # add self.py_name here when merging with posixmodule conversion
Larry Hastings31826802013-10-19 00:09:25 -07002367 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2368 self.function.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002369 strify(self.nullable),
2370 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002371 )
2372
2373 def cleanup(self):
2374 return "path_cleanup(&" + self.name + ");\n"
2375
2376
2377class dir_fd_converter(CConverter):
2378 type = 'int'
2379 converter = 'OS_STAT_DIR_FD_CONVERTER'
2380
2381 def converter_init(self):
2382 if self.default in (unspecified, None):
2383 self.c_default = 'DEFAULT_DIR_FD'
2384
2385
Larry Hastings61272b72014-01-07 12:41:53 -08002386[python start generated code]*/
Larry Hastings7726ac92014-01-31 22:03:12 -08002387/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002388
Larry Hastings61272b72014-01-07 12:41:53 -08002389/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002390
Larry Hastings2a727912014-01-16 11:32:01 -08002391os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002392
2393 path : path_t(allow_fd=True)
2394 Path to be examined; can be string, bytes, or open-file-descriptor int.
2395
2396 *
2397
2398 dir_fd : dir_fd = None
2399 If not None, it should be a file descriptor open to a directory,
2400 and path should be a relative string; path will then be relative to
2401 that directory.
2402
2403 follow_symlinks: bool = True
2404 If False, and the last element of the path is a symbolic link,
2405 stat will examine the symbolic link itself instead of the file
2406 the link points to.
2407
2408Perform a stat system call on the given path.
2409
2410dir_fd and follow_symlinks may not be implemented
2411 on your platform. If they are unavailable, using them will raise a
2412 NotImplementedError.
2413
2414It's an error to use dir_fd or follow_symlinks when specifying path as
2415 an open file descriptor.
2416
Larry Hastings61272b72014-01-07 12:41:53 -08002417[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002418
2419PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002420"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2421"--\n"
2422"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002423"Perform a stat system call on the given path.\n"
2424"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002425" path\n"
2426" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2427" dir_fd\n"
2428" If not None, it should be a file descriptor open to a directory,\n"
2429" and path should be a relative string; path will then be relative to\n"
2430" that directory.\n"
2431" follow_symlinks\n"
2432" If False, and the last element of the path is a symbolic link,\n"
2433" stat will examine the symbolic link itself instead of the file\n"
2434" the link points to.\n"
2435"\n"
2436"dir_fd and follow_symlinks may not be implemented\n"
2437" on your platform. If they are unavailable, using them will raise a\n"
2438" NotImplementedError.\n"
2439"\n"
2440"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2441" an open file descriptor.");
2442
2443#define OS_STAT_METHODDEF \
2444 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002445
2446static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002447os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002448
2449static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002450os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002451{
Larry Hastings31826802013-10-19 00:09:25 -07002452 PyObject *return_value = NULL;
2453 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2454 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002455 int dir_fd = DEFAULT_DIR_FD;
2456 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002457
Larry Hastings31826802013-10-19 00:09:25 -07002458 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2459 "O&|$O&p:stat", _keywords,
2460 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2461 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002462 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002463
2464exit:
2465 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002466 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002467
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468 return return_value;
2469}
2470
Larry Hastings31826802013-10-19 00:09:25 -07002471static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002472os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002473/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474{
2475 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2476}
2477
Larry Hastings9cf065c2012-06-22 16:30:09 -07002478PyDoc_STRVAR(posix_lstat__doc__,
2479"lstat(path, *, dir_fd=None) -> stat result\n\n\
2480Like stat(), but do not follow symbolic links.\n\
2481Equivalent to stat(path, follow_symlinks=False).");
2482
2483static PyObject *
2484posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2485{
2486 static char *keywords[] = {"path", "dir_fd", NULL};
2487 path_t path;
2488 int dir_fd = DEFAULT_DIR_FD;
2489 int follow_symlinks = 0;
2490 PyObject *return_value;
2491
2492 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002493 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2495 path_converter, &path,
2496#ifdef HAVE_FSTATAT
2497 dir_fd_converter, &dir_fd
2498#else
2499 dir_fd_unavailable, &dir_fd
2500#endif
2501 ))
2502 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002503 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002504 path_cleanup(&path);
2505 return return_value;
2506}
2507
Larry Hastings31826802013-10-19 00:09:25 -07002508
2509#ifdef HAVE_FACCESSAT
2510 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2511#else
2512 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2513#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002514/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002515os.access
Larry Hastings31826802013-10-19 00:09:25 -07002516
2517 path: path_t(allow_fd=True)
2518 Path to be tested; can be string, bytes, or open-file-descriptor int.
2519
2520 mode: int
2521 Operating-system mode bitfield. Can be F_OK to test existence,
2522 or the inclusive-OR of R_OK, W_OK, and X_OK.
2523
2524 *
2525
2526 dir_fd : dir_fd = None
2527 If not None, it should be a file descriptor open to a directory,
2528 and path should be relative; path will then be relative to that
2529 directory.
2530
2531 effective_ids: bool = False
2532 If True, access will use the effective uid/gid instead of
2533 the real uid/gid.
2534
2535 follow_symlinks: bool = True
2536 If False, and the last element of the path is a symbolic link,
2537 access will examine the symbolic link itself instead of the file
2538 the link points to.
2539
2540Use the real uid/gid to test for access to a path.
2541
2542{parameters}
2543dir_fd, effective_ids, and follow_symlinks may not be implemented
2544 on your platform. If they are unavailable, using them will raise a
2545 NotImplementedError.
2546
2547Note that most operations will use the effective uid/gid, therefore this
2548 routine can be used in a suid/sgid environment to test if the invoking user
2549 has the specified access to the path.
2550
Larry Hastings61272b72014-01-07 12:41:53 -08002551[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002552
2553PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002554"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2555" follow_symlinks=True)\n"
2556"--\n"
2557"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002558"Use the real uid/gid to test for access to a path.\n"
2559"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002560" path\n"
2561" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2562" mode\n"
2563" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2564" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2565" dir_fd\n"
2566" If not None, it should be a file descriptor open to a directory,\n"
2567" and path should be relative; path will then be relative to that\n"
2568" directory.\n"
2569" effective_ids\n"
2570" If True, access will use the effective uid/gid instead of\n"
2571" the real uid/gid.\n"
2572" follow_symlinks\n"
2573" If False, and the last element of the path is a symbolic link,\n"
2574" access will examine the symbolic link itself instead of the file\n"
2575" the link points to.\n"
2576"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002577"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2578" on your platform. If they are unavailable, using them will raise a\n"
2579" NotImplementedError.\n"
2580"\n"
2581"Note that most operations will use the effective uid/gid, therefore this\n"
2582" routine can be used in a suid/sgid environment to test if the invoking user\n"
2583" has the specified access to the path.");
2584
2585#define OS_ACCESS_METHODDEF \
2586 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587
2588static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002589os_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 -07002590
2591static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002592os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593{
Larry Hastings31826802013-10-19 00:09:25 -07002594 PyObject *return_value = NULL;
2595 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2596 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002598 int dir_fd = DEFAULT_DIR_FD;
2599 int effective_ids = 0;
2600 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002601
2602 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2603 "O&i|$O&pp:access", _keywords,
2604 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2605 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002606 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002607
2608exit:
2609 /* Cleanup for path */
2610 path_cleanup(&path);
2611
2612 return return_value;
2613}
2614
2615static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002616os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002617/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
Larry Hastings31826802013-10-19 00:09:25 -07002618{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002620
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002621#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002623#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002625#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627#ifndef HAVE_FACCESSAT
2628 if (follow_symlinks_specified("access", follow_symlinks))
2629 goto exit;
2630
2631 if (effective_ids) {
2632 argument_unavailable_error("access", "effective_ids");
2633 goto exit;
2634 }
2635#endif
2636
2637#ifdef MS_WINDOWS
2638 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002639 if (path->wide != NULL)
2640 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002642 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643 Py_END_ALLOW_THREADS
2644
2645 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002646 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647 * * we didn't get a -1, and
2648 * * write access wasn't requested,
2649 * * or the file isn't read-only,
2650 * * or it's a directory.
2651 * (Directories cannot be read-only on Windows.)
2652 */
2653 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002654 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002655 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656 !(attr & FILE_ATTRIBUTE_READONLY) ||
2657 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2658#else
2659
2660 Py_BEGIN_ALLOW_THREADS
2661#ifdef HAVE_FACCESSAT
2662 if ((dir_fd != DEFAULT_DIR_FD) ||
2663 effective_ids ||
2664 !follow_symlinks) {
2665 int flags = 0;
2666 if (!follow_symlinks)
2667 flags |= AT_SYMLINK_NOFOLLOW;
2668 if (effective_ids)
2669 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002670 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 }
2672 else
2673#endif
Larry Hastings31826802013-10-19 00:09:25 -07002674 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002675 Py_END_ALLOW_THREADS
2676 return_value = PyBool_FromLong(!result);
2677#endif
2678
2679#ifndef HAVE_FACCESSAT
2680exit:
2681#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002682 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002683}
2684
Guido van Rossumd371ff11999-01-25 16:12:23 +00002685#ifndef F_OK
2686#define F_OK 0
2687#endif
2688#ifndef R_OK
2689#define R_OK 4
2690#endif
2691#ifndef W_OK
2692#define W_OK 2
2693#endif
2694#ifndef X_OK
2695#define X_OK 1
2696#endif
2697
Larry Hastings31826802013-10-19 00:09:25 -07002698
Guido van Rossumd371ff11999-01-25 16:12:23 +00002699#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002700
Larry Hastings61272b72014-01-07 12:41:53 -08002701/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002702os.ttyname -> DecodeFSDefault
2703
2704 fd: int
2705 Integer file descriptor handle.
2706
2707 /
2708
2709Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002710[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002711
2712PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002713"ttyname($module, fd, /)\n"
2714"--\n"
2715"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002716"Return the name of the terminal device connected to \'fd\'.\n"
2717"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002718" fd\n"
2719" Integer file descriptor handle.");
2720
2721#define OS_TTYNAME_METHODDEF \
2722 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2723
2724static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002725os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002726
2727static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002728os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002729{
Larry Hastings31826802013-10-19 00:09:25 -07002730 PyObject *return_value = NULL;
2731 int fd;
2732 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002733
Larry Hastings31826802013-10-19 00:09:25 -07002734 if (!PyArg_ParseTuple(args,
2735 "i:ttyname",
2736 &fd))
2737 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002738 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002739 if (_return_value == NULL)
2740 goto exit;
2741 return_value = PyUnicode_DecodeFSDefault(_return_value);
2742
2743exit:
2744 return return_value;
2745}
2746
2747static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002748os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002749/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002750{
2751 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002752
Larry Hastings31826802013-10-19 00:09:25 -07002753 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002754 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002755 posix_error();
2756 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002757}
Larry Hastings31826802013-10-19 00:09:25 -07002758#else
2759#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002760#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002761
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002762#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002763PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002764"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002765Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002766
2767static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002768posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002769{
Victor Stinner8c62be82010-05-06 00:08:46 +00002770 char *ret;
2771 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002772
Greg Wardb48bc172000-03-01 21:51:56 +00002773#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002774 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002775#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002777#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002778 if (ret == NULL)
2779 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002780 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002781}
2782#endif
2783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002784PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002785"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786Change the current working directory to the specified path.\n\
2787\n\
2788path may always be specified as a string.\n\
2789On some platforms, path may also be specified as an open file descriptor.\n\
2790 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002791
Barry Warsaw53699e91996-12-10 23:23:01 +00002792static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002794{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 path_t path;
2796 int result;
2797 PyObject *return_value = NULL;
2798 static char *keywords[] = {"path", NULL};
2799
2800 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002801 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#ifdef HAVE_FCHDIR
2803 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002804#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2806 path_converter, &path
2807 ))
2808 return NULL;
2809
2810 Py_BEGIN_ALLOW_THREADS
2811#ifdef MS_WINDOWS
2812 if (path.wide)
2813 result = win32_wchdir(path.wide);
2814 else
2815 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002816 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817#else
2818#ifdef HAVE_FCHDIR
2819 if (path.fd != -1)
2820 result = fchdir(path.fd);
2821 else
2822#endif
2823 result = chdir(path.narrow);
2824#endif
2825 Py_END_ALLOW_THREADS
2826
2827 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002828 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 goto exit;
2830 }
2831
2832 return_value = Py_None;
2833 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002834
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835exit:
2836 path_cleanup(&path);
2837 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002838}
2839
Fred Drake4d1e64b2002-04-15 19:40:07 +00002840#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002841PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842"fchdir(fd)\n\n\
2843Change to the directory of the given file descriptor. fd must be\n\
2844opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002845
2846static PyObject *
2847posix_fchdir(PyObject *self, PyObject *fdobj)
2848{
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002850}
2851#endif /* HAVE_FCHDIR */
2852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2856Change the access permissions of a file.\n\
2857\n\
2858path may always be specified as a string.\n\
2859On some platforms, path may also be specified as an open file descriptor.\n\
2860 If this functionality is unavailable, using it raises an exception.\n\
2861If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2862 and path should be relative; path will then be relative to that directory.\n\
2863If follow_symlinks is False, and the last element of the path is a symbolic\n\
2864 link, chmod will modify the symbolic link itself instead of the file the\n\
2865 link points to.\n\
2866It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2867 an open file descriptor.\n\
2868dir_fd and follow_symlinks may not be implemented on your platform.\n\
2869 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Barry Warsaw53699e91996-12-10 23:23:01 +00002871static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002873{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874 path_t path;
2875 int mode;
2876 int dir_fd = DEFAULT_DIR_FD;
2877 int follow_symlinks = 1;
2878 int result;
2879 PyObject *return_value = NULL;
2880 static char *keywords[] = {"path", "mode", "dir_fd",
2881 "follow_symlinks", NULL};
2882
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002883#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002884 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002886
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887#ifdef HAVE_FCHMODAT
2888 int fchmodat_nofollow_unsupported = 0;
2889#endif
2890
2891 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002892 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893#ifdef HAVE_FCHMOD
2894 path.allow_fd = 1;
2895#endif
2896 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2897 path_converter, &path,
2898 &mode,
2899#ifdef HAVE_FCHMODAT
2900 dir_fd_converter, &dir_fd,
2901#else
2902 dir_fd_unavailable, &dir_fd,
2903#endif
2904 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906
2907#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2908 if (follow_symlinks_specified("chmod", follow_symlinks))
2909 goto exit;
2910#endif
2911
2912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002913 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002914 if (path.wide)
2915 attr = GetFileAttributesW(path.wide);
2916 else
2917 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002918 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002919 result = 0;
2920 else {
2921 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 attr &= ~FILE_ATTRIBUTE_READONLY;
2923 else
2924 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002925 if (path.wide)
2926 result = SetFileAttributesW(path.wide, attr);
2927 else
2928 result = SetFileAttributesA(path.narrow, attr);
2929 }
2930 Py_END_ALLOW_THREADS
2931
2932 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002933 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002934 goto exit;
2935 }
2936#else /* MS_WINDOWS */
2937 Py_BEGIN_ALLOW_THREADS
2938#ifdef HAVE_FCHMOD
2939 if (path.fd != -1)
2940 result = fchmod(path.fd, mode);
2941 else
2942#endif
2943#ifdef HAVE_LCHMOD
2944 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2945 result = lchmod(path.narrow, mode);
2946 else
2947#endif
2948#ifdef HAVE_FCHMODAT
2949 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2950 /*
2951 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2952 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002953 * and then says it isn't implemented yet.
2954 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002955 *
2956 * Once it is supported, os.chmod will automatically
2957 * support dir_fd and follow_symlinks=False. (Hopefully.)
2958 * Until then, we need to be careful what exception we raise.
2959 */
2960 result = fchmodat(dir_fd, path.narrow, mode,
2961 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2962 /*
2963 * But wait! We can't throw the exception without allowing threads,
2964 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2965 */
2966 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002967 result &&
2968 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2969 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 }
2971 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002972#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002973 result = chmod(path.narrow, mode);
2974 Py_END_ALLOW_THREADS
2975
2976 if (result) {
2977#ifdef HAVE_FCHMODAT
2978 if (fchmodat_nofollow_unsupported) {
2979 if (dir_fd != DEFAULT_DIR_FD)
2980 dir_fd_and_follow_symlinks_invalid("chmod",
2981 dir_fd, follow_symlinks);
2982 else
2983 follow_symlinks_specified("chmod", follow_symlinks);
2984 }
2985 else
2986#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002987 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002988 goto exit;
2989 }
2990#endif
2991
2992 Py_INCREF(Py_None);
2993 return_value = Py_None;
2994exit:
2995 path_cleanup(&path);
2996 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002997}
2998
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999
Christian Heimes4e30a842007-11-30 22:12:06 +00003000#ifdef HAVE_FCHMOD
3001PyDoc_STRVAR(posix_fchmod__doc__,
3002"fchmod(fd, mode)\n\n\
3003Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003004descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003005
3006static PyObject *
3007posix_fchmod(PyObject *self, PyObject *args)
3008{
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 int fd, mode, res;
3010 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3011 return NULL;
3012 Py_BEGIN_ALLOW_THREADS
3013 res = fchmod(fd, mode);
3014 Py_END_ALLOW_THREADS
3015 if (res < 0)
3016 return posix_error();
3017 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003018}
3019#endif /* HAVE_FCHMOD */
3020
3021#ifdef HAVE_LCHMOD
3022PyDoc_STRVAR(posix_lchmod__doc__,
3023"lchmod(path, mode)\n\n\
3024Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003025affects the link itself rather than the target.\n\
3026Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003027
3028static PyObject *
3029posix_lchmod(PyObject *self, PyObject *args)
3030{
Victor Stinner292c8352012-10-30 02:17:38 +01003031 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 int i;
3033 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003034 memset(&path, 0, sizeof(path));
3035 path.function_name = "lchmod";
3036 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3037 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003040 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003041 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003042 if (res < 0) {
3043 path_error(&path);
3044 path_cleanup(&path);
3045 return NULL;
3046 }
3047 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003049}
3050#endif /* HAVE_LCHMOD */
3051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003052
Thomas Wouterscf297e42007-02-23 15:07:44 +00003053#ifdef HAVE_CHFLAGS
3054PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003055"chflags(path, flags, *, follow_symlinks=True)\n\n\
3056Set file flags.\n\
3057\n\
3058If follow_symlinks is False, and the last element of the path is a symbolic\n\
3059 link, chflags will change flags on the symbolic link itself instead of the\n\
3060 file the link points to.\n\
3061follow_symlinks may not be implemented on your platform. If it is\n\
3062unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003063
3064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003067 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003068 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069 int follow_symlinks = 1;
3070 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003071 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3073
3074 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003075 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3077 path_converter, &path,
3078 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080
3081#ifndef HAVE_LCHFLAGS
3082 if (follow_symlinks_specified("chflags", follow_symlinks))
3083 goto exit;
3084#endif
3085
Victor Stinner8c62be82010-05-06 00:08:46 +00003086 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087#ifdef HAVE_LCHFLAGS
3088 if (!follow_symlinks)
3089 result = lchflags(path.narrow, flags);
3090 else
3091#endif
3092 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003094
3095 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003096 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097 goto exit;
3098 }
3099
3100 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003101 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003102
3103exit:
3104 path_cleanup(&path);
3105 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003106}
3107#endif /* HAVE_CHFLAGS */
3108
3109#ifdef HAVE_LCHFLAGS
3110PyDoc_STRVAR(posix_lchflags__doc__,
3111"lchflags(path, flags)\n\n\
3112Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113This function will not follow symbolic links.\n\
3114Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003115
3116static PyObject *
3117posix_lchflags(PyObject *self, PyObject *args)
3118{
Victor Stinner292c8352012-10-30 02:17:38 +01003119 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003120 unsigned long flags;
3121 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003122 memset(&path, 0, sizeof(path));
3123 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003125 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003127 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003128 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003129 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003130 if (res < 0) {
3131 path_error(&path);
3132 path_cleanup(&path);
3133 return NULL;
3134 }
3135 path_cleanup(&path);
3136 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003137}
3138#endif /* HAVE_LCHFLAGS */
3139
Martin v. Löwis244edc82001-10-04 22:44:26 +00003140#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003142"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003143Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003144
3145static PyObject *
3146posix_chroot(PyObject *self, PyObject *args)
3147{
Victor Stinner292c8352012-10-30 02:17:38 +01003148 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003149}
3150#endif
3151
Guido van Rossum21142a01999-01-08 21:05:37 +00003152#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003153PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003154"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003155force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003156
3157static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003158posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003159{
Stefan Krah0e803b32010-11-26 16:16:47 +00003160 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003161}
3162#endif /* HAVE_FSYNC */
3163
Ross Lagerwall7807c352011-03-17 20:20:30 +02003164#ifdef HAVE_SYNC
3165PyDoc_STRVAR(posix_sync__doc__,
3166"sync()\n\n\
3167Force write of everything to disk.");
3168
3169static PyObject *
3170posix_sync(PyObject *self, PyObject *noargs)
3171{
3172 Py_BEGIN_ALLOW_THREADS
3173 sync();
3174 Py_END_ALLOW_THREADS
3175 Py_RETURN_NONE;
3176}
3177#endif
3178
Guido van Rossum21142a01999-01-08 21:05:37 +00003179#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003180
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003181#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003182extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3183#endif
3184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003186"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003187force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003188 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003189
3190static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003191posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003192{
Stefan Krah0e803b32010-11-26 16:16:47 +00003193 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003194}
3195#endif /* HAVE_FDATASYNC */
3196
3197
Fredrik Lundh10723342000-07-10 16:38:09 +00003198#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003199PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3201Change the owner and group id of path to the numeric uid and gid.\n\
3202\n\
3203path may always be specified as a string.\n\
3204On some platforms, path may also be specified as an open file descriptor.\n\
3205 If this functionality is unavailable, using it raises an exception.\n\
3206If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3207 and path should be relative; path will then be relative to that directory.\n\
3208If follow_symlinks is False, and the last element of the path is a symbolic\n\
3209 link, chown will modify the symbolic link itself instead of the file the\n\
3210 link points to.\n\
3211It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3212 an open file descriptor.\n\
3213dir_fd and follow_symlinks may not be implemented on your platform.\n\
3214 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003215
Barry Warsaw53699e91996-12-10 23:23:01 +00003216static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220 uid_t uid;
3221 gid_t gid;
3222 int dir_fd = DEFAULT_DIR_FD;
3223 int follow_symlinks = 1;
3224 int result;
3225 PyObject *return_value = NULL;
3226 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3227 "follow_symlinks", NULL};
3228
3229 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003230 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231#ifdef HAVE_FCHOWN
3232 path.allow_fd = 1;
3233#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003234 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003236 _Py_Uid_Converter, &uid,
3237 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238#ifdef HAVE_FCHOWNAT
3239 dir_fd_converter, &dir_fd,
3240#else
3241 dir_fd_unavailable, &dir_fd,
3242#endif
3243 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003244 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245
3246#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3247 if (follow_symlinks_specified("chown", follow_symlinks))
3248 goto exit;
3249#endif
3250 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3251 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3252 goto exit;
3253
3254#ifdef __APPLE__
3255 /*
3256 * This is for Mac OS X 10.3, which doesn't have lchown.
3257 * (But we still have an lchown symbol because of weak-linking.)
3258 * It doesn't have fchownat either. So there's no possibility
3259 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003260 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261 if ((!follow_symlinks) && (lchown == NULL)) {
3262 follow_symlinks_specified("chown", follow_symlinks);
3263 goto exit;
3264 }
3265#endif
3266
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268#ifdef HAVE_FCHOWN
3269 if (path.fd != -1)
3270 result = fchown(path.fd, uid, gid);
3271 else
3272#endif
3273#ifdef HAVE_LCHOWN
3274 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3275 result = lchown(path.narrow, uid, gid);
3276 else
3277#endif
3278#ifdef HAVE_FCHOWNAT
3279 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3280 result = fchownat(dir_fd, path.narrow, uid, gid,
3281 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3282 else
3283#endif
3284 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286
3287 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003288 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003289 goto exit;
3290 }
3291
3292 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003294
3295exit:
3296 path_cleanup(&path);
3297 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003298}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003299#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003300
Christian Heimes4e30a842007-11-30 22:12:06 +00003301#ifdef HAVE_FCHOWN
3302PyDoc_STRVAR(posix_fchown__doc__,
3303"fchown(fd, uid, gid)\n\n\
3304Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003305fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003306
3307static PyObject *
3308posix_fchown(PyObject *self, PyObject *args)
3309{
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003311 uid_t uid;
3312 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003314 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3315 _Py_Uid_Converter, &uid,
3316 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 return NULL;
3318 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003319 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 Py_END_ALLOW_THREADS
3321 if (res < 0)
3322 return posix_error();
3323 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003324}
3325#endif /* HAVE_FCHOWN */
3326
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003327#ifdef HAVE_LCHOWN
3328PyDoc_STRVAR(posix_lchown__doc__,
3329"lchown(path, uid, gid)\n\n\
3330Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331This function will not follow symbolic links.\n\
3332Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003333
3334static PyObject *
3335posix_lchown(PyObject *self, PyObject *args)
3336{
Victor Stinner292c8352012-10-30 02:17:38 +01003337 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003338 uid_t uid;
3339 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003341 memset(&path, 0, sizeof(path));
3342 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003343 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003344 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003345 _Py_Uid_Converter, &uid,
3346 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003349 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003351 if (res < 0) {
3352 path_error(&path);
3353 path_cleanup(&path);
3354 return NULL;
3355 }
3356 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003357 Py_INCREF(Py_None);
3358 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003359}
3360#endif /* HAVE_LCHOWN */
3361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003362
Barry Warsaw53699e91996-12-10 23:23:01 +00003363static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003364posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003365{
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 char buf[1026];
3367 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003368
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003369#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 if (!use_bytes) {
3371 wchar_t wbuf[1026];
3372 wchar_t *wbuf2 = wbuf;
3373 PyObject *resobj;
3374 DWORD len;
3375 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003376 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 /* If the buffer is large enough, len does not include the
3378 terminating \0. If the buffer is too small, len includes
3379 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003380 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003381 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 if (wbuf2)
3383 len = GetCurrentDirectoryW(len, wbuf2);
3384 }
3385 Py_END_ALLOW_THREADS
3386 if (!wbuf2) {
3387 PyErr_NoMemory();
3388 return NULL;
3389 }
3390 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003391 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003392 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003393 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 }
3395 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003396 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003397 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 return resobj;
3399 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003400
3401 if (win32_warn_bytes_api())
3402 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003403#endif
3404
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 Py_END_ALLOW_THREADS
3408 if (res == NULL)
3409 return posix_error();
3410 if (use_bytes)
3411 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003412 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003413}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003414
3415PyDoc_STRVAR(posix_getcwd__doc__,
3416"getcwd() -> path\n\n\
3417Return a unicode string representing the current working directory.");
3418
3419static PyObject *
3420posix_getcwd_unicode(PyObject *self)
3421{
3422 return posix_getcwd(0);
3423}
3424
3425PyDoc_STRVAR(posix_getcwdb__doc__,
3426"getcwdb() -> path\n\n\
3427Return a bytes string representing the current working directory.");
3428
3429static PyObject *
3430posix_getcwd_bytes(PyObject *self)
3431{
3432 return posix_getcwd(1);
3433}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003434
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3436#define HAVE_LINK 1
3437#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003438
Guido van Rossumb6775db1994-08-01 11:34:53 +00003439#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003440PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3442Create a hard link to a file.\n\
3443\n\
3444If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3445 descriptor open to a directory, and the respective path string (src or dst)\n\
3446 should be relative; the path will then be relative to that directory.\n\
3447If follow_symlinks is False, and the last element of src is a symbolic\n\
3448 link, link will create a link to the symbolic link itself instead of the\n\
3449 file the link points to.\n\
3450src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3451 platform. If they are unavailable, using them will raise a\n\
3452 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003453
Barry Warsaw53699e91996-12-10 23:23:01 +00003454static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003456{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 path_t src, dst;
3458 int src_dir_fd = DEFAULT_DIR_FD;
3459 int dst_dir_fd = DEFAULT_DIR_FD;
3460 int follow_symlinks = 1;
3461 PyObject *return_value = NULL;
3462 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3463 "follow_symlinks", NULL};
3464#ifdef MS_WINDOWS
3465 BOOL result;
3466#else
3467 int result;
3468#endif
3469
3470 memset(&src, 0, sizeof(src));
3471 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003472 src.function_name = "link";
3473 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3475 path_converter, &src,
3476 path_converter, &dst,
3477 dir_fd_converter, &src_dir_fd,
3478 dir_fd_converter, &dst_dir_fd,
3479 &follow_symlinks))
3480 return NULL;
3481
3482#ifndef HAVE_LINKAT
3483 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3484 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3485 goto exit;
3486 }
3487#endif
3488
3489 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3490 PyErr_SetString(PyExc_NotImplementedError,
3491 "link: src and dst must be the same type");
3492 goto exit;
3493 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003494
Brian Curtin1b9df392010-11-24 20:24:31 +00003495#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 Py_BEGIN_ALLOW_THREADS
3497 if (src.wide)
3498 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3499 else
3500 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3501 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003502
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003504 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003506 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507#else
3508 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003509#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3511 (dst_dir_fd != DEFAULT_DIR_FD) ||
3512 (!follow_symlinks))
3513 result = linkat(src_dir_fd, src.narrow,
3514 dst_dir_fd, dst.narrow,
3515 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3516 else
3517#endif
3518 result = link(src.narrow, dst.narrow);
3519 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003520
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003522 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003524 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525#endif
3526
3527 return_value = Py_None;
3528 Py_INCREF(Py_None);
3529
3530exit:
3531 path_cleanup(&src);
3532 path_cleanup(&dst);
3533 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003534}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535#endif
3536
Brian Curtin1b9df392010-11-24 20:24:31 +00003537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003539PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003540"listdir(path='.') -> list_of_filenames\n\n\
3541Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003542The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543entries '.' and '..' even if they are present in the directory.\n\
3544\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003545path can be specified as either str or bytes. If path is bytes,\n\
3546 the filenames returned will also be bytes; in all other circumstances\n\
3547 the filenames returned will be str.\n\
3548On some platforms, path may also be specified as an open file descriptor;\n\
3549 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003551
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003552#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003553static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003554_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003555{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 PyObject *v;
3558 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3559 BOOL result;
3560 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003561 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 char *bufptr = namebuf;
3563 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003564 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 PyObject *po = NULL;
3566 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567
Gregory P. Smith40a21602013-03-20 20:52:50 -07003568 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003571
Gregory P. Smith40a21602013-03-20 20:52:50 -07003572 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003573 po_wchars = L".";
3574 len = 1;
3575 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576 po_wchars = path->wide;
3577 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003578 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003580 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 if (!wnamebuf) {
3582 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003585 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003587 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003588 if (wch != SEP && wch != ALTSEP && wch != L':')
3589 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 wcscpy(wnamebuf + len, L"*.*");
3591 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 if ((list = PyList_New(0)) == NULL) {
3593 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003595 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003597 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (hFindFile == INVALID_HANDLE_VALUE) {
3599 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 if (error == ERROR_FILE_NOT_FOUND)
3601 goto exit;
3602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 }
3606 do {
3607 /* Skip over . and .. */
3608 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3609 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 v = PyUnicode_FromWideChar(wFileData.cFileName,
3611 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 Py_DECREF(list);
3614 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 break;
3616 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 Py_DECREF(list);
3620 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 break;
3622 }
3623 Py_DECREF(v);
3624 }
3625 Py_BEGIN_ALLOW_THREADS
3626 result = FindNextFileW(hFindFile, &wFileData);
3627 Py_END_ALLOW_THREADS
3628 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3629 it got to the end of the directory. */
3630 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003632 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 }
3635 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003636
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003639 strcpy(namebuf, path->narrow);
3640 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 if (len > 0) {
3642 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003643 if (ch != '\\' && ch != '/' && ch != ':')
3644 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 strcpy(namebuf + len, "*.*");
3646 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003647
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003650
Antoine Pitroub73caab2010-08-09 23:39:31 +00003651 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003652 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003653 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 if (hFindFile == INVALID_HANDLE_VALUE) {
3655 int error = GetLastError();
3656 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 goto exit;
3658 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003659 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 }
3662 do {
3663 /* Skip over . and .. */
3664 if (strcmp(FileData.cFileName, ".") != 0 &&
3665 strcmp(FileData.cFileName, "..") != 0) {
3666 v = PyBytes_FromString(FileData.cFileName);
3667 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668 Py_DECREF(list);
3669 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 break;
3671 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_DECREF(list);
3675 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 break;
3677 }
3678 Py_DECREF(v);
3679 }
3680 Py_BEGIN_ALLOW_THREADS
3681 result = FindNextFile(hFindFile, &FileData);
3682 Py_END_ALLOW_THREADS
3683 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3684 it got to the end of the directory. */
3685 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003686 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003687 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 }
3690 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003691
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692exit:
3693 if (hFindFile != INVALID_HANDLE_VALUE) {
3694 if (FindClose(hFindFile) == FALSE) {
3695 if (list != NULL) {
3696 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003697 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 }
3699 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003701 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003702
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003704} /* end of _listdir_windows_no_opendir */
3705
3706#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3707
3708static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003709_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003710{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003711 PyObject *v;
3712 DIR *dirp = NULL;
3713 struct dirent *ep;
3714 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003715#ifdef HAVE_FDOPENDIR
3716 int fd = -1;
3717#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003718
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003721 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003722 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003723 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003724 if (fd == -1)
3725 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726
Larry Hastingsfdaea062012-06-25 04:42:23 -07003727 return_str = 1;
3728
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 Py_BEGIN_ALLOW_THREADS
3730 dirp = fdopendir(fd);
3731 Py_END_ALLOW_THREADS
3732 }
3733 else
3734#endif
3735 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003736 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003737 if (path->narrow) {
3738 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003739 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003740 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003741 }
3742 else {
3743 name = ".";
3744 return_str = 1;
3745 }
3746
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 Py_BEGIN_ALLOW_THREADS
3748 dirp = opendir(name);
3749 Py_END_ALLOW_THREADS
3750 }
3751
3752 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003753 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003754#ifdef HAVE_FDOPENDIR
3755 if (fd != -1) {
3756 Py_BEGIN_ALLOW_THREADS
3757 close(fd);
3758 Py_END_ALLOW_THREADS
3759 }
3760#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761 goto exit;
3762 }
3763 if ((list = PyList_New(0)) == NULL) {
3764 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 }
3766 for (;;) {
3767 errno = 0;
3768 Py_BEGIN_ALLOW_THREADS
3769 ep = readdir(dirp);
3770 Py_END_ALLOW_THREADS
3771 if (ep == NULL) {
3772 if (errno == 0) {
3773 break;
3774 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003775 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003776 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 }
3779 }
3780 if (ep->d_name[0] == '.' &&
3781 (NAMLEN(ep) == 1 ||
3782 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3783 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003784 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003785 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3786 else
3787 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003789 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 break;
3791 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003792 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003794 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 break;
3796 }
3797 Py_DECREF(v);
3798 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003799
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800exit:
3801 if (dirp != NULL) {
3802 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003803#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003804 if (fd > -1)
3805 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003806#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003807 closedir(dirp);
3808 Py_END_ALLOW_THREADS
3809 }
3810
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003812} /* end of _posix_listdir */
3813#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003814
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003815static PyObject *
3816posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3817{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003818 path_t path;
3819 PyObject *list = NULL;
3820 static char *keywords[] = {"path", NULL};
3821 PyObject *return_value;
3822
3823 memset(&path, 0, sizeof(path));
3824 path.function_name = "listdir";
3825 path.nullable = 1;
3826#ifdef HAVE_FDOPENDIR
3827 path.allow_fd = 1;
3828 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003829#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003830
3831 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3832 path_converter, &path)) {
3833 return NULL;
3834 }
3835
3836#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3837 return_value = _listdir_windows_no_opendir(&path, list);
3838#else
3839 return_value = _posix_listdir(&path, list);
3840#endif
3841 path_cleanup(&path);
3842 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003843}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003844
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003845#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003846/* A helper function for abspath on win32 */
3847static PyObject *
3848posix__getfullpathname(PyObject *self, PyObject *args)
3849{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003850 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003851 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003853 PyObject *po;
3854
3855 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3856 {
3857 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003858 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003859 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003860 DWORD result;
3861 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003862
3863 wpath = PyUnicode_AsUnicode(po);
3864 if (wpath == NULL)
3865 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003866 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003867 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003869 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003870 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 if (!woutbufp)
3872 return PyErr_NoMemory();
3873 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3874 }
3875 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003876 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003878 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003880 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 return v;
3882 }
3883 /* Drop the argument parsing error as narrow strings
3884 are also valid. */
3885 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003886
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003887 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3888 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003890 if (win32_warn_bytes_api())
3891 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003892 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 outbuf, &temp)) {
3894 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 return NULL;
3896 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3898 return PyUnicode_Decode(outbuf, strlen(outbuf),
3899 Py_FileSystemDefaultEncoding, NULL);
3900 }
3901 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003902} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003903
Brian Curtind25aef52011-06-13 15:16:04 -05003904
Brian Curtinf5e76d02010-11-24 13:14:05 +00003905
Brian Curtind40e6f72010-07-08 21:39:08 +00003906/* A helper function for samepath on windows */
3907static PyObject *
3908posix__getfinalpathname(PyObject *self, PyObject *args)
3909{
3910 HANDLE hFile;
3911 int buf_size;
3912 wchar_t *target_path;
3913 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003914 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003915 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003916
Victor Stinnereb5657a2011-09-30 01:44:27 +02003917 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003918 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003919 path = PyUnicode_AsUnicode(po);
3920 if (path == NULL)
3921 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003922
3923 if(!check_GetFinalPathNameByHandle()) {
3924 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3925 NotImplementedError. */
3926 return PyErr_Format(PyExc_NotImplementedError,
3927 "GetFinalPathNameByHandle not available on this platform");
3928 }
3929
3930 hFile = CreateFileW(
3931 path,
3932 0, /* desired access */
3933 0, /* share mode */
3934 NULL, /* security attributes */
3935 OPEN_EXISTING,
3936 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3937 FILE_FLAG_BACKUP_SEMANTICS,
3938 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003939
Victor Stinnereb5657a2011-09-30 01:44:27 +02003940 if(hFile == INVALID_HANDLE_VALUE)
3941 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003942
3943 /* We have a good handle to the target, use it to determine the
3944 target path name. */
3945 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3946
3947 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003948 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003949
Victor Stinnerb6404912013-07-07 16:21:41 +02003950 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003951 if(!target_path)
3952 return PyErr_NoMemory();
3953
3954 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3955 buf_size, VOLUME_NAME_DOS);
3956 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003957 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003958
3959 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003960 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003961
3962 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003963 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003964 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003965 return result;
3966
3967} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003968
Brian Curtin95d028f2011-06-09 09:10:38 -05003969PyDoc_STRVAR(posix__isdir__doc__,
3970"Return true if the pathname refers to an existing directory.");
3971
Brian Curtin9c669cc2011-06-08 18:17:18 -05003972static PyObject *
3973posix__isdir(PyObject *self, PyObject *args)
3974{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003975 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003976 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003977 DWORD attributes;
3978
3979 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003980 wchar_t *wpath = PyUnicode_AsUnicode(po);
3981 if (wpath == NULL)
3982 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003983
3984 attributes = GetFileAttributesW(wpath);
3985 if (attributes == INVALID_FILE_ATTRIBUTES)
3986 Py_RETURN_FALSE;
3987 goto check;
3988 }
3989 /* Drop the argument parsing error as narrow strings
3990 are also valid. */
3991 PyErr_Clear();
3992
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003993 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003994 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003995 if (win32_warn_bytes_api())
3996 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003997 attributes = GetFileAttributesA(path);
3998 if (attributes == INVALID_FILE_ATTRIBUTES)
3999 Py_RETURN_FALSE;
4000
4001check:
4002 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4003 Py_RETURN_TRUE;
4004 else
4005 Py_RETURN_FALSE;
4006}
Tim Golden6b528062013-08-01 12:44:00 +01004007
4008PyDoc_STRVAR(posix__getvolumepathname__doc__,
4009"Return volume mount point of the specified path.");
4010
4011/* A helper function for ismount on windows */
4012static PyObject *
4013posix__getvolumepathname(PyObject *self, PyObject *args)
4014{
4015 PyObject *po, *result;
4016 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004017 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004018 BOOL ret;
4019
4020 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4021 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004022 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004023 if (path == NULL)
4024 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004025 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004026
4027 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004028 buflen = Py_MAX(buflen, MAX_PATH);
4029
4030 if (buflen > DWORD_MAX) {
4031 PyErr_SetString(PyExc_OverflowError, "path too long");
4032 return NULL;
4033 }
4034
4035 mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
Tim Golden6b528062013-08-01 12:44:00 +01004036 if (mountpath == NULL)
4037 return PyErr_NoMemory();
4038
4039 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004040 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004041 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004042 Py_END_ALLOW_THREADS
4043
4044 if (!ret) {
4045 result = win32_error_object("_getvolumepathname", po);
4046 goto exit;
4047 }
4048 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4049
4050exit:
4051 PyMem_Free(mountpath);
4052 return result;
4053}
4054/* end of posix__getvolumepathname */
4055
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004056#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4060Create a directory.\n\
4061\n\
4062If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4063 and path should be relative; path will then be relative to that directory.\n\
4064dir_fd may not be implemented on your platform.\n\
4065 If it is unavailable, using it will raise a NotImplementedError.\n\
4066\n\
4067The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004068
Barry Warsaw53699e91996-12-10 23:23:01 +00004069static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004070posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004071{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004072 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 int dir_fd = DEFAULT_DIR_FD;
4075 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4076 PyObject *return_value = NULL;
4077 int result;
4078
4079 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004080 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4082 path_converter, &path, &mode,
4083#ifdef HAVE_MKDIRAT
4084 dir_fd_converter, &dir_fd
4085#else
4086 dir_fd_unavailable, &dir_fd
4087#endif
4088 ))
4089 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004090
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004091#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093 if (path.wide)
4094 result = CreateDirectoryW(path.wide, NULL);
4095 else
4096 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004097 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004098
Larry Hastings9cf065c2012-06-22 16:30:09 -07004099 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004100 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004101 goto exit;
4102 }
4103#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004104 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105#if HAVE_MKDIRAT
4106 if (dir_fd != DEFAULT_DIR_FD)
4107 result = mkdirat(dir_fd, path.narrow, mode);
4108 else
4109#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004110#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004112#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004114#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004117 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 goto exit;
4119 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004120#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121 return_value = Py_None;
4122 Py_INCREF(Py_None);
4123exit:
4124 path_cleanup(&path);
4125 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004126}
4127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004128
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004129/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4130#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004131#include <sys/resource.h>
4132#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004133
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004134
4135#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004136PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004137"nice(inc) -> new_priority\n\n\
4138Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004139
Barry Warsaw53699e91996-12-10 23:23:01 +00004140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004141posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004142{
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004144
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4146 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004147
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 /* There are two flavours of 'nice': one that returns the new
4149 priority (as required by almost all standards out there) and the
4150 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4151 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004152
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 If we are of the nice family that returns the new priority, we
4154 need to clear errno before the call, and check if errno is filled
4155 before calling posix_error() on a returnvalue of -1, because the
4156 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004157
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 errno = 0;
4159 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004160#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 if (value == 0)
4162 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004163#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 if (value == -1 && errno != 0)
4165 /* either nice() or getpriority() returned an error */
4166 return posix_error();
4167 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004168}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004169#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004170
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004171
4172#ifdef HAVE_GETPRIORITY
4173PyDoc_STRVAR(posix_getpriority__doc__,
4174"getpriority(which, who) -> current_priority\n\n\
4175Get program scheduling priority.");
4176
4177static PyObject *
4178posix_getpriority(PyObject *self, PyObject *args)
4179{
4180 int which, who, retval;
4181
4182 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4183 return NULL;
4184 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004185 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004186 if (errno != 0)
4187 return posix_error();
4188 return PyLong_FromLong((long)retval);
4189}
4190#endif /* HAVE_GETPRIORITY */
4191
4192
4193#ifdef HAVE_SETPRIORITY
4194PyDoc_STRVAR(posix_setpriority__doc__,
4195"setpriority(which, who, prio) -> None\n\n\
4196Set program scheduling priority.");
4197
4198static PyObject *
4199posix_setpriority(PyObject *self, PyObject *args)
4200{
4201 int which, who, prio, retval;
4202
4203 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4204 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004205 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004206 if (retval == -1)
4207 return posix_error();
4208 Py_RETURN_NONE;
4209}
4210#endif /* HAVE_SETPRIORITY */
4211
4212
Barry Warsaw53699e91996-12-10 23:23:01 +00004213static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004214internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004215{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004216 char *function_name = is_replace ? "replace" : "rename";
4217 path_t src;
4218 path_t dst;
4219 int src_dir_fd = DEFAULT_DIR_FD;
4220 int dst_dir_fd = DEFAULT_DIR_FD;
4221 int dir_fd_specified;
4222 PyObject *return_value = NULL;
4223 char format[24];
4224 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4225
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004226#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004228 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004229#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004231#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232
4233 memset(&src, 0, sizeof(src));
4234 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004235 src.function_name = function_name;
4236 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004237 strcpy(format, "O&O&|$O&O&:");
4238 strcat(format, function_name);
4239 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4240 path_converter, &src,
4241 path_converter, &dst,
4242 dir_fd_converter, &src_dir_fd,
4243 dir_fd_converter, &dst_dir_fd))
4244 return NULL;
4245
4246 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4247 (dst_dir_fd != DEFAULT_DIR_FD);
4248#ifndef HAVE_RENAMEAT
4249 if (dir_fd_specified) {
4250 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4251 goto exit;
4252 }
4253#endif
4254
4255 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4256 PyErr_Format(PyExc_ValueError,
4257 "%s: src and dst must be the same type", function_name);
4258 goto exit;
4259 }
4260
4261#ifdef MS_WINDOWS
4262 Py_BEGIN_ALLOW_THREADS
4263 if (src.wide)
4264 result = MoveFileExW(src.wide, dst.wide, flags);
4265 else
4266 result = MoveFileExA(src.narrow, dst.narrow, flags);
4267 Py_END_ALLOW_THREADS
4268
4269 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004270 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271 goto exit;
4272 }
4273
4274#else
4275 Py_BEGIN_ALLOW_THREADS
4276#ifdef HAVE_RENAMEAT
4277 if (dir_fd_specified)
4278 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4279 else
4280#endif
4281 result = rename(src.narrow, dst.narrow);
4282 Py_END_ALLOW_THREADS
4283
4284 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004285 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004286 goto exit;
4287 }
4288#endif
4289
4290 Py_INCREF(Py_None);
4291 return_value = Py_None;
4292exit:
4293 path_cleanup(&src);
4294 path_cleanup(&dst);
4295 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004296}
4297
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004298PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4300Rename a file or directory.\n\
4301\n\
4302If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4303 descriptor open to a directory, and the respective path string (src or dst)\n\
4304 should be relative; the path will then be relative to that directory.\n\
4305src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4306 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004307
4308static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004310{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004312}
4313
4314PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4316Rename a file or directory, overwriting the destination.\n\
4317\n\
4318If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4319 descriptor open to a directory, and the respective path string (src or dst)\n\
4320 should be relative; the path will then be relative to that directory.\n\
4321src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4322 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004323
4324static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004326{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004327 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004328}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004330PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004331"rmdir(path, *, dir_fd=None)\n\n\
4332Remove a directory.\n\
4333\n\
4334If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4335 and path should be relative; path will then be relative to that directory.\n\
4336dir_fd may not be implemented on your platform.\n\
4337 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004338
Barry Warsaw53699e91996-12-10 23:23:01 +00004339static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004340posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004341{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004342 path_t path;
4343 int dir_fd = DEFAULT_DIR_FD;
4344 static char *keywords[] = {"path", "dir_fd", NULL};
4345 int result;
4346 PyObject *return_value = NULL;
4347
4348 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004349 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004350 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4351 path_converter, &path,
4352#ifdef HAVE_UNLINKAT
4353 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004354#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004355 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004356#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004357 ))
4358 return NULL;
4359
4360 Py_BEGIN_ALLOW_THREADS
4361#ifdef MS_WINDOWS
4362 if (path.wide)
4363 result = RemoveDirectoryW(path.wide);
4364 else
4365 result = RemoveDirectoryA(path.narrow);
4366 result = !result; /* Windows, success=1, UNIX, success=0 */
4367#else
4368#ifdef HAVE_UNLINKAT
4369 if (dir_fd != DEFAULT_DIR_FD)
4370 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4371 else
4372#endif
4373 result = rmdir(path.narrow);
4374#endif
4375 Py_END_ALLOW_THREADS
4376
4377 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004378 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004379 goto exit;
4380 }
4381
4382 return_value = Py_None;
4383 Py_INCREF(Py_None);
4384
4385exit:
4386 path_cleanup(&path);
4387 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004388}
4389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004390
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004391#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004392PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004393"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004394Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004395
Barry Warsaw53699e91996-12-10 23:23:01 +00004396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004397posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004398{
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004400#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004401 wchar_t *command;
4402 if (!PyArg_ParseTuple(args, "u:system", &command))
4403 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004404
Victor Stinner8c62be82010-05-06 00:08:46 +00004405 Py_BEGIN_ALLOW_THREADS
4406 sts = _wsystem(command);
4407 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004408#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004409 PyObject *command_obj;
4410 char *command;
4411 if (!PyArg_ParseTuple(args, "O&:system",
4412 PyUnicode_FSConverter, &command_obj))
4413 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004414
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 command = PyBytes_AsString(command_obj);
4416 Py_BEGIN_ALLOW_THREADS
4417 sts = system(command);
4418 Py_END_ALLOW_THREADS
4419 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004420#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004421 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004422}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004423#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004425
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004426PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004427"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004428Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004429
Barry Warsaw53699e91996-12-10 23:23:01 +00004430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004431posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004432{
Victor Stinner8c62be82010-05-06 00:08:46 +00004433 int i;
4434 if (!PyArg_ParseTuple(args, "i:umask", &i))
4435 return NULL;
4436 i = (int)umask(i);
4437 if (i < 0)
4438 return posix_error();
4439 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004440}
4441
Brian Curtind40e6f72010-07-08 21:39:08 +00004442#ifdef MS_WINDOWS
4443
4444/* override the default DeleteFileW behavior so that directory
4445symlinks can be removed with this function, the same as with
4446Unix symlinks */
4447BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4448{
4449 WIN32_FILE_ATTRIBUTE_DATA info;
4450 WIN32_FIND_DATAW find_data;
4451 HANDLE find_data_handle;
4452 int is_directory = 0;
4453 int is_link = 0;
4454
4455 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4456 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004457
Brian Curtind40e6f72010-07-08 21:39:08 +00004458 /* Get WIN32_FIND_DATA structure for the path to determine if
4459 it is a symlink */
4460 if(is_directory &&
4461 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4462 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4463
4464 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004465 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4466 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4467 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4468 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004469 FindClose(find_data_handle);
4470 }
4471 }
4472 }
4473
4474 if (is_directory && is_link)
4475 return RemoveDirectoryW(lpFileName);
4476
4477 return DeleteFileW(lpFileName);
4478}
4479#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004481PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004482"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004483Remove a file (same as remove()).\n\
4484\n\
4485If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4486 and path should be relative; path will then be relative to that directory.\n\
4487dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004488 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004491"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492Remove a file (same as unlink()).\n\
4493\n\
4494If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4495 and path should be relative; path will then be relative to that directory.\n\
4496dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004497 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004498
Barry Warsaw53699e91996-12-10 23:23:01 +00004499static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004500posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004501{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502 path_t path;
4503 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004504 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004505 int result;
4506 PyObject *return_value = NULL;
4507
4508 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004509 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004510 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004511 path_converter, &path,
4512#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004513 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004514#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004515 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004516#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004517 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 return NULL;
4519
4520 Py_BEGIN_ALLOW_THREADS
4521#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004522 if (path.wide)
4523 result = Py_DeleteFileW(path.wide);
4524 else
4525 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 result = !result; /* Windows, success=1, UNIX, success=0 */
4527#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004528#ifdef HAVE_UNLINKAT
4529 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004530 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 else
4532#endif /* HAVE_UNLINKAT */
4533 result = unlink(path.narrow);
4534#endif
4535 Py_END_ALLOW_THREADS
4536
4537 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004538 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539 goto exit;
4540 }
4541
4542 return_value = Py_None;
4543 Py_INCREF(Py_None);
4544
4545exit:
4546 path_cleanup(&path);
4547 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004548}
4549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004551PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004552"uname() -> uname_result\n\n\
4553Return an object identifying the current operating system.\n\
4554The object behaves like a named tuple with the following fields:\n\
4555 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004556
Larry Hastings605a62d2012-06-24 04:33:36 -07004557static PyStructSequence_Field uname_result_fields[] = {
4558 {"sysname", "operating system name"},
4559 {"nodename", "name of machine on network (implementation-defined)"},
4560 {"release", "operating system release"},
4561 {"version", "operating system version"},
4562 {"machine", "hardware identifier"},
4563 {NULL}
4564};
4565
4566PyDoc_STRVAR(uname_result__doc__,
4567"uname_result: Result from os.uname().\n\n\
4568This object may be accessed either as a tuple of\n\
4569 (sysname, nodename, release, version, machine),\n\
4570or via the attributes sysname, nodename, release, version, and machine.\n\
4571\n\
4572See os.uname for more information.");
4573
4574static PyStructSequence_Desc uname_result_desc = {
4575 "uname_result", /* name */
4576 uname_result__doc__, /* doc */
4577 uname_result_fields,
4578 5
4579};
4580
4581static PyTypeObject UnameResultType;
4582
4583
4584#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004586posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004587{
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 struct utsname u;
4589 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004590 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004591
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 Py_BEGIN_ALLOW_THREADS
4593 res = uname(&u);
4594 Py_END_ALLOW_THREADS
4595 if (res < 0)
4596 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004597
4598 value = PyStructSequence_New(&UnameResultType);
4599 if (value == NULL)
4600 return NULL;
4601
4602#define SET(i, field) \
4603 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004604 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004605 if (!o) { \
4606 Py_DECREF(value); \
4607 return NULL; \
4608 } \
4609 PyStructSequence_SET_ITEM(value, i, o); \
4610 } \
4611
4612 SET(0, u.sysname);
4613 SET(1, u.nodename);
4614 SET(2, u.release);
4615 SET(3, u.version);
4616 SET(4, u.machine);
4617
4618#undef SET
4619
4620 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004621}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004622#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004623
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004624
Larry Hastings9cf065c2012-06-22 16:30:09 -07004625PyDoc_STRVAR(posix_utime__doc__,
4626"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4627Set the access and modified time of path.\n\
4628\n\
4629path may always be specified as a string.\n\
4630On some platforms, path may also be specified as an open file descriptor.\n\
4631 If this functionality is unavailable, using it raises an exception.\n\
4632\n\
4633If times is not None, it must be a tuple (atime, mtime);\n\
4634 atime and mtime should be expressed as float seconds since the epoch.\n\
4635If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4636 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4637 since the epoch.\n\
4638If both times and ns are None, utime uses the current time.\n\
4639Specifying tuples for both times and ns is an error.\n\
4640\n\
4641If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4642 and path should be relative; path will then be relative to that directory.\n\
4643If follow_symlinks is False, and the last element of the path is a symbolic\n\
4644 link, utime will modify the symbolic link itself instead of the file the\n\
4645 link points to.\n\
4646It is an error to use dir_fd or follow_symlinks when specifying path\n\
4647 as an open file descriptor.\n\
4648dir_fd and follow_symlinks may not be available on your platform.\n\
4649 If they are unavailable, using them will raise a NotImplementedError.");
4650
4651typedef struct {
4652 int now;
4653 time_t atime_s;
4654 long atime_ns;
4655 time_t mtime_s;
4656 long mtime_ns;
4657} utime_t;
4658
4659/*
4660 * these macros assume that "utime" is a pointer to a utime_t
4661 * they also intentionally leak the declaration of a pointer named "time"
4662 */
4663#define UTIME_TO_TIMESPEC \
4664 struct timespec ts[2]; \
4665 struct timespec *time; \
4666 if (utime->now) \
4667 time = NULL; \
4668 else { \
4669 ts[0].tv_sec = utime->atime_s; \
4670 ts[0].tv_nsec = utime->atime_ns; \
4671 ts[1].tv_sec = utime->mtime_s; \
4672 ts[1].tv_nsec = utime->mtime_ns; \
4673 time = ts; \
4674 } \
4675
4676#define UTIME_TO_TIMEVAL \
4677 struct timeval tv[2]; \
4678 struct timeval *time; \
4679 if (utime->now) \
4680 time = NULL; \
4681 else { \
4682 tv[0].tv_sec = utime->atime_s; \
4683 tv[0].tv_usec = utime->atime_ns / 1000; \
4684 tv[1].tv_sec = utime->mtime_s; \
4685 tv[1].tv_usec = utime->mtime_ns / 1000; \
4686 time = tv; \
4687 } \
4688
4689#define UTIME_TO_UTIMBUF \
4690 struct utimbuf u[2]; \
4691 struct utimbuf *time; \
4692 if (utime->now) \
4693 time = NULL; \
4694 else { \
4695 u.actime = utime->atime_s; \
4696 u.modtime = utime->mtime_s; \
4697 time = u; \
4698 }
4699
4700#define UTIME_TO_TIME_T \
4701 time_t timet[2]; \
4702 struct timet time; \
4703 if (utime->now) \
4704 time = NULL; \
4705 else { \
4706 timet[0] = utime->atime_s; \
4707 timet[1] = utime->mtime_s; \
4708 time = &timet; \
4709 } \
4710
4711
4712#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4713
4714#if UTIME_HAVE_DIR_FD
4715
4716static int
4717utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4718{
4719#ifdef HAVE_UTIMENSAT
4720 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4721 UTIME_TO_TIMESPEC;
4722 return utimensat(dir_fd, path, time, flags);
4723#elif defined(HAVE_FUTIMESAT)
4724 UTIME_TO_TIMEVAL;
4725 /*
4726 * follow_symlinks will never be false here;
4727 * we only allow !follow_symlinks and dir_fd together
4728 * if we have utimensat()
4729 */
4730 assert(follow_symlinks);
4731 return futimesat(dir_fd, path, time);
4732#endif
4733}
4734
4735#endif
4736
4737#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4738
4739#if UTIME_HAVE_FD
4740
4741static int
4742utime_fd(utime_t *utime, int fd)
4743{
4744#ifdef HAVE_FUTIMENS
4745 UTIME_TO_TIMESPEC;
4746 return futimens(fd, time);
4747#else
4748 UTIME_TO_TIMEVAL;
4749 return futimes(fd, time);
4750#endif
4751}
4752
4753#endif
4754
4755
4756#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4757 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4758
4759#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4760
4761static int
4762utime_nofollow_symlinks(utime_t *utime, char *path)
4763{
4764#ifdef HAVE_UTIMENSAT
4765 UTIME_TO_TIMESPEC;
4766 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4767#else
4768 UTIME_TO_TIMEVAL;
4769 return lutimes(path, time);
4770#endif
4771}
4772
4773#endif
4774
4775#ifndef MS_WINDOWS
4776
4777static int
4778utime_default(utime_t *utime, char *path)
4779{
4780#ifdef HAVE_UTIMENSAT
4781 UTIME_TO_TIMESPEC;
4782 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4783#elif defined(HAVE_UTIMES)
4784 UTIME_TO_TIMEVAL;
4785 return utimes(path, time);
4786#elif defined(HAVE_UTIME_H)
4787 UTIME_TO_UTIMBUF;
4788 return utime(path, time);
4789#else
4790 UTIME_TO_TIME_T;
4791 return utime(path, time);
4792#endif
4793}
4794
4795#endif
4796
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797static int
4798split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4799{
4800 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004801 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004802 divmod = PyNumber_Divmod(py_long, billion);
4803 if (!divmod)
4804 goto exit;
4805 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4806 if ((*s == -1) && PyErr_Occurred())
4807 goto exit;
4808 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004809 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004810 goto exit;
4811
4812 result = 1;
4813exit:
4814 Py_XDECREF(divmod);
4815 return result;
4816}
4817
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818static PyObject *
4819posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004820{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004822 PyObject *times = NULL;
4823 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 int dir_fd = DEFAULT_DIR_FD;
4825 int follow_symlinks = 1;
4826 char *keywords[] = {"path", "times", "ns", "dir_fd",
4827 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004828
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004830
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831#ifdef MS_WINDOWS
4832 HANDLE hFile;
4833 FILETIME atime, mtime;
4834#else
4835 int result;
4836#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004837
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004839
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004841 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004842 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843#if UTIME_HAVE_FD
4844 path.allow_fd = 1;
4845#endif
4846 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4847 "O&|O$OO&p:utime", keywords,
4848 path_converter, &path,
4849 &times, &ns,
4850#if UTIME_HAVE_DIR_FD
4851 dir_fd_converter, &dir_fd,
4852#else
4853 dir_fd_unavailable, &dir_fd,
4854#endif
4855 &follow_symlinks
4856 ))
4857 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004858
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859 if (times && (times != Py_None) && ns) {
4860 PyErr_SetString(PyExc_ValueError,
4861 "utime: you may specify either 'times'"
4862 " or 'ns' but not both");
4863 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004864 }
4865
4866 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004867 time_t a_sec, m_sec;
4868 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004869 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870 PyErr_SetString(PyExc_TypeError,
4871 "utime: 'times' must be either"
4872 " a tuple of two ints or None");
4873 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004874 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004876 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004877 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004878 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004879 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004880 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004881 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004882 utime.atime_s = a_sec;
4883 utime.atime_ns = a_nsec;
4884 utime.mtime_s = m_sec;
4885 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004886 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004887 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 PyErr_SetString(PyExc_TypeError,
4890 "utime: 'ns' must be a tuple of two ints");
4891 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004892 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004894 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004895 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004896 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897 &utime.mtime_s, &utime.mtime_ns)) {
4898 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004899 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 }
4901 else {
4902 /* times and ns are both None/unspecified. use "now". */
4903 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004904 }
4905
Larry Hastings9cf065c2012-06-22 16:30:09 -07004906#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4907 if (follow_symlinks_specified("utime", follow_symlinks))
4908 goto exit;
4909#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004910
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4912 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4913 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4914 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004915
Larry Hastings9cf065c2012-06-22 16:30:09 -07004916#if !defined(HAVE_UTIMENSAT)
4917 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004918 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 "utime: cannot use dir_fd and follow_symlinks "
4920 "together on this platform");
4921 goto exit;
4922 }
4923#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004924
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004925#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004926 Py_BEGIN_ALLOW_THREADS
4927 if (path.wide)
4928 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 NULL, OPEN_EXISTING,
4930 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004931 else
4932 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 NULL, OPEN_EXISTING,
4934 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004935 Py_END_ALLOW_THREADS
4936 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004937 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004938 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004939 }
4940
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004942 GetSystemTimeAsFileTime(&mtime);
4943 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4947 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 }
4949 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4950 /* Avoid putting the file name into the error here,
4951 as that may confuse the user into believing that
4952 something is wrong with the file, when it also
4953 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004954 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004957#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004959
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4961 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4962 result = utime_nofollow_symlinks(&utime, path.narrow);
4963 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004964#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965
4966#if UTIME_HAVE_DIR_FD
4967 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4968 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4969 else
4970#endif
4971
4972#if UTIME_HAVE_FD
4973 if (path.fd != -1)
4974 result = utime_fd(&utime, path.fd);
4975 else
4976#endif
4977
4978 result = utime_default(&utime, path.narrow);
4979
4980 Py_END_ALLOW_THREADS
4981
4982 if (result < 0) {
4983 /* see previous comment about not putting filename in error here */
4984 return_value = posix_error();
4985 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004987
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004988#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004989
4990 Py_INCREF(Py_None);
4991 return_value = Py_None;
4992
4993exit:
4994 path_cleanup(&path);
4995#ifdef MS_WINDOWS
4996 if (hFile != INVALID_HANDLE_VALUE)
4997 CloseHandle(hFile);
4998#endif
4999 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005000}
5001
Guido van Rossum3b066191991-06-04 19:40:25 +00005002/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005003
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005004PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005005"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005006Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005007
Barry Warsaw53699e91996-12-10 23:23:01 +00005008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005009posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005010{
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 int sts;
5012 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5013 return NULL;
5014 _exit(sts);
5015 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005016}
5017
Martin v. Löwis114619e2002-10-07 06:44:21 +00005018#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5019static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005020free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005021{
Victor Stinner8c62be82010-05-06 00:08:46 +00005022 Py_ssize_t i;
5023 for (i = 0; i < count; i++)
5024 PyMem_Free(array[i]);
5025 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005026}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005027
Antoine Pitrou69f71142009-05-24 21:25:49 +00005028static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005029int fsconvert_strdup(PyObject *o, char**out)
5030{
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 PyObject *bytes;
5032 Py_ssize_t size;
5033 if (!PyUnicode_FSConverter(o, &bytes))
5034 return 0;
5035 size = PyBytes_GET_SIZE(bytes);
5036 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005037 if (!*out) {
5038 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005040 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 memcpy(*out, PyBytes_AsString(bytes), size+1);
5042 Py_DECREF(bytes);
5043 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005044}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005045#endif
5046
Ross Lagerwall7807c352011-03-17 20:20:30 +02005047#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005048static char**
5049parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5050{
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 char **envlist;
5052 Py_ssize_t i, pos, envc;
5053 PyObject *keys=NULL, *vals=NULL;
5054 PyObject *key, *val, *key2, *val2;
5055 char *p, *k, *v;
5056 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005057
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 i = PyMapping_Size(env);
5059 if (i < 0)
5060 return NULL;
5061 envlist = PyMem_NEW(char *, i + 1);
5062 if (envlist == NULL) {
5063 PyErr_NoMemory();
5064 return NULL;
5065 }
5066 envc = 0;
5067 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005068 if (!keys)
5069 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005071 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 goto error;
5073 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5074 PyErr_Format(PyExc_TypeError,
5075 "env.keys() or env.values() is not a list");
5076 goto error;
5077 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005078
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 for (pos = 0; pos < i; pos++) {
5080 key = PyList_GetItem(keys, pos);
5081 val = PyList_GetItem(vals, pos);
5082 if (!key || !val)
5083 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005084
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 if (PyUnicode_FSConverter(key, &key2) == 0)
5086 goto error;
5087 if (PyUnicode_FSConverter(val, &val2) == 0) {
5088 Py_DECREF(key2);
5089 goto error;
5090 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005091
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 k = PyBytes_AsString(key2);
5093 v = PyBytes_AsString(val2);
5094 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005095
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 p = PyMem_NEW(char, len);
5097 if (p == NULL) {
5098 PyErr_NoMemory();
5099 Py_DECREF(key2);
5100 Py_DECREF(val2);
5101 goto error;
5102 }
5103 PyOS_snprintf(p, len, "%s=%s", k, v);
5104 envlist[envc++] = p;
5105 Py_DECREF(key2);
5106 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 }
5108 Py_DECREF(vals);
5109 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 envlist[envc] = 0;
5112 *envc_ptr = envc;
5113 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005114
5115error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 Py_XDECREF(keys);
5117 Py_XDECREF(vals);
5118 while (--envc >= 0)
5119 PyMem_DEL(envlist[envc]);
5120 PyMem_DEL(envlist);
5121 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005122}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005123
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124static char**
5125parse_arglist(PyObject* argv, Py_ssize_t *argc)
5126{
5127 int i;
5128 char **argvlist = PyMem_NEW(char *, *argc+1);
5129 if (argvlist == NULL) {
5130 PyErr_NoMemory();
5131 return NULL;
5132 }
5133 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005134 PyObject* item = PySequence_ITEM(argv, i);
5135 if (item == NULL)
5136 goto fail;
5137 if (!fsconvert_strdup(item, &argvlist[i])) {
5138 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005139 goto fail;
5140 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005141 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 }
5143 argvlist[*argc] = NULL;
5144 return argvlist;
5145fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005146 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005147 free_string_array(argvlist, *argc);
5148 return NULL;
5149}
5150#endif
5151
5152#ifdef HAVE_EXECV
5153PyDoc_STRVAR(posix_execv__doc__,
5154"execv(path, args)\n\n\
5155Execute an executable path with arguments, replacing current process.\n\
5156\n\
5157 path: path of executable file\n\
5158 args: tuple or list of strings");
5159
5160static PyObject *
5161posix_execv(PyObject *self, PyObject *args)
5162{
5163 PyObject *opath;
5164 char *path;
5165 PyObject *argv;
5166 char **argvlist;
5167 Py_ssize_t argc;
5168
5169 /* execv has two arguments: (path, argv), where
5170 argv is a list or tuple of strings. */
5171
5172 if (!PyArg_ParseTuple(args, "O&O:execv",
5173 PyUnicode_FSConverter,
5174 &opath, &argv))
5175 return NULL;
5176 path = PyBytes_AsString(opath);
5177 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5178 PyErr_SetString(PyExc_TypeError,
5179 "execv() arg 2 must be a tuple or list");
5180 Py_DECREF(opath);
5181 return NULL;
5182 }
5183 argc = PySequence_Size(argv);
5184 if (argc < 1) {
5185 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5186 Py_DECREF(opath);
5187 return NULL;
5188 }
5189
5190 argvlist = parse_arglist(argv, &argc);
5191 if (argvlist == NULL) {
5192 Py_DECREF(opath);
5193 return NULL;
5194 }
5195
5196 execv(path, argvlist);
5197
5198 /* If we get here it's definitely an error */
5199
5200 free_string_array(argvlist, argc);
5201 Py_DECREF(opath);
5202 return posix_error();
5203}
5204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005205PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005206"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005207Execute a path with arguments and environment, replacing current process.\n\
5208\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 path: path of executable file\n\
5210 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005211 env: dictionary of strings mapping to strings\n\
5212\n\
5213On some platforms, you may specify an open file descriptor for path;\n\
5214 execve will execute the program the file descriptor is open to.\n\
5215 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005216
Barry Warsaw53699e91996-12-10 23:23:01 +00005217static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005218posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005219{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005220 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005222 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005224 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005225 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005226
Victor Stinner8c62be82010-05-06 00:08:46 +00005227 /* execve has three arguments: (path, argv, env), where
5228 argv is a list or tuple of strings and env is a dictionary
5229 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005230
Larry Hastings9cf065c2012-06-22 16:30:09 -07005231 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005232 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005233#ifdef HAVE_FEXECVE
5234 path.allow_fd = 1;
5235#endif
5236 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5237 path_converter, &path,
5238 &argv, &env
5239 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005241
Ross Lagerwall7807c352011-03-17 20:20:30 +02005242 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005244 "execve: argv must be a tuple or list");
5245 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005247 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 if (!PyMapping_Check(env)) {
5249 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005250 "execve: environment must be a mapping object");
5251 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005253
Ross Lagerwall7807c352011-03-17 20:20:30 +02005254 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005256 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005258
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 envlist = parse_envlist(env, &envc);
5260 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005261 goto fail;
5262
Larry Hastings9cf065c2012-06-22 16:30:09 -07005263#ifdef HAVE_FEXECVE
5264 if (path.fd > -1)
5265 fexecve(path.fd, argvlist, envlist);
5266 else
5267#endif
5268 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005269
5270 /* If we get here it's definitely an error */
5271
Victor Stinner292c8352012-10-30 02:17:38 +01005272 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005273
5274 while (--envc >= 0)
5275 PyMem_DEL(envlist[envc]);
5276 PyMem_DEL(envlist);
5277 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005278 if (argvlist)
5279 free_string_array(argvlist, argc);
5280 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005281 return NULL;
5282}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005283#endif /* HAVE_EXECV */
5284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005285
Guido van Rossuma1065681999-01-25 23:20:23 +00005286#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005287PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005288"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005289Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005290\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 mode: mode of process creation\n\
5292 path: path of executable file\n\
5293 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005294
5295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005296posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005297{
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 PyObject *opath;
5299 char *path;
5300 PyObject *argv;
5301 char **argvlist;
5302 int mode, i;
5303 Py_ssize_t argc;
5304 Py_intptr_t spawnval;
5305 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005306
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 /* spawnv has three arguments: (mode, path, argv), where
5308 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005309
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5311 PyUnicode_FSConverter,
5312 &opath, &argv))
5313 return NULL;
5314 path = PyBytes_AsString(opath);
5315 if (PyList_Check(argv)) {
5316 argc = PyList_Size(argv);
5317 getitem = PyList_GetItem;
5318 }
5319 else if (PyTuple_Check(argv)) {
5320 argc = PyTuple_Size(argv);
5321 getitem = PyTuple_GetItem;
5322 }
5323 else {
5324 PyErr_SetString(PyExc_TypeError,
5325 "spawnv() arg 2 must be a tuple or list");
5326 Py_DECREF(opath);
5327 return NULL;
5328 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005329
Victor Stinner8c62be82010-05-06 00:08:46 +00005330 argvlist = PyMem_NEW(char *, argc+1);
5331 if (argvlist == NULL) {
5332 Py_DECREF(opath);
5333 return PyErr_NoMemory();
5334 }
5335 for (i = 0; i < argc; i++) {
5336 if (!fsconvert_strdup((*getitem)(argv, i),
5337 &argvlist[i])) {
5338 free_string_array(argvlist, i);
5339 PyErr_SetString(
5340 PyExc_TypeError,
5341 "spawnv() arg 2 must contain only strings");
5342 Py_DECREF(opath);
5343 return NULL;
5344 }
5345 }
5346 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 if (mode == _OLD_P_OVERLAY)
5349 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005350
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 Py_BEGIN_ALLOW_THREADS
5352 spawnval = _spawnv(mode, path, argvlist);
5353 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005354
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 free_string_array(argvlist, argc);
5356 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 if (spawnval == -1)
5359 return posix_error();
5360 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005361 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005362}
5363
5364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005365PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005366"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005367Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005368\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005369 mode: mode of process creation\n\
5370 path: path of executable file\n\
5371 args: tuple or list of arguments\n\
5372 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005373
5374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005375posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005376{
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 PyObject *opath;
5378 char *path;
5379 PyObject *argv, *env;
5380 char **argvlist;
5381 char **envlist;
5382 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005383 int mode;
5384 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 Py_intptr_t spawnval;
5386 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5387 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005388
Victor Stinner8c62be82010-05-06 00:08:46 +00005389 /* spawnve has four arguments: (mode, path, argv, env), where
5390 argv is a list or tuple of strings and env is a dictionary
5391 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005392
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5394 PyUnicode_FSConverter,
5395 &opath, &argv, &env))
5396 return NULL;
5397 path = PyBytes_AsString(opath);
5398 if (PyList_Check(argv)) {
5399 argc = PyList_Size(argv);
5400 getitem = PyList_GetItem;
5401 }
5402 else if (PyTuple_Check(argv)) {
5403 argc = PyTuple_Size(argv);
5404 getitem = PyTuple_GetItem;
5405 }
5406 else {
5407 PyErr_SetString(PyExc_TypeError,
5408 "spawnve() arg 2 must be a tuple or list");
5409 goto fail_0;
5410 }
5411 if (!PyMapping_Check(env)) {
5412 PyErr_SetString(PyExc_TypeError,
5413 "spawnve() arg 3 must be a mapping object");
5414 goto fail_0;
5415 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005416
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 argvlist = PyMem_NEW(char *, argc+1);
5418 if (argvlist == NULL) {
5419 PyErr_NoMemory();
5420 goto fail_0;
5421 }
5422 for (i = 0; i < argc; i++) {
5423 if (!fsconvert_strdup((*getitem)(argv, i),
5424 &argvlist[i]))
5425 {
5426 lastarg = i;
5427 goto fail_1;
5428 }
5429 }
5430 lastarg = argc;
5431 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005432
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 envlist = parse_envlist(env, &envc);
5434 if (envlist == NULL)
5435 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005436
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 if (mode == _OLD_P_OVERLAY)
5438 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005439
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 Py_BEGIN_ALLOW_THREADS
5441 spawnval = _spawnve(mode, path, argvlist, envlist);
5442 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005443
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 if (spawnval == -1)
5445 (void) posix_error();
5446 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005447 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005448
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 while (--envc >= 0)
5450 PyMem_DEL(envlist[envc]);
5451 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005452 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005454 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 Py_DECREF(opath);
5456 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005457}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005458
Guido van Rossuma1065681999-01-25 23:20:23 +00005459#endif /* HAVE_SPAWNV */
5460
5461
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005462#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005463PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005464"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005465Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5466\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005468
5469static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005470posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005471{
Victor Stinner8c62be82010-05-06 00:08:46 +00005472 pid_t pid;
5473 int result = 0;
5474 _PyImport_AcquireLock();
5475 pid = fork1();
5476 if (pid == 0) {
5477 /* child: this clobbers and resets the import lock. */
5478 PyOS_AfterFork();
5479 } else {
5480 /* parent: release the import lock. */
5481 result = _PyImport_ReleaseLock();
5482 }
5483 if (pid == -1)
5484 return posix_error();
5485 if (result < 0) {
5486 /* Don't clobber the OSError if the fork failed. */
5487 PyErr_SetString(PyExc_RuntimeError,
5488 "not holding the import lock");
5489 return NULL;
5490 }
5491 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005492}
5493#endif
5494
5495
Guido van Rossumad0ee831995-03-01 10:34:45 +00005496#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005498"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005499Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005501
Barry Warsaw53699e91996-12-10 23:23:01 +00005502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005503posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005504{
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 pid_t pid;
5506 int result = 0;
5507 _PyImport_AcquireLock();
5508 pid = fork();
5509 if (pid == 0) {
5510 /* child: this clobbers and resets the import lock. */
5511 PyOS_AfterFork();
5512 } else {
5513 /* parent: release the import lock. */
5514 result = _PyImport_ReleaseLock();
5515 }
5516 if (pid == -1)
5517 return posix_error();
5518 if (result < 0) {
5519 /* Don't clobber the OSError if the fork failed. */
5520 PyErr_SetString(PyExc_RuntimeError,
5521 "not holding the import lock");
5522 return NULL;
5523 }
5524 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005525}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005526#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005527
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005528#ifdef HAVE_SCHED_H
5529
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005530#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5531
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005532PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5533"sched_get_priority_max(policy)\n\n\
5534Get the maximum scheduling priority for *policy*.");
5535
5536static PyObject *
5537posix_sched_get_priority_max(PyObject *self, PyObject *args)
5538{
5539 int policy, max;
5540
5541 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5542 return NULL;
5543 max = sched_get_priority_max(policy);
5544 if (max < 0)
5545 return posix_error();
5546 return PyLong_FromLong(max);
5547}
5548
5549PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5550"sched_get_priority_min(policy)\n\n\
5551Get the minimum scheduling priority for *policy*.");
5552
5553static PyObject *
5554posix_sched_get_priority_min(PyObject *self, PyObject *args)
5555{
5556 int policy, min;
5557
5558 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5559 return NULL;
5560 min = sched_get_priority_min(policy);
5561 if (min < 0)
5562 return posix_error();
5563 return PyLong_FromLong(min);
5564}
5565
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005566#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5567
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005568#ifdef HAVE_SCHED_SETSCHEDULER
5569
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005570PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5571"sched_getscheduler(pid)\n\n\
5572Get the scheduling policy for the process with a PID of *pid*.\n\
5573Passing a PID of 0 returns the scheduling policy for the calling process.");
5574
5575static PyObject *
5576posix_sched_getscheduler(PyObject *self, PyObject *args)
5577{
5578 pid_t pid;
5579 int policy;
5580
5581 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5582 return NULL;
5583 policy = sched_getscheduler(pid);
5584 if (policy < 0)
5585 return posix_error();
5586 return PyLong_FromLong(policy);
5587}
5588
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005589#endif
5590
5591#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5592
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005593static PyObject *
5594sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5595{
5596 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005597 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005598
5599 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5600 return NULL;
5601 res = PyStructSequence_New(type);
5602 if (!res)
5603 return NULL;
5604 Py_INCREF(priority);
5605 PyStructSequence_SET_ITEM(res, 0, priority);
5606 return res;
5607}
5608
5609PyDoc_STRVAR(sched_param__doc__,
5610"sched_param(sched_priority): A scheduling parameter.\n\n\
5611Current has only one field: sched_priority");
5612
5613static PyStructSequence_Field sched_param_fields[] = {
5614 {"sched_priority", "the scheduling priority"},
5615 {0}
5616};
5617
5618static PyStructSequence_Desc sched_param_desc = {
5619 "sched_param", /* name */
5620 sched_param__doc__, /* doc */
5621 sched_param_fields,
5622 1
5623};
5624
5625static int
5626convert_sched_param(PyObject *param, struct sched_param *res)
5627{
5628 long priority;
5629
5630 if (Py_TYPE(param) != &SchedParamType) {
5631 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5632 return 0;
5633 }
5634 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5635 if (priority == -1 && PyErr_Occurred())
5636 return 0;
5637 if (priority > INT_MAX || priority < INT_MIN) {
5638 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5639 return 0;
5640 }
5641 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5642 return 1;
5643}
5644
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005645#endif
5646
5647#ifdef HAVE_SCHED_SETSCHEDULER
5648
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005649PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5650"sched_setscheduler(pid, policy, param)\n\n\
5651Set the scheduling policy, *policy*, for *pid*.\n\
5652If *pid* is 0, the calling process is changed.\n\
5653*param* is an instance of sched_param.");
5654
5655static PyObject *
5656posix_sched_setscheduler(PyObject *self, PyObject *args)
5657{
5658 pid_t pid;
5659 int policy;
5660 struct sched_param param;
5661
5662 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5663 &pid, &policy, &convert_sched_param, &param))
5664 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005665
5666 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005667 ** sched_setscheduler() returns 0 in Linux, but the previous
5668 ** scheduling policy under Solaris/Illumos, and others.
5669 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005670 */
5671 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005672 return posix_error();
5673 Py_RETURN_NONE;
5674}
5675
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005676#endif
5677
5678#ifdef HAVE_SCHED_SETPARAM
5679
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680PyDoc_STRVAR(posix_sched_getparam__doc__,
5681"sched_getparam(pid) -> sched_param\n\n\
5682Returns scheduling parameters for the process with *pid* as an instance of the\n\
5683sched_param class. A PID of 0 means the calling process.");
5684
5685static PyObject *
5686posix_sched_getparam(PyObject *self, PyObject *args)
5687{
5688 pid_t pid;
5689 struct sched_param param;
5690 PyObject *res, *priority;
5691
5692 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5693 return NULL;
5694 if (sched_getparam(pid, &param))
5695 return posix_error();
5696 res = PyStructSequence_New(&SchedParamType);
5697 if (!res)
5698 return NULL;
5699 priority = PyLong_FromLong(param.sched_priority);
5700 if (!priority) {
5701 Py_DECREF(res);
5702 return NULL;
5703 }
5704 PyStructSequence_SET_ITEM(res, 0, priority);
5705 return res;
5706}
5707
5708PyDoc_STRVAR(posix_sched_setparam__doc__,
5709"sched_setparam(pid, param)\n\n\
5710Set scheduling parameters for a process with PID *pid*.\n\
5711A PID of 0 means the calling process.");
5712
5713static PyObject *
5714posix_sched_setparam(PyObject *self, PyObject *args)
5715{
5716 pid_t pid;
5717 struct sched_param param;
5718
5719 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5720 &pid, &convert_sched_param, &param))
5721 return NULL;
5722 if (sched_setparam(pid, &param))
5723 return posix_error();
5724 Py_RETURN_NONE;
5725}
5726
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005727#endif
5728
5729#ifdef HAVE_SCHED_RR_GET_INTERVAL
5730
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005731PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5732"sched_rr_get_interval(pid) -> float\n\n\
5733Return the round-robin quantum for the process with PID *pid* in seconds.");
5734
5735static PyObject *
5736posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5737{
5738 pid_t pid;
5739 struct timespec interval;
5740
5741 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5742 return NULL;
5743 if (sched_rr_get_interval(pid, &interval))
5744 return posix_error();
5745 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5746}
5747
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005748#endif
5749
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005750PyDoc_STRVAR(posix_sched_yield__doc__,
5751"sched_yield()\n\n\
5752Voluntarily relinquish the CPU.");
5753
5754static PyObject *
5755posix_sched_yield(PyObject *self, PyObject *noargs)
5756{
5757 if (sched_yield())
5758 return posix_error();
5759 Py_RETURN_NONE;
5760}
5761
Benjamin Peterson2740af82011-08-02 17:41:34 -05005762#ifdef HAVE_SCHED_SETAFFINITY
5763
Antoine Pitrou84869872012-08-04 16:16:35 +02005764/* The minimum number of CPUs allocated in a cpu_set_t */
5765static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005766
5767PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5768"sched_setaffinity(pid, cpu_set)\n\n\
5769Set the affinity of the process with PID *pid* to *cpu_set*.");
5770
5771static PyObject *
5772posix_sched_setaffinity(PyObject *self, PyObject *args)
5773{
5774 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005775 int ncpus;
5776 size_t setsize;
5777 cpu_set_t *mask = NULL;
5778 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005779
Antoine Pitrou84869872012-08-04 16:16:35 +02005780 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5781 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005782 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005783
5784 iterator = PyObject_GetIter(iterable);
5785 if (iterator == NULL)
5786 return NULL;
5787
5788 ncpus = NCPUS_START;
5789 setsize = CPU_ALLOC_SIZE(ncpus);
5790 mask = CPU_ALLOC(ncpus);
5791 if (mask == NULL) {
5792 PyErr_NoMemory();
5793 goto error;
5794 }
5795 CPU_ZERO_S(setsize, mask);
5796
5797 while ((item = PyIter_Next(iterator))) {
5798 long cpu;
5799 if (!PyLong_Check(item)) {
5800 PyErr_Format(PyExc_TypeError,
5801 "expected an iterator of ints, "
5802 "but iterator yielded %R",
5803 Py_TYPE(item));
5804 Py_DECREF(item);
5805 goto error;
5806 }
5807 cpu = PyLong_AsLong(item);
5808 Py_DECREF(item);
5809 if (cpu < 0) {
5810 if (!PyErr_Occurred())
5811 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5812 goto error;
5813 }
5814 if (cpu > INT_MAX - 1) {
5815 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5816 goto error;
5817 }
5818 if (cpu >= ncpus) {
5819 /* Grow CPU mask to fit the CPU number */
5820 int newncpus = ncpus;
5821 cpu_set_t *newmask;
5822 size_t newsetsize;
5823 while (newncpus <= cpu) {
5824 if (newncpus > INT_MAX / 2)
5825 newncpus = cpu + 1;
5826 else
5827 newncpus = newncpus * 2;
5828 }
5829 newmask = CPU_ALLOC(newncpus);
5830 if (newmask == NULL) {
5831 PyErr_NoMemory();
5832 goto error;
5833 }
5834 newsetsize = CPU_ALLOC_SIZE(newncpus);
5835 CPU_ZERO_S(newsetsize, newmask);
5836 memcpy(newmask, mask, setsize);
5837 CPU_FREE(mask);
5838 setsize = newsetsize;
5839 mask = newmask;
5840 ncpus = newncpus;
5841 }
5842 CPU_SET_S(cpu, setsize, mask);
5843 }
5844 Py_CLEAR(iterator);
5845
5846 if (sched_setaffinity(pid, setsize, mask)) {
5847 posix_error();
5848 goto error;
5849 }
5850 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005851 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005852
5853error:
5854 if (mask)
5855 CPU_FREE(mask);
5856 Py_XDECREF(iterator);
5857 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005858}
5859
5860PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5861"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5862Return the affinity of the process with PID *pid*.\n\
5863The returned cpu_set will be of size *ncpus*.");
5864
5865static PyObject *
5866posix_sched_getaffinity(PyObject *self, PyObject *args)
5867{
5868 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005869 int cpu, ncpus, count;
5870 size_t setsize;
5871 cpu_set_t *mask = NULL;
5872 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005873
Antoine Pitrou84869872012-08-04 16:16:35 +02005874 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5875 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005876 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005877
5878 ncpus = NCPUS_START;
5879 while (1) {
5880 setsize = CPU_ALLOC_SIZE(ncpus);
5881 mask = CPU_ALLOC(ncpus);
5882 if (mask == NULL)
5883 return PyErr_NoMemory();
5884 if (sched_getaffinity(pid, setsize, mask) == 0)
5885 break;
5886 CPU_FREE(mask);
5887 if (errno != EINVAL)
5888 return posix_error();
5889 if (ncpus > INT_MAX / 2) {
5890 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5891 "a large enough CPU set");
5892 return NULL;
5893 }
5894 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005895 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005896
5897 res = PySet_New(NULL);
5898 if (res == NULL)
5899 goto error;
5900 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5901 if (CPU_ISSET_S(cpu, setsize, mask)) {
5902 PyObject *cpu_num = PyLong_FromLong(cpu);
5903 --count;
5904 if (cpu_num == NULL)
5905 goto error;
5906 if (PySet_Add(res, cpu_num)) {
5907 Py_DECREF(cpu_num);
5908 goto error;
5909 }
5910 Py_DECREF(cpu_num);
5911 }
5912 }
5913 CPU_FREE(mask);
5914 return res;
5915
5916error:
5917 if (mask)
5918 CPU_FREE(mask);
5919 Py_XDECREF(res);
5920 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005921}
5922
Benjamin Peterson2740af82011-08-02 17:41:34 -05005923#endif /* HAVE_SCHED_SETAFFINITY */
5924
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005925#endif /* HAVE_SCHED_H */
5926
Neal Norwitzb59798b2003-03-21 01:43:31 +00005927/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005928/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5929#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005930#define DEV_PTY_FILE "/dev/ptc"
5931#define HAVE_DEV_PTMX
5932#else
5933#define DEV_PTY_FILE "/dev/ptmx"
5934#endif
5935
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005937#ifdef HAVE_PTY_H
5938#include <pty.h>
5939#else
5940#ifdef HAVE_LIBUTIL_H
5941#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005942#else
5943#ifdef HAVE_UTIL_H
5944#include <util.h>
5945#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005946#endif /* HAVE_LIBUTIL_H */
5947#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005948#ifdef HAVE_STROPTS_H
5949#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005950#endif
5951#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005953#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005955"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005957
5958static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005959posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005960{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005961 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005962#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005965#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005967#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005969#endif
5970#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005971
Thomas Wouters70c21a12000-07-14 14:28:33 +00005972#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005974 goto posix_error;
5975
5976 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5977 goto error;
5978 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5979 goto error;
5980
Neal Norwitzb59798b2003-03-21 01:43:31 +00005981#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5983 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984 goto posix_error;
5985 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5986 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005987
Victor Stinnerdaf45552013-08-28 00:53:59 +02005988 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005990 goto posix_error;
5991
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005992#else
Victor Stinner000de532013-11-25 23:19:58 +01005993 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005995 goto posix_error;
5996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005998
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 /* change permission of slave */
6000 if (grantpt(master_fd) < 0) {
6001 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006002 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006004
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 /* unlock slave */
6006 if (unlockpt(master_fd) < 0) {
6007 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006010
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006012
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 slave_name = ptsname(master_fd); /* get name of slave */
6014 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006015 goto posix_error;
6016
6017 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006019 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006020
6021 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6022 goto posix_error;
6023
Neal Norwitzb59798b2003-03-21 01:43:31 +00006024#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6026 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006027#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006029#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006030#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006031#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006032
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006034
Victor Stinnerdaf45552013-08-28 00:53:59 +02006035posix_error:
6036 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006037#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006038error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006039#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006040 if (master_fd != -1)
6041 close(master_fd);
6042 if (slave_fd != -1)
6043 close(slave_fd);
6044 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006045}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006046#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006047
6048#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006051Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6052Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006054
6055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006056posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006057{
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 int master_fd = -1, result = 0;
6059 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006060
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 _PyImport_AcquireLock();
6062 pid = forkpty(&master_fd, NULL, NULL, NULL);
6063 if (pid == 0) {
6064 /* child: this clobbers and resets the import lock. */
6065 PyOS_AfterFork();
6066 } else {
6067 /* parent: release the import lock. */
6068 result = _PyImport_ReleaseLock();
6069 }
6070 if (pid == -1)
6071 return posix_error();
6072 if (result < 0) {
6073 /* Don't clobber the OSError if the fork failed. */
6074 PyErr_SetString(PyExc_RuntimeError,
6075 "not holding the import lock");
6076 return NULL;
6077 }
6078 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006079}
6080#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006081
Ross Lagerwall7807c352011-03-17 20:20:30 +02006082
Guido van Rossumad0ee831995-03-01 10:34:45 +00006083#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006085"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006086Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006087
Barry Warsaw53699e91996-12-10 23:23:01 +00006088static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006089posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006090{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006091 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006092}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006093#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Guido van Rossumad0ee831995-03-01 10:34:45 +00006096#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006100
Barry Warsaw53699e91996-12-10 23:23:01 +00006101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006102posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006103{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006104 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006105}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006106#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006107
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Guido van Rossumad0ee831995-03-01 10:34:45 +00006109#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006111"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006112Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006113
Barry Warsaw53699e91996-12-10 23:23:01 +00006114static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006115posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006116{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006117 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006118}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006119#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006123"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006125
Barry Warsaw53699e91996-12-10 23:23:01 +00006126static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006127posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006128{
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006130}
6131
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006132#ifdef HAVE_GETGROUPLIST
6133PyDoc_STRVAR(posix_getgrouplist__doc__,
6134"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6135Returns a list of groups to which a user belongs.\n\n\
6136 user: username to lookup\n\
6137 group: base group id of the user");
6138
6139static PyObject *
6140posix_getgrouplist(PyObject *self, PyObject *args)
6141{
6142#ifdef NGROUPS_MAX
6143#define MAX_GROUPS NGROUPS_MAX
6144#else
6145 /* defined to be 16 on Solaris7, so this should be a small number */
6146#define MAX_GROUPS 64
6147#endif
6148
6149 const char *user;
6150 int i, ngroups;
6151 PyObject *list;
6152#ifdef __APPLE__
6153 int *groups, basegid;
6154#else
6155 gid_t *groups, basegid;
6156#endif
6157 ngroups = MAX_GROUPS;
6158
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006159#ifdef __APPLE__
6160 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006161 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006162#else
6163 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6164 _Py_Gid_Converter, &basegid))
6165 return NULL;
6166#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006167
6168#ifdef __APPLE__
6169 groups = PyMem_Malloc(ngroups * sizeof(int));
6170#else
6171 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6172#endif
6173 if (groups == NULL)
6174 return PyErr_NoMemory();
6175
6176 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6177 PyMem_Del(groups);
6178 return posix_error();
6179 }
6180
6181 list = PyList_New(ngroups);
6182 if (list == NULL) {
6183 PyMem_Del(groups);
6184 return NULL;
6185 }
6186
6187 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006188#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006189 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006190#else
6191 PyObject *o = _PyLong_FromGid(groups[i]);
6192#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006193 if (o == NULL) {
6194 Py_DECREF(list);
6195 PyMem_Del(groups);
6196 return NULL;
6197 }
6198 PyList_SET_ITEM(list, i, o);
6199 }
6200
6201 PyMem_Del(groups);
6202
6203 return list;
6204}
6205#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006206
Fred Drakec9680921999-12-13 16:37:25 +00006207#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006209"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006211
6212static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006213posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006214{
6215 PyObject *result = NULL;
6216
Fred Drakec9680921999-12-13 16:37:25 +00006217#ifdef NGROUPS_MAX
6218#define MAX_GROUPS NGROUPS_MAX
6219#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006221#define MAX_GROUPS 64
6222#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006224
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006225 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006226 * This is a helper variable to store the intermediate result when
6227 * that happens.
6228 *
6229 * To keep the code readable the OSX behaviour is unconditional,
6230 * according to the POSIX spec this should be safe on all unix-y
6231 * systems.
6232 */
6233 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006235
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006236#ifdef __APPLE__
6237 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6238 * there are more groups than can fit in grouplist. Therefore, on OS X
6239 * always first call getgroups with length 0 to get the actual number
6240 * of groups.
6241 */
6242 n = getgroups(0, NULL);
6243 if (n < 0) {
6244 return posix_error();
6245 } else if (n <= MAX_GROUPS) {
6246 /* groups will fit in existing array */
6247 alt_grouplist = grouplist;
6248 } else {
6249 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6250 if (alt_grouplist == NULL) {
6251 errno = EINVAL;
6252 return posix_error();
6253 }
6254 }
6255
6256 n = getgroups(n, alt_grouplist);
6257 if (n == -1) {
6258 if (alt_grouplist != grouplist) {
6259 PyMem_Free(alt_grouplist);
6260 }
6261 return posix_error();
6262 }
6263#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006265 if (n < 0) {
6266 if (errno == EINVAL) {
6267 n = getgroups(0, NULL);
6268 if (n == -1) {
6269 return posix_error();
6270 }
6271 if (n == 0) {
6272 /* Avoid malloc(0) */
6273 alt_grouplist = grouplist;
6274 } else {
6275 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6276 if (alt_grouplist == NULL) {
6277 errno = EINVAL;
6278 return posix_error();
6279 }
6280 n = getgroups(n, alt_grouplist);
6281 if (n == -1) {
6282 PyMem_Free(alt_grouplist);
6283 return posix_error();
6284 }
6285 }
6286 } else {
6287 return posix_error();
6288 }
6289 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006290#endif
6291
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292 result = PyList_New(n);
6293 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 int i;
6295 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006296 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006298 Py_DECREF(result);
6299 result = NULL;
6300 break;
Fred Drakec9680921999-12-13 16:37:25 +00006301 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006303 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006304 }
6305
6306 if (alt_grouplist != grouplist) {
6307 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006309
Fred Drakec9680921999-12-13 16:37:25 +00006310 return result;
6311}
6312#endif
6313
Antoine Pitroub7572f02009-12-02 20:46:48 +00006314#ifdef HAVE_INITGROUPS
6315PyDoc_STRVAR(posix_initgroups__doc__,
6316"initgroups(username, gid) -> None\n\n\
6317Call the system initgroups() to initialize the group access list with all of\n\
6318the groups of which the specified username is a member, plus the specified\n\
6319group id.");
6320
6321static PyObject *
6322posix_initgroups(PyObject *self, PyObject *args)
6323{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006324 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006326 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006327#ifdef __APPLE__
6328 int gid;
6329#else
6330 gid_t gid;
6331#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006332
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006333#ifdef __APPLE__
6334 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6335 PyUnicode_FSConverter, &oname,
6336 &gid))
6337#else
6338 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6339 PyUnicode_FSConverter, &oname,
6340 _Py_Gid_Converter, &gid))
6341#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006343 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006344
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006345 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006346 Py_DECREF(oname);
6347 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006349
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 Py_INCREF(Py_None);
6351 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006352}
6353#endif
6354
Martin v. Löwis606edc12002-06-13 21:09:11 +00006355#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006356PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006357"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006358Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006359
6360static PyObject *
6361posix_getpgid(PyObject *self, PyObject *args)
6362{
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 pid_t pid, pgid;
6364 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6365 return NULL;
6366 pgid = getpgid(pid);
6367 if (pgid < 0)
6368 return posix_error();
6369 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006370}
6371#endif /* HAVE_GETPGID */
6372
6373
Guido van Rossumb6775db1994-08-01 11:34:53 +00006374#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Barry Warsaw53699e91996-12-10 23:23:01 +00006379static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006380posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006381{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006384#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006386#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006387}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006388#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006390
Guido van Rossumb6775db1994-08-01 11:34:53 +00006391#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006392PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006393"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006394Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006395
Barry Warsaw53699e91996-12-10 23:23:01 +00006396static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006397posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006398{
Guido van Rossum64933891994-10-20 21:56:42 +00006399#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006401#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006403#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 return posix_error();
6405 Py_INCREF(Py_None);
6406 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006407}
6408
Guido van Rossumb6775db1994-08-01 11:34:53 +00006409#endif /* HAVE_SETPGRP */
6410
Guido van Rossumad0ee831995-03-01 10:34:45 +00006411#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006412
6413#ifdef MS_WINDOWS
6414#include <tlhelp32.h>
6415
6416static PyObject*
6417win32_getppid()
6418{
6419 HANDLE snapshot;
6420 pid_t mypid;
6421 PyObject* result = NULL;
6422 BOOL have_record;
6423 PROCESSENTRY32 pe;
6424
6425 mypid = getpid(); /* This function never fails */
6426
6427 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6428 if (snapshot == INVALID_HANDLE_VALUE)
6429 return PyErr_SetFromWindowsErr(GetLastError());
6430
6431 pe.dwSize = sizeof(pe);
6432 have_record = Process32First(snapshot, &pe);
6433 while (have_record) {
6434 if (mypid == (pid_t)pe.th32ProcessID) {
6435 /* We could cache the ulong value in a static variable. */
6436 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6437 break;
6438 }
6439
6440 have_record = Process32Next(snapshot, &pe);
6441 }
6442
6443 /* If our loop exits and our pid was not found (result will be NULL)
6444 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6445 * error anyway, so let's raise it. */
6446 if (!result)
6447 result = PyErr_SetFromWindowsErr(GetLastError());
6448
6449 CloseHandle(snapshot);
6450
6451 return result;
6452}
6453#endif /*MS_WINDOWS*/
6454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006456"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457Return the parent's process id. If the parent process has already exited,\n\
6458Windows machines will still return its id; others systems will return the id\n\
6459of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Barry Warsaw53699e91996-12-10 23:23:01 +00006461static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006462posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006463{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006464#ifdef MS_WINDOWS
6465 return win32_getppid();
6466#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006468#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006469}
6470#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006474PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006475"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006476Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006477
6478static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006479posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006480{
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006482#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006483 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006484 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006485
6486 if (GetUserNameW(user_name, &num_chars)) {
6487 /* num_chars is the number of unicode chars plus null terminator */
6488 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006489 }
6490 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006491 result = PyErr_SetFromWindowsErr(GetLastError());
6492#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006493 char *name;
6494 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006495
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 errno = 0;
6497 name = getlogin();
6498 if (name == NULL) {
6499 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006500 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006501 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006502 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 }
6504 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006505 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006507#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006508 return result;
6509}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006510#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006511
Guido van Rossumad0ee831995-03-01 10:34:45 +00006512#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006513PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006514"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Barry Warsaw53699e91996-12-10 23:23:01 +00006517static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006518posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006519{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006520 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006521}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006522#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Guido van Rossumad0ee831995-03-01 10:34:45 +00006525#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006527"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006529
Barry Warsaw53699e91996-12-10 23:23:01 +00006530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006531posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006532{
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 pid_t pid;
6534 int sig;
6535 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6536 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 if (kill(pid, sig) == -1)
6538 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 Py_INCREF(Py_None);
6540 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006541}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006542#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006543
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006544#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006546"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006548
6549static PyObject *
6550posix_killpg(PyObject *self, PyObject *args)
6551{
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 int sig;
6553 pid_t pgid;
6554 /* XXX some man pages make the `pgid` parameter an int, others
6555 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6556 take the same type. Moreover, pid_t is always at least as wide as
6557 int (else compilation of this module fails), which is safe. */
6558 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6559 return NULL;
6560 if (killpg(pgid, sig) == -1)
6561 return posix_error();
6562 Py_INCREF(Py_None);
6563 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006564}
6565#endif
6566
Brian Curtineb24d742010-04-12 17:16:38 +00006567#ifdef MS_WINDOWS
6568PyDoc_STRVAR(win32_kill__doc__,
6569"kill(pid, sig)\n\n\
6570Kill a process with a signal.");
6571
6572static PyObject *
6573win32_kill(PyObject *self, PyObject *args)
6574{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006575 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006576 pid_t pid;
6577 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006579
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006580 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006582
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 /* Console processes which share a common console can be sent CTRL+C or
6584 CTRL+BREAK events, provided they handle said events. */
6585 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006586 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 err = GetLastError();
6588 PyErr_SetFromWindowsErr(err);
6589 }
6590 else
6591 Py_RETURN_NONE;
6592 }
Brian Curtineb24d742010-04-12 17:16:38 +00006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6595 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006596 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 if (handle == NULL) {
6598 err = GetLastError();
6599 return PyErr_SetFromWindowsErr(err);
6600 }
Brian Curtineb24d742010-04-12 17:16:38 +00006601
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 if (TerminateProcess(handle, sig) == 0) {
6603 err = GetLastError();
6604 result = PyErr_SetFromWindowsErr(err);
6605 } else {
6606 Py_INCREF(Py_None);
6607 result = Py_None;
6608 }
Brian Curtineb24d742010-04-12 17:16:38 +00006609
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 CloseHandle(handle);
6611 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006612}
6613#endif /* MS_WINDOWS */
6614
Guido van Rossumc0125471996-06-28 18:55:32 +00006615#ifdef HAVE_PLOCK
6616
6617#ifdef HAVE_SYS_LOCK_H
6618#include <sys/lock.h>
6619#endif
6620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006622"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006624
Barry Warsaw53699e91996-12-10 23:23:01 +00006625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006626posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006627{
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 int op;
6629 if (!PyArg_ParseTuple(args, "i:plock", &op))
6630 return NULL;
6631 if (plock(op) == -1)
6632 return posix_error();
6633 Py_INCREF(Py_None);
6634 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006635}
6636#endif
6637
Guido van Rossumb6775db1994-08-01 11:34:53 +00006638#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006640"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641Set the current process's user id.");
6642
Barry Warsaw53699e91996-12-10 23:23:01 +00006643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006644posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006645{
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006647 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (setuid(uid) < 0)
6650 return posix_error();
6651 Py_INCREF(Py_None);
6652 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006653}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006654#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006655
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006656
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006657#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006659"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660Set the current process's effective user id.");
6661
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006662static PyObject *
6663posix_seteuid (PyObject *self, PyObject *args)
6664{
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006666 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 if (seteuid(euid) < 0) {
6669 return posix_error();
6670 } else {
6671 Py_INCREF(Py_None);
6672 return Py_None;
6673 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006674}
6675#endif /* HAVE_SETEUID */
6676
6677#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006679"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680Set the current process's effective group id.");
6681
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006682static PyObject *
6683posix_setegid (PyObject *self, PyObject *args)
6684{
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006686 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 if (setegid(egid) < 0) {
6689 return posix_error();
6690 } else {
6691 Py_INCREF(Py_None);
6692 return Py_None;
6693 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006694}
6695#endif /* HAVE_SETEGID */
6696
6697#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006699"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700Set the current process's real and effective user ids.");
6701
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006702static PyObject *
6703posix_setreuid (PyObject *self, PyObject *args)
6704{
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006706 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6707 _Py_Uid_Converter, &ruid,
6708 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 if (setreuid(ruid, euid) < 0) {
6711 return posix_error();
6712 } else {
6713 Py_INCREF(Py_None);
6714 return Py_None;
6715 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006716}
6717#endif /* HAVE_SETREUID */
6718
6719#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006721"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722Set the current process's real and effective group ids.");
6723
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006724static PyObject *
6725posix_setregid (PyObject *self, PyObject *args)
6726{
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006728 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6729 _Py_Gid_Converter, &rgid,
6730 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 if (setregid(rgid, egid) < 0) {
6733 return posix_error();
6734 } else {
6735 Py_INCREF(Py_None);
6736 return Py_None;
6737 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006738}
6739#endif /* HAVE_SETREGID */
6740
Guido van Rossumb6775db1994-08-01 11:34:53 +00006741#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006742PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006743"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006744Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006745
Barry Warsaw53699e91996-12-10 23:23:01 +00006746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006747posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006748{
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006750 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 if (setgid(gid) < 0)
6753 return posix_error();
6754 Py_INCREF(Py_None);
6755 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006756}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006757#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006758
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006759#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006761"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006762Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006763
6764static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006765posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006766{
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 int i, len;
6768 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006769
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 if (!PySequence_Check(groups)) {
6771 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6772 return NULL;
6773 }
6774 len = PySequence_Size(groups);
6775 if (len > MAX_GROUPS) {
6776 PyErr_SetString(PyExc_ValueError, "too many groups");
6777 return NULL;
6778 }
6779 for(i = 0; i < len; i++) {
6780 PyObject *elem;
6781 elem = PySequence_GetItem(groups, i);
6782 if (!elem)
6783 return NULL;
6784 if (!PyLong_Check(elem)) {
6785 PyErr_SetString(PyExc_TypeError,
6786 "groups must be integers");
6787 Py_DECREF(elem);
6788 return NULL;
6789 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006790 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 Py_DECREF(elem);
6792 return NULL;
6793 }
6794 }
6795 Py_DECREF(elem);
6796 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006797
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 if (setgroups(len, grouplist) < 0)
6799 return posix_error();
6800 Py_INCREF(Py_None);
6801 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006802}
6803#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006804
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006805#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6806static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006807wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808{
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 PyObject *result;
6810 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006811 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 if (pid == -1)
6814 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 if (struct_rusage == NULL) {
6817 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6818 if (m == NULL)
6819 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006820 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 Py_DECREF(m);
6822 if (struct_rusage == NULL)
6823 return NULL;
6824 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6827 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6828 if (!result)
6829 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830
6831#ifndef doubletime
6832#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6833#endif
6834
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006836 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006838 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6841 SET_INT(result, 2, ru->ru_maxrss);
6842 SET_INT(result, 3, ru->ru_ixrss);
6843 SET_INT(result, 4, ru->ru_idrss);
6844 SET_INT(result, 5, ru->ru_isrss);
6845 SET_INT(result, 6, ru->ru_minflt);
6846 SET_INT(result, 7, ru->ru_majflt);
6847 SET_INT(result, 8, ru->ru_nswap);
6848 SET_INT(result, 9, ru->ru_inblock);
6849 SET_INT(result, 10, ru->ru_oublock);
6850 SET_INT(result, 11, ru->ru_msgsnd);
6851 SET_INT(result, 12, ru->ru_msgrcv);
6852 SET_INT(result, 13, ru->ru_nsignals);
6853 SET_INT(result, 14, ru->ru_nvcsw);
6854 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855#undef SET_INT
6856
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 if (PyErr_Occurred()) {
6858 Py_DECREF(result);
6859 return NULL;
6860 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006861
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863}
6864#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6865
6866#ifdef HAVE_WAIT3
6867PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006868"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869Wait for completion of a child process.");
6870
6871static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006872posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873{
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 pid_t pid;
6875 int options;
6876 struct rusage ru;
6877 WAIT_TYPE status;
6878 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879
Victor Stinner4195b5c2012-02-08 23:03:19 +01006880 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 Py_BEGIN_ALLOW_THREADS
6884 pid = wait3(&status, options, &ru);
6885 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner4195b5c2012-02-08 23:03:19 +01006887 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888}
6889#endif /* HAVE_WAIT3 */
6890
6891#ifdef HAVE_WAIT4
6892PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006893"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894Wait for completion of a given child process.");
6895
6896static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006897posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006898{
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 pid_t pid;
6900 int options;
6901 struct rusage ru;
6902 WAIT_TYPE status;
6903 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006904
Victor Stinner4195b5c2012-02-08 23:03:19 +01006905 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 Py_BEGIN_ALLOW_THREADS
6909 pid = wait4(pid, &status, options, &ru);
6910 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911
Victor Stinner4195b5c2012-02-08 23:03:19 +01006912 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913}
6914#endif /* HAVE_WAIT4 */
6915
Ross Lagerwall7807c352011-03-17 20:20:30 +02006916#if defined(HAVE_WAITID) && !defined(__APPLE__)
6917PyDoc_STRVAR(posix_waitid__doc__,
6918"waitid(idtype, id, options) -> waitid_result\n\n\
6919Wait for the completion of one or more child processes.\n\n\
6920idtype can be P_PID, P_PGID or P_ALL.\n\
6921id specifies the pid to wait on.\n\
6922options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6923or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6924Returns either waitid_result or None if WNOHANG is specified and there are\n\
6925no children in a waitable state.");
6926
6927static PyObject *
6928posix_waitid(PyObject *self, PyObject *args)
6929{
6930 PyObject *result;
6931 idtype_t idtype;
6932 id_t id;
6933 int options, res;
6934 siginfo_t si;
6935 si.si_pid = 0;
6936 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6937 return NULL;
6938 Py_BEGIN_ALLOW_THREADS
6939 res = waitid(idtype, id, &si, options);
6940 Py_END_ALLOW_THREADS
6941 if (res == -1)
6942 return posix_error();
6943
6944 if (si.si_pid == 0)
6945 Py_RETURN_NONE;
6946
6947 result = PyStructSequence_New(&WaitidResultType);
6948 if (!result)
6949 return NULL;
6950
6951 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006952 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006953 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6954 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6955 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6956 if (PyErr_Occurred()) {
6957 Py_DECREF(result);
6958 return NULL;
6959 }
6960
6961 return result;
6962}
6963#endif
6964
Guido van Rossumb6775db1994-08-01 11:34:53 +00006965#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006966PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006967"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006968Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006969
Barry Warsaw53699e91996-12-10 23:23:01 +00006970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006971posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006972{
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 pid_t pid;
6974 int options;
6975 WAIT_TYPE status;
6976 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006977
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6979 return NULL;
6980 Py_BEGIN_ALLOW_THREADS
6981 pid = waitpid(pid, &status, options);
6982 Py_END_ALLOW_THREADS
6983 if (pid == -1)
6984 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006985
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006987}
6988
Tim Petersab034fa2002-02-01 11:27:43 +00006989#elif defined(HAVE_CWAIT)
6990
6991/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006993"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006994"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006995
6996static PyObject *
6997posix_waitpid(PyObject *self, PyObject *args)
6998{
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 Py_intptr_t pid;
7000 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007001
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007002 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 return NULL;
7004 Py_BEGIN_ALLOW_THREADS
7005 pid = _cwait(&status, pid, options);
7006 Py_END_ALLOW_THREADS
7007 if (pid == -1)
7008 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007009
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007011 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007012}
7013#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007014
Guido van Rossumad0ee831995-03-01 10:34:45 +00007015#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007016PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007017"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007018Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007019
Barry Warsaw53699e91996-12-10 23:23:01 +00007020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007021posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007022{
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 pid_t pid;
7024 WAIT_TYPE status;
7025 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007026
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 Py_BEGIN_ALLOW_THREADS
7028 pid = wait(&status);
7029 Py_END_ALLOW_THREADS
7030 if (pid == -1)
7031 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007032
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007034}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007035#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007037
Larry Hastings9cf065c2012-06-22 16:30:09 -07007038#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7039PyDoc_STRVAR(readlink__doc__,
7040"readlink(path, *, dir_fd=None) -> path\n\n\
7041Return a string representing the path to which the symbolic link points.\n\
7042\n\
7043If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7044 and path should be relative; path will then be relative to that directory.\n\
7045dir_fd may not be implemented on your platform.\n\
7046 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007047#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007048
Guido van Rossumb6775db1994-08-01 11:34:53 +00007049#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007050
Barry Warsaw53699e91996-12-10 23:23:01 +00007051static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007052posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007053{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007054 path_t path;
7055 int dir_fd = DEFAULT_DIR_FD;
7056 char buffer[MAXPATHLEN];
7057 ssize_t length;
7058 PyObject *return_value = NULL;
7059 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007060
Larry Hastings9cf065c2012-06-22 16:30:09 -07007061 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007062 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7064 path_converter, &path,
7065#ifdef HAVE_READLINKAT
7066 dir_fd_converter, &dir_fd
7067#else
7068 dir_fd_unavailable, &dir_fd
7069#endif
7070 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007072
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007074#ifdef HAVE_READLINKAT
7075 if (dir_fd != DEFAULT_DIR_FD)
7076 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007077 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007078#endif
7079 length = readlink(path.narrow, buffer, sizeof(buffer));
7080 Py_END_ALLOW_THREADS
7081
7082 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007083 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084 goto exit;
7085 }
7086
7087 if (PyUnicode_Check(path.object))
7088 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7089 else
7090 return_value = PyBytes_FromStringAndSize(buffer, length);
7091exit:
7092 path_cleanup(&path);
7093 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007094}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095
7096
Guido van Rossumb6775db1994-08-01 11:34:53 +00007097#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007099
Larry Hastings9cf065c2012-06-22 16:30:09 -07007100#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007101PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7103Create a symbolic link pointing to src named dst.\n\n\
7104target_is_directory is required on Windows if the target is to be\n\
7105 interpreted as a directory. (On Windows, symlink requires\n\
7106 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7107 target_is_directory is ignored on non-Windows platforms.\n\
7108\n\
7109If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7110 and path should be relative; path will then be relative to that directory.\n\
7111dir_fd may not be implemented on your platform.\n\
7112 If it is unavailable, using it will raise a NotImplementedError.");
7113
7114#if defined(MS_WINDOWS)
7115
7116/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7117static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7118static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007119
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007121check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122{
7123 HINSTANCE hKernel32;
7124 /* only recheck */
7125 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7126 return 1;
7127 hKernel32 = GetModuleHandleW(L"KERNEL32");
7128 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7129 "CreateSymbolicLinkW");
7130 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7131 "CreateSymbolicLinkA");
7132 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7133}
7134
Victor Stinner31b3b922013-06-05 01:49:17 +02007135/* Remove the last portion of the path */
7136static void
7137_dirnameW(WCHAR *path)
7138{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007139 WCHAR *ptr;
7140
7141 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007142 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007143 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007144 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007145 }
7146 *ptr = 0;
7147}
7148
Victor Stinner31b3b922013-06-05 01:49:17 +02007149/* Remove the last portion of the path */
7150static void
7151_dirnameA(char *path)
7152{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007153 char *ptr;
7154
7155 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007156 for(ptr = path + strlen(path); ptr != path; ptr--) {
7157 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007158 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007159 }
7160 *ptr = 0;
7161}
7162
Victor Stinner31b3b922013-06-05 01:49:17 +02007163/* Is this path absolute? */
7164static int
7165_is_absW(const WCHAR *path)
7166{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007167 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7168
7169}
7170
Victor Stinner31b3b922013-06-05 01:49:17 +02007171/* Is this path absolute? */
7172static int
7173_is_absA(const char *path)
7174{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007175 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7176
7177}
7178
Victor Stinner31b3b922013-06-05 01:49:17 +02007179/* join root and rest with a backslash */
7180static void
7181_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7182{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007183 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007184
Victor Stinner31b3b922013-06-05 01:49:17 +02007185 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007186 wcscpy(dest_path, rest);
7187 return;
7188 }
7189
7190 root_len = wcslen(root);
7191
7192 wcscpy(dest_path, root);
7193 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007194 dest_path[root_len] = L'\\';
7195 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007196 }
7197 wcscpy(dest_path+root_len, rest);
7198}
7199
Victor Stinner31b3b922013-06-05 01:49:17 +02007200/* join root and rest with a backslash */
7201static void
7202_joinA(char *dest_path, const char *root, const char *rest)
7203{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007204 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007205
Victor Stinner31b3b922013-06-05 01:49:17 +02007206 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007207 strcpy(dest_path, rest);
7208 return;
7209 }
7210
7211 root_len = strlen(root);
7212
7213 strcpy(dest_path, root);
7214 if(root_len) {
7215 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007216 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007217 }
7218 strcpy(dest_path+root_len, rest);
7219}
7220
Victor Stinner31b3b922013-06-05 01:49:17 +02007221/* Return True if the path at src relative to dest is a directory */
7222static int
7223_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007224{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007225 WIN32_FILE_ATTRIBUTE_DATA src_info;
7226 WCHAR dest_parent[MAX_PATH];
7227 WCHAR src_resolved[MAX_PATH] = L"";
7228
7229 /* dest_parent = os.path.dirname(dest) */
7230 wcscpy(dest_parent, dest);
7231 _dirnameW(dest_parent);
7232 /* src_resolved = os.path.join(dest_parent, src) */
7233 _joinW(src_resolved, dest_parent, src);
7234 return (
7235 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7236 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7237 );
7238}
7239
Victor Stinner31b3b922013-06-05 01:49:17 +02007240/* Return True if the path at src relative to dest is a directory */
7241static int
7242_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007244 WIN32_FILE_ATTRIBUTE_DATA src_info;
7245 char dest_parent[MAX_PATH];
7246 char src_resolved[MAX_PATH] = "";
7247
7248 /* dest_parent = os.path.dirname(dest) */
7249 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007250 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007251 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007252 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007253 return (
7254 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7255 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7256 );
7257}
7258
Larry Hastings9cf065c2012-06-22 16:30:09 -07007259#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007260
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007261static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007263{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007264 path_t src;
7265 path_t dst;
7266 int dir_fd = DEFAULT_DIR_FD;
7267 int target_is_directory = 0;
7268 static char *keywords[] = {"src", "dst", "target_is_directory",
7269 "dir_fd", NULL};
7270 PyObject *return_value;
7271#ifdef MS_WINDOWS
7272 DWORD result;
7273#else
7274 int result;
7275#endif
7276
7277 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007278 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279 src.argument_name = "src";
7280 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007281 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007282 dst.argument_name = "dst";
7283
7284#ifdef MS_WINDOWS
7285 if (!check_CreateSymbolicLink()) {
7286 PyErr_SetString(PyExc_NotImplementedError,
7287 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007288 return NULL;
7289 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007290 if (!win32_can_symlink) {
7291 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007292 return NULL;
7293 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007294#endif
7295
7296 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7297 keywords,
7298 path_converter, &src,
7299 path_converter, &dst,
7300 &target_is_directory,
7301#ifdef HAVE_SYMLINKAT
7302 dir_fd_converter, &dir_fd
7303#else
7304 dir_fd_unavailable, &dir_fd
7305#endif
7306 ))
7307 return NULL;
7308
7309 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7310 PyErr_SetString(PyExc_ValueError,
7311 "symlink: src and dst must be the same type");
7312 return_value = NULL;
7313 goto exit;
7314 }
7315
7316#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007317
Larry Hastings9cf065c2012-06-22 16:30:09 -07007318 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007319 if (dst.wide) {
7320 /* if src is a directory, ensure target_is_directory==1 */
7321 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007322 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7323 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007324 }
7325 else {
7326 /* if src is a directory, ensure target_is_directory==1 */
7327 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007328 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7329 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007331 Py_END_ALLOW_THREADS
7332
7333 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007334 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007335 goto exit;
7336 }
7337
7338#else
7339
7340 Py_BEGIN_ALLOW_THREADS
7341#if HAVE_SYMLINKAT
7342 if (dir_fd != DEFAULT_DIR_FD)
7343 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7344 else
7345#endif
7346 result = symlink(src.narrow, dst.narrow);
7347 Py_END_ALLOW_THREADS
7348
7349 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007350 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351 goto exit;
7352 }
7353#endif
7354
7355 return_value = Py_None;
7356 Py_INCREF(Py_None);
7357 goto exit; /* silence "unused label" warning */
7358exit:
7359 path_cleanup(&src);
7360 path_cleanup(&dst);
7361 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007362}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007363
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007364#endif /* HAVE_SYMLINK */
7365
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366
Brian Curtind40e6f72010-07-08 21:39:08 +00007367#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7368
Brian Curtind40e6f72010-07-08 21:39:08 +00007369static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007370win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007371{
7372 wchar_t *path;
7373 DWORD n_bytes_returned;
7374 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007375 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007376 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007377 HANDLE reparse_point_handle;
7378
7379 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7380 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7381 wchar_t *print_name;
7382
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383 static char *keywords[] = {"path", "dir_fd", NULL};
7384
7385 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7386 &po,
7387 dir_fd_unavailable, &dir_fd
7388 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007389 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390
Victor Stinnereb5657a2011-09-30 01:44:27 +02007391 path = PyUnicode_AsUnicode(po);
7392 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007393 return NULL;
7394
7395 /* First get a handle to the reparse point */
7396 Py_BEGIN_ALLOW_THREADS
7397 reparse_point_handle = CreateFileW(
7398 path,
7399 0,
7400 0,
7401 0,
7402 OPEN_EXISTING,
7403 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7404 0);
7405 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007406
Brian Curtind40e6f72010-07-08 21:39:08 +00007407 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007408 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007409
Brian Curtind40e6f72010-07-08 21:39:08 +00007410 Py_BEGIN_ALLOW_THREADS
7411 /* New call DeviceIoControl to read the reparse point */
7412 io_result = DeviceIoControl(
7413 reparse_point_handle,
7414 FSCTL_GET_REPARSE_POINT,
7415 0, 0, /* in buffer */
7416 target_buffer, sizeof(target_buffer),
7417 &n_bytes_returned,
7418 0 /* we're not using OVERLAPPED_IO */
7419 );
7420 CloseHandle(reparse_point_handle);
7421 Py_END_ALLOW_THREADS
7422
7423 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007424 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007425
7426 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7427 {
7428 PyErr_SetString(PyExc_ValueError,
7429 "not a symbolic link");
7430 return NULL;
7431 }
Brian Curtin74e45612010-07-09 15:58:59 +00007432 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7433 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7434
7435 result = PyUnicode_FromWideChar(print_name,
7436 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007437 return result;
7438}
7439
7440#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7441
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442
Larry Hastings605a62d2012-06-24 04:33:36 -07007443static PyStructSequence_Field times_result_fields[] = {
7444 {"user", "user time"},
7445 {"system", "system time"},
7446 {"children_user", "user time of children"},
7447 {"children_system", "system time of children"},
7448 {"elapsed", "elapsed time since an arbitrary point in the past"},
7449 {NULL}
7450};
7451
7452PyDoc_STRVAR(times_result__doc__,
7453"times_result: Result from os.times().\n\n\
7454This object may be accessed either as a tuple of\n\
7455 (user, system, children_user, children_system, elapsed),\n\
7456or via the attributes user, system, children_user, children_system,\n\
7457and elapsed.\n\
7458\n\
7459See os.times for more information.");
7460
7461static PyStructSequence_Desc times_result_desc = {
7462 "times_result", /* name */
7463 times_result__doc__, /* doc */
7464 times_result_fields,
7465 5
7466};
7467
7468static PyTypeObject TimesResultType;
7469
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007470#ifdef MS_WINDOWS
7471#define HAVE_TIMES /* mandatory, for the method table */
7472#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007473
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007474#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007475
7476static PyObject *
7477build_times_result(double user, double system,
7478 double children_user, double children_system,
7479 double elapsed)
7480{
7481 PyObject *value = PyStructSequence_New(&TimesResultType);
7482 if (value == NULL)
7483 return NULL;
7484
7485#define SET(i, field) \
7486 { \
7487 PyObject *o = PyFloat_FromDouble(field); \
7488 if (!o) { \
7489 Py_DECREF(value); \
7490 return NULL; \
7491 } \
7492 PyStructSequence_SET_ITEM(value, i, o); \
7493 } \
7494
7495 SET(0, user);
7496 SET(1, system);
7497 SET(2, children_user);
7498 SET(3, children_system);
7499 SET(4, elapsed);
7500
7501#undef SET
7502
7503 return value;
7504}
7505
7506PyDoc_STRVAR(posix_times__doc__,
7507"times() -> times_result\n\n\
7508Return an object containing floating point numbers indicating process\n\
7509times. The object behaves like a named tuple with these fields:\n\
7510 (utime, stime, cutime, cstime, elapsed_time)");
7511
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007512#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007514posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007515{
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 FILETIME create, exit, kernel, user;
7517 HANDLE hProc;
7518 hProc = GetCurrentProcess();
7519 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7520 /* The fields of a FILETIME structure are the hi and lo part
7521 of a 64-bit value expressed in 100 nanosecond units.
7522 1e7 is one second in such units; 1e-7 the inverse.
7523 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7524 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007525 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 (double)(user.dwHighDateTime*429.4967296 +
7527 user.dwLowDateTime*1e-7),
7528 (double)(kernel.dwHighDateTime*429.4967296 +
7529 kernel.dwLowDateTime*1e-7),
7530 (double)0,
7531 (double)0,
7532 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007533}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007534#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007535#define NEED_TICKS_PER_SECOND
7536static long ticks_per_second = -1;
7537static PyObject *
7538posix_times(PyObject *self, PyObject *noargs)
7539{
7540 struct tms t;
7541 clock_t c;
7542 errno = 0;
7543 c = times(&t);
7544 if (c == (clock_t) -1)
7545 return posix_error();
7546 return build_times_result(
7547 (double)t.tms_utime / ticks_per_second,
7548 (double)t.tms_stime / ticks_per_second,
7549 (double)t.tms_cutime / ticks_per_second,
7550 (double)t.tms_cstime / ticks_per_second,
7551 (double)c / ticks_per_second);
7552}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007553#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007554
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007555#endif /* HAVE_TIMES */
7556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007557
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007558#ifdef HAVE_GETSID
7559PyDoc_STRVAR(posix_getsid__doc__,
7560"getsid(pid) -> sid\n\n\
7561Call the system call getsid().");
7562
7563static PyObject *
7564posix_getsid(PyObject *self, PyObject *args)
7565{
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 pid_t pid;
7567 int sid;
7568 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7569 return NULL;
7570 sid = getsid(pid);
7571 if (sid < 0)
7572 return posix_error();
7573 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007574}
7575#endif /* HAVE_GETSID */
7576
7577
Guido van Rossumb6775db1994-08-01 11:34:53 +00007578#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007579PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007580"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007581Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007582
Barry Warsaw53699e91996-12-10 23:23:01 +00007583static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007584posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007585{
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 if (setsid() < 0)
7587 return posix_error();
7588 Py_INCREF(Py_None);
7589 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007590}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007592
Guido van Rossumb6775db1994-08-01 11:34:53 +00007593#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007594PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007595"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007596Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007597
Barry Warsaw53699e91996-12-10 23:23:01 +00007598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007599posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007600{
Victor Stinner8c62be82010-05-06 00:08:46 +00007601 pid_t pid;
7602 int pgrp;
7603 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7604 return NULL;
7605 if (setpgid(pid, pgrp) < 0)
7606 return posix_error();
7607 Py_INCREF(Py_None);
7608 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007610#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007612
Guido van Rossumb6775db1994-08-01 11:34:53 +00007613#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007615"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007616Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007617
Barry Warsaw53699e91996-12-10 23:23:01 +00007618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007619posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007620{
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 int fd;
7622 pid_t pgid;
7623 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7624 return NULL;
7625 pgid = tcgetpgrp(fd);
7626 if (pgid < 0)
7627 return posix_error();
7628 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007634PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007635"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007636Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007637
Barry Warsaw53699e91996-12-10 23:23:01 +00007638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007639posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007640{
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 int fd;
7642 pid_t pgid;
7643 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7644 return NULL;
7645 if (tcsetpgrp(fd, pgid) < 0)
7646 return posix_error();
7647 Py_INCREF(Py_None);
7648 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007649}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007650#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007651
Guido van Rossum687dd131993-05-17 08:34:16 +00007652/* Functions acting on file descriptors */
7653
Victor Stinnerdaf45552013-08-28 00:53:59 +02007654#ifdef O_CLOEXEC
7655extern int _Py_open_cloexec_works;
7656#endif
7657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007658PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007659"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7660Open a file for low level IO. Returns a file handle (integer).\n\
7661\n\
7662If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7663 and path should be relative; path will then be relative to that directory.\n\
7664dir_fd may not be implemented on your platform.\n\
7665 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007666
Barry Warsaw53699e91996-12-10 23:23:01 +00007667static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007668posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007669{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007670 path_t path;
7671 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007673 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007675 PyObject *return_value = NULL;
7676 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007677#ifdef O_CLOEXEC
7678 int *atomic_flag_works = &_Py_open_cloexec_works;
7679#elif !defined(MS_WINDOWS)
7680 int *atomic_flag_works = NULL;
7681#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007682
Larry Hastings9cf065c2012-06-22 16:30:09 -07007683 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007684 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007685 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7686 path_converter, &path,
7687 &flags, &mode,
7688#ifdef HAVE_OPENAT
7689 dir_fd_converter, &dir_fd
7690#else
7691 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007692#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007693 ))
7694 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007695
Victor Stinnerdaf45552013-08-28 00:53:59 +02007696#ifdef MS_WINDOWS
7697 flags |= O_NOINHERIT;
7698#elif defined(O_CLOEXEC)
7699 flags |= O_CLOEXEC;
7700#endif
7701
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007703#ifdef MS_WINDOWS
7704 if (path.wide)
7705 fd = _wopen(path.wide, flags, mode);
7706 else
7707#endif
7708#ifdef HAVE_OPENAT
7709 if (dir_fd != DEFAULT_DIR_FD)
7710 fd = openat(dir_fd, path.narrow, flags, mode);
7711 else
7712#endif
7713 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007714 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007715
Larry Hastings9cf065c2012-06-22 16:30:09 -07007716 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007717 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007718 goto exit;
7719 }
7720
Victor Stinnerdaf45552013-08-28 00:53:59 +02007721#ifndef MS_WINDOWS
7722 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7723 close(fd);
7724 goto exit;
7725 }
7726#endif
7727
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728 return_value = PyLong_FromLong((long)fd);
7729
7730exit:
7731 path_cleanup(&path);
7732 return return_value;
7733}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007735PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007736"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007737Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Benjamin Peterson932bba32014-02-11 10:16:16 -05007739/*
7740The underscore at end of function name avoids a name clash with the libc
7741function posix_close.
7742*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007743static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007744posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007745{
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 int fd, res;
7747 if (!PyArg_ParseTuple(args, "i:close", &fd))
7748 return NULL;
7749 if (!_PyVerify_fd(fd))
7750 return posix_error();
7751 Py_BEGIN_ALLOW_THREADS
7752 res = close(fd);
7753 Py_END_ALLOW_THREADS
7754 if (res < 0)
7755 return posix_error();
7756 Py_INCREF(Py_None);
7757 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007758}
7759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007760
Victor Stinner8c62be82010-05-06 00:08:46 +00007761PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007762"closerange(fd_low, fd_high)\n\n\
7763Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7764
7765static PyObject *
7766posix_closerange(PyObject *self, PyObject *args)
7767{
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 int fd_from, fd_to, i;
7769 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7770 return NULL;
7771 Py_BEGIN_ALLOW_THREADS
7772 for (i = fd_from; i < fd_to; i++)
7773 if (_PyVerify_fd(i))
7774 close(i);
7775 Py_END_ALLOW_THREADS
7776 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007777}
7778
7779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007780PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007781"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007782Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007783
Barry Warsaw53699e91996-12-10 23:23:01 +00007784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007785posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007786{
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007788
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7790 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007791
Victor Stinnerdaf45552013-08-28 00:53:59 +02007792 fd = _Py_dup(fd);
7793 if (fd == -1)
7794 return NULL;
7795
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007797}
7798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007799
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007800PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007801"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007802Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007803
Barry Warsaw53699e91996-12-10 23:23:01 +00007804static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007805posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007806{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007807 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7808 int fd, fd2;
7809 int inheritable = 1;
7810 int res;
7811#if defined(HAVE_DUP3) && \
7812 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7813 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7814 int dup3_works = -1;
7815#endif
7816
7817 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7818 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007820
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 if (!_PyVerify_fd_dup2(fd, fd2))
7822 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007823
7824#ifdef MS_WINDOWS
7825 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007827 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 if (res < 0)
7829 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007830
7831 /* Character files like console cannot be make non-inheritable */
7832 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7833 close(fd2);
7834 return NULL;
7835 }
7836
7837#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7838 Py_BEGIN_ALLOW_THREADS
7839 if (!inheritable)
7840 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7841 else
7842 res = dup2(fd, fd2);
7843 Py_END_ALLOW_THREADS
7844 if (res < 0)
7845 return posix_error();
7846
7847#else
7848
7849#ifdef HAVE_DUP3
7850 if (!inheritable && dup3_works != 0) {
7851 Py_BEGIN_ALLOW_THREADS
7852 res = dup3(fd, fd2, O_CLOEXEC);
7853 Py_END_ALLOW_THREADS
7854 if (res < 0) {
7855 if (dup3_works == -1)
7856 dup3_works = (errno != ENOSYS);
7857 if (dup3_works)
7858 return posix_error();
7859 }
7860 }
7861
7862 if (inheritable || dup3_works == 0)
7863 {
7864#endif
7865 Py_BEGIN_ALLOW_THREADS
7866 res = dup2(fd, fd2);
7867 Py_END_ALLOW_THREADS
7868 if (res < 0)
7869 return posix_error();
7870
7871 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7872 close(fd2);
7873 return NULL;
7874 }
7875#ifdef HAVE_DUP3
7876 }
7877#endif
7878
7879#endif
7880
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 Py_INCREF(Py_None);
7882 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007883}
7884
Ross Lagerwall7807c352011-03-17 20:20:30 +02007885#ifdef HAVE_LOCKF
7886PyDoc_STRVAR(posix_lockf__doc__,
7887"lockf(fd, cmd, len)\n\n\
7888Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7889fd is an open file descriptor.\n\
7890cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7891F_TEST.\n\
7892len specifies the section of the file to lock.");
7893
7894static PyObject *
7895posix_lockf(PyObject *self, PyObject *args)
7896{
7897 int fd, cmd, res;
7898 off_t len;
7899 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7900 &fd, &cmd, _parse_off_t, &len))
7901 return NULL;
7902
7903 Py_BEGIN_ALLOW_THREADS
7904 res = lockf(fd, cmd, len);
7905 Py_END_ALLOW_THREADS
7906
7907 if (res < 0)
7908 return posix_error();
7909
7910 Py_RETURN_NONE;
7911}
7912#endif
7913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007915PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007916"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007917Set the current position of a file descriptor.\n\
7918Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007919
Barry Warsaw53699e91996-12-10 23:23:01 +00007920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007921posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007922{
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007924#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007926#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007928#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007929 PyObject *posobj;
7930 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007932#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7934 switch (how) {
7935 case 0: how = SEEK_SET; break;
7936 case 1: how = SEEK_CUR; break;
7937 case 2: how = SEEK_END; break;
7938 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007939#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007940
Ross Lagerwall8e749672011-03-17 21:54:07 +02007941#if !defined(HAVE_LARGEFILE_SUPPORT)
7942 pos = PyLong_AsLong(posobj);
7943#else
7944 pos = PyLong_AsLongLong(posobj);
7945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 if (PyErr_Occurred())
7947 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007948
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 if (!_PyVerify_fd(fd))
7950 return posix_error();
7951 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007952#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007956#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 Py_END_ALLOW_THREADS
7958 if (res < 0)
7959 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007960
7961#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007963#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007965#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007966}
7967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007968
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007969PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007970"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007971Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007972
Barry Warsaw53699e91996-12-10 23:23:01 +00007973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007974posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007975{
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 int fd, size;
7977 Py_ssize_t n;
7978 PyObject *buffer;
7979 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7980 return NULL;
7981 if (size < 0) {
7982 errno = EINVAL;
7983 return posix_error();
7984 }
7985 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7986 if (buffer == NULL)
7987 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007988 if (!_PyVerify_fd(fd)) {
7989 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007991 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 Py_BEGIN_ALLOW_THREADS
7993 n = read(fd, PyBytes_AS_STRING(buffer), size);
7994 Py_END_ALLOW_THREADS
7995 if (n < 0) {
7996 Py_DECREF(buffer);
7997 return posix_error();
7998 }
7999 if (n != size)
8000 _PyBytes_Resize(&buffer, n);
8001 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008002}
8003
Ross Lagerwall7807c352011-03-17 20:20:30 +02008004#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8005 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008006static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008007iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8008{
8009 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008010 Py_ssize_t blen, total = 0;
8011
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012 *iov = PyMem_New(struct iovec, cnt);
8013 if (*iov == NULL) {
8014 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008015 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008016 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008017
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008018 *buf = PyMem_New(Py_buffer, cnt);
8019 if (*buf == NULL) {
8020 PyMem_Del(*iov);
8021 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008022 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008023 }
8024
8025 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008026 PyObject *item = PySequence_GetItem(seq, i);
8027 if (item == NULL)
8028 goto fail;
8029 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8030 Py_DECREF(item);
8031 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008033 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008034 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035 blen = (*buf)[i].len;
8036 (*iov)[i].iov_len = blen;
8037 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008039 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008040
8041fail:
8042 PyMem_Del(*iov);
8043 for (j = 0; j < i; j++) {
8044 PyBuffer_Release(&(*buf)[j]);
8045 }
8046 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008047 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048}
8049
8050static void
8051iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8052{
8053 int i;
8054 PyMem_Del(iov);
8055 for (i = 0; i < cnt; i++) {
8056 PyBuffer_Release(&buf[i]);
8057 }
8058 PyMem_Del(buf);
8059}
8060#endif
8061
Ross Lagerwall7807c352011-03-17 20:20:30 +02008062#ifdef HAVE_READV
8063PyDoc_STRVAR(posix_readv__doc__,
8064"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008065Read from a file descriptor fd into a number of mutable, bytes-like\n\
8066objects (\"buffers\"). readv will transfer data into each buffer\n\
8067until it is full and then move on to the next buffer in the sequence\n\
8068to hold the rest of the data.\n\n\
8069readv returns the total number of bytes read (which may be less than\n\
8070the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008071
8072static PyObject *
8073posix_readv(PyObject *self, PyObject *args)
8074{
8075 int fd, cnt;
8076 Py_ssize_t n;
8077 PyObject *seq;
8078 struct iovec *iov;
8079 Py_buffer *buf;
8080
8081 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8082 return NULL;
8083 if (!PySequence_Check(seq)) {
8084 PyErr_SetString(PyExc_TypeError,
8085 "readv() arg 2 must be a sequence");
8086 return NULL;
8087 }
8088 cnt = PySequence_Size(seq);
8089
Victor Stinner57ddf782014-01-08 15:21:28 +01008090 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008091 return NULL;
8092
8093 Py_BEGIN_ALLOW_THREADS
8094 n = readv(fd, iov, cnt);
8095 Py_END_ALLOW_THREADS
8096
8097 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008098 if (n < 0)
8099 return posix_error();
8100
Ross Lagerwall7807c352011-03-17 20:20:30 +02008101 return PyLong_FromSsize_t(n);
8102}
8103#endif
8104
8105#ifdef HAVE_PREAD
8106PyDoc_STRVAR(posix_pread__doc__,
8107"pread(fd, buffersize, offset) -> string\n\n\
8108Read from a file descriptor, fd, at a position of offset. It will read up\n\
8109to buffersize number of bytes. The file offset remains unchanged.");
8110
8111static PyObject *
8112posix_pread(PyObject *self, PyObject *args)
8113{
8114 int fd, size;
8115 off_t offset;
8116 Py_ssize_t n;
8117 PyObject *buffer;
8118 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8119 return NULL;
8120
8121 if (size < 0) {
8122 errno = EINVAL;
8123 return posix_error();
8124 }
8125 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8126 if (buffer == NULL)
8127 return NULL;
8128 if (!_PyVerify_fd(fd)) {
8129 Py_DECREF(buffer);
8130 return posix_error();
8131 }
8132 Py_BEGIN_ALLOW_THREADS
8133 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8134 Py_END_ALLOW_THREADS
8135 if (n < 0) {
8136 Py_DECREF(buffer);
8137 return posix_error();
8138 }
8139 if (n != size)
8140 _PyBytes_Resize(&buffer, n);
8141 return buffer;
8142}
8143#endif
8144
8145PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008146"write(fd, data) -> byteswritten\n\n\
8147Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148
8149static PyObject *
8150posix_write(PyObject *self, PyObject *args)
8151{
8152 Py_buffer pbuf;
8153 int fd;
8154 Py_ssize_t size, len;
8155
8156 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8157 return NULL;
8158 if (!_PyVerify_fd(fd)) {
8159 PyBuffer_Release(&pbuf);
8160 return posix_error();
8161 }
8162 len = pbuf.len;
8163 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008164#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165 if (len > INT_MAX)
8166 len = INT_MAX;
8167 size = write(fd, pbuf.buf, (int)len);
8168#else
8169 size = write(fd, pbuf.buf, len);
8170#endif
8171 Py_END_ALLOW_THREADS
8172 PyBuffer_Release(&pbuf);
8173 if (size < 0)
8174 return posix_error();
8175 return PyLong_FromSsize_t(size);
8176}
8177
8178#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008179PyDoc_STRVAR(posix_sendfile__doc__,
8180"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8181sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8182 -> byteswritten\n\
8183Copy nbytes bytes from file descriptor in to file descriptor out.");
8184
8185static PyObject *
8186posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8187{
8188 int in, out;
8189 Py_ssize_t ret;
8190 off_t offset;
8191
8192#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8193#ifndef __APPLE__
8194 Py_ssize_t len;
8195#endif
8196 PyObject *headers = NULL, *trailers = NULL;
8197 Py_buffer *hbuf, *tbuf;
8198 off_t sbytes;
8199 struct sf_hdtr sf;
8200 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008201 static char *keywords[] = {"out", "in",
8202 "offset", "count",
8203 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008204
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008205 sf.headers = NULL;
8206 sf.trailers = NULL;
8207
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008208#ifdef __APPLE__
8209 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008210 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008211#else
8212 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008213 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008214#endif
8215 &headers, &trailers, &flags))
8216 return NULL;
8217 if (headers != NULL) {
8218 if (!PySequence_Check(headers)) {
8219 PyErr_SetString(PyExc_TypeError,
8220 "sendfile() headers must be a sequence or None");
8221 return NULL;
8222 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008223 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008224 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008225 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008226 (i = iov_setup(&(sf.headers), &hbuf,
8227 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008228 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008229#ifdef __APPLE__
8230 sbytes += i;
8231#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008232 }
8233 }
8234 if (trailers != NULL) {
8235 if (!PySequence_Check(trailers)) {
8236 PyErr_SetString(PyExc_TypeError,
8237 "sendfile() trailers must be a sequence or None");
8238 return NULL;
8239 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008240 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008241 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008242 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008243 (i = iov_setup(&(sf.trailers), &tbuf,
8244 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008246#ifdef __APPLE__
8247 sbytes += i;
8248#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008249 }
8250 }
8251
8252 Py_BEGIN_ALLOW_THREADS
8253#ifdef __APPLE__
8254 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8255#else
8256 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8257#endif
8258 Py_END_ALLOW_THREADS
8259
8260 if (sf.headers != NULL)
8261 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8262 if (sf.trailers != NULL)
8263 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8264
8265 if (ret < 0) {
8266 if ((errno == EAGAIN) || (errno == EBUSY)) {
8267 if (sbytes != 0) {
8268 // some data has been sent
8269 goto done;
8270 }
8271 else {
8272 // no data has been sent; upper application is supposed
8273 // to retry on EAGAIN or EBUSY
8274 return posix_error();
8275 }
8276 }
8277 return posix_error();
8278 }
8279 goto done;
8280
8281done:
8282 #if !defined(HAVE_LARGEFILE_SUPPORT)
8283 return Py_BuildValue("l", sbytes);
8284 #else
8285 return Py_BuildValue("L", sbytes);
8286 #endif
8287
8288#else
8289 Py_ssize_t count;
8290 PyObject *offobj;
8291 static char *keywords[] = {"out", "in",
8292 "offset", "count", NULL};
8293 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8294 keywords, &out, &in, &offobj, &count))
8295 return NULL;
8296#ifdef linux
8297 if (offobj == Py_None) {
8298 Py_BEGIN_ALLOW_THREADS
8299 ret = sendfile(out, in, NULL, count);
8300 Py_END_ALLOW_THREADS
8301 if (ret < 0)
8302 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008303 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 }
8305#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008306 if (!_parse_off_t(offobj, &offset))
8307 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308 Py_BEGIN_ALLOW_THREADS
8309 ret = sendfile(out, in, &offset, count);
8310 Py_END_ALLOW_THREADS
8311 if (ret < 0)
8312 return posix_error();
8313 return Py_BuildValue("n", ret);
8314#endif
8315}
8316#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008318PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008319"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008320Like stat(), but for an open file descriptor.\n\
8321Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008322
Barry Warsaw53699e91996-12-10 23:23:01 +00008323static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008324posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008325{
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 int fd;
8327 STRUCT_STAT st;
8328 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008329 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 Py_BEGIN_ALLOW_THREADS
8332 res = FSTAT(fd, &st);
8333 Py_END_ALLOW_THREADS
8334 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008335#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008336 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008337#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008339#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 }
Tim Peters5aa91602002-01-30 05:46:57 +00008341
Victor Stinner4195b5c2012-02-08 23:03:19 +01008342 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008343}
8344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008345PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008346"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008347Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008348connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008349
8350static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008351posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008352{
Victor Stinner8c62be82010-05-06 00:08:46 +00008353 int fd;
8354 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8355 return NULL;
8356 if (!_PyVerify_fd(fd))
8357 return PyBool_FromLong(0);
8358 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008359}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008360
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008361#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008362PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008363"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008364Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008365
Barry Warsaw53699e91996-12-10 23:23:01 +00008366static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008367posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008368{
Victor Stinner8c62be82010-05-06 00:08:46 +00008369 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008370#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008372 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008374#else
8375 int res;
8376#endif
8377
8378#ifdef MS_WINDOWS
8379 attr.nLength = sizeof(attr);
8380 attr.lpSecurityDescriptor = NULL;
8381 attr.bInheritHandle = FALSE;
8382
8383 Py_BEGIN_ALLOW_THREADS
8384 ok = CreatePipe(&read, &write, &attr, 0);
8385 if (ok) {
8386 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8387 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8388 if (fds[0] == -1 || fds[1] == -1) {
8389 CloseHandle(read);
8390 CloseHandle(write);
8391 ok = 0;
8392 }
8393 }
8394 Py_END_ALLOW_THREADS
8395
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008397 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008398#else
8399
8400#ifdef HAVE_PIPE2
8401 Py_BEGIN_ALLOW_THREADS
8402 res = pipe2(fds, O_CLOEXEC);
8403 Py_END_ALLOW_THREADS
8404
8405 if (res != 0 && errno == ENOSYS)
8406 {
8407#endif
8408 Py_BEGIN_ALLOW_THREADS
8409 res = pipe(fds);
8410 Py_END_ALLOW_THREADS
8411
8412 if (res == 0) {
8413 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8414 close(fds[0]);
8415 close(fds[1]);
8416 return NULL;
8417 }
8418 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8419 close(fds[0]);
8420 close(fds[1]);
8421 return NULL;
8422 }
8423 }
8424#ifdef HAVE_PIPE2
8425 }
8426#endif
8427
8428 if (res != 0)
8429 return PyErr_SetFromErrno(PyExc_OSError);
8430#endif /* !MS_WINDOWS */
8431 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008432}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008433#endif /* HAVE_PIPE */
8434
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008435#ifdef HAVE_PIPE2
8436PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008437"pipe2(flags) -> (read_end, write_end)\n\n\
8438Create a pipe with flags set atomically.\n\
8439flags can be constructed by ORing together one or more of these values:\n\
8440O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008441");
8442
8443static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008444posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008445{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008446 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008447 int fds[2];
8448 int res;
8449
Serhiy Storchaka78980432013-01-15 01:12:17 +02008450 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008451 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008452 return NULL;
8453
8454 res = pipe2(fds, flags);
8455 if (res != 0)
8456 return posix_error();
8457 return Py_BuildValue("(ii)", fds[0], fds[1]);
8458}
8459#endif /* HAVE_PIPE2 */
8460
Ross Lagerwall7807c352011-03-17 20:20:30 +02008461#ifdef HAVE_WRITEV
8462PyDoc_STRVAR(posix_writev__doc__,
8463"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008464Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8465must be a sequence of bytes-like objects.\n\n\
8466writev writes the contents of each object to the file descriptor\n\
8467and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008468
8469static PyObject *
8470posix_writev(PyObject *self, PyObject *args)
8471{
8472 int fd, cnt;
8473 Py_ssize_t res;
8474 PyObject *seq;
8475 struct iovec *iov;
8476 Py_buffer *buf;
8477 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8478 return NULL;
8479 if (!PySequence_Check(seq)) {
8480 PyErr_SetString(PyExc_TypeError,
8481 "writev() arg 2 must be a sequence");
8482 return NULL;
8483 }
8484 cnt = PySequence_Size(seq);
8485
Victor Stinner57ddf782014-01-08 15:21:28 +01008486 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008487 return NULL;
8488 }
8489
8490 Py_BEGIN_ALLOW_THREADS
8491 res = writev(fd, iov, cnt);
8492 Py_END_ALLOW_THREADS
8493
8494 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008495 if (res < 0)
8496 return posix_error();
8497
Ross Lagerwall7807c352011-03-17 20:20:30 +02008498 return PyLong_FromSsize_t(res);
8499}
8500#endif
8501
8502#ifdef HAVE_PWRITE
8503PyDoc_STRVAR(posix_pwrite__doc__,
8504"pwrite(fd, string, offset) -> byteswritten\n\n\
8505Write string to a file descriptor, fd, from offset, leaving the file\n\
8506offset unchanged.");
8507
8508static PyObject *
8509posix_pwrite(PyObject *self, PyObject *args)
8510{
8511 Py_buffer pbuf;
8512 int fd;
8513 off_t offset;
8514 Py_ssize_t size;
8515
8516 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8517 return NULL;
8518
8519 if (!_PyVerify_fd(fd)) {
8520 PyBuffer_Release(&pbuf);
8521 return posix_error();
8522 }
8523 Py_BEGIN_ALLOW_THREADS
8524 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8525 Py_END_ALLOW_THREADS
8526 PyBuffer_Release(&pbuf);
8527 if (size < 0)
8528 return posix_error();
8529 return PyLong_FromSsize_t(size);
8530}
8531#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008532
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008533#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008534PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008535"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8536Create a FIFO (a POSIX named pipe).\n\
8537\n\
8538If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8539 and path should be relative; path will then be relative to that directory.\n\
8540dir_fd may not be implemented on your platform.\n\
8541 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008542
Barry Warsaw53699e91996-12-10 23:23:01 +00008543static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008544posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008545{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008546 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008548 int dir_fd = DEFAULT_DIR_FD;
8549 int result;
8550 PyObject *return_value = NULL;
8551 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8552
8553 memset(&path, 0, sizeof(path));
8554 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8555 path_converter, &path,
8556 &mode,
8557#ifdef HAVE_MKFIFOAT
8558 dir_fd_converter, &dir_fd
8559#else
8560 dir_fd_unavailable, &dir_fd
8561#endif
8562 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008564
Victor Stinner8c62be82010-05-06 00:08:46 +00008565 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008566#ifdef HAVE_MKFIFOAT
8567 if (dir_fd != DEFAULT_DIR_FD)
8568 result = mkfifoat(dir_fd, path.narrow, mode);
8569 else
8570#endif
8571 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008573
8574 if (result < 0) {
8575 return_value = posix_error();
8576 goto exit;
8577 }
8578
8579 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008581
8582exit:
8583 path_cleanup(&path);
8584 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008585}
8586#endif
8587
Neal Norwitz11690112002-07-30 01:08:28 +00008588#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008589PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008590"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008591Create a filesystem node (file, device special file or named pipe)\n\
8592named filename. mode specifies both the permissions to use and the\n\
8593type of node to be created, being combined (bitwise OR) with one of\n\
8594S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008595device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008596os.makedev()), otherwise it is ignored.\n\
8597\n\
8598If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8599 and path should be relative; path will then be relative to that directory.\n\
8600dir_fd may not be implemented on your platform.\n\
8601 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008602
8603
8604static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008605posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008606{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008607 path_t path;
8608 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008609 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008610 int dir_fd = DEFAULT_DIR_FD;
8611 int result;
8612 PyObject *return_value = NULL;
8613 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8614
8615 memset(&path, 0, sizeof(path));
8616 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8617 path_converter, &path,
8618 &mode, &device,
8619#ifdef HAVE_MKNODAT
8620 dir_fd_converter, &dir_fd
8621#else
8622 dir_fd_unavailable, &dir_fd
8623#endif
8624 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008625 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008626
Victor Stinner8c62be82010-05-06 00:08:46 +00008627 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008628#ifdef HAVE_MKNODAT
8629 if (dir_fd != DEFAULT_DIR_FD)
8630 result = mknodat(dir_fd, path.narrow, mode, device);
8631 else
8632#endif
8633 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008635
8636 if (result < 0) {
8637 return_value = posix_error();
8638 goto exit;
8639 }
8640
8641 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008642 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008643
Larry Hastings9cf065c2012-06-22 16:30:09 -07008644exit:
8645 path_cleanup(&path);
8646 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008647}
8648#endif
8649
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008650#ifdef HAVE_DEVICE_MACROS
8651PyDoc_STRVAR(posix_major__doc__,
8652"major(device) -> major number\n\
8653Extracts a device major number from a raw device number.");
8654
8655static PyObject *
8656posix_major(PyObject *self, PyObject *args)
8657{
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 int device;
8659 if (!PyArg_ParseTuple(args, "i:major", &device))
8660 return NULL;
8661 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008662}
8663
8664PyDoc_STRVAR(posix_minor__doc__,
8665"minor(device) -> minor number\n\
8666Extracts a device minor number from a raw device number.");
8667
8668static PyObject *
8669posix_minor(PyObject *self, PyObject *args)
8670{
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 int device;
8672 if (!PyArg_ParseTuple(args, "i:minor", &device))
8673 return NULL;
8674 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008675}
8676
8677PyDoc_STRVAR(posix_makedev__doc__,
8678"makedev(major, minor) -> device number\n\
8679Composes a raw device number from the major and minor device numbers.");
8680
8681static PyObject *
8682posix_makedev(PyObject *self, PyObject *args)
8683{
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 int major, minor;
8685 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8686 return NULL;
8687 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008688}
8689#endif /* device macros */
8690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008691
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008692#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008693PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008694"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008695Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008696
Barry Warsaw53699e91996-12-10 23:23:01 +00008697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008698posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008699{
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 int fd;
8701 off_t length;
8702 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008703
Ross Lagerwall7807c352011-03-17 20:20:30 +02008704 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008705 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008706
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 Py_BEGIN_ALLOW_THREADS
8708 res = ftruncate(fd, length);
8709 Py_END_ALLOW_THREADS
8710 if (res < 0)
8711 return posix_error();
8712 Py_INCREF(Py_None);
8713 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008714}
8715#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008716
Ross Lagerwall7807c352011-03-17 20:20:30 +02008717#ifdef HAVE_TRUNCATE
8718PyDoc_STRVAR(posix_truncate__doc__,
8719"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008720Truncate the file given by path to length bytes.\n\
8721On some platforms, path may also be specified as an open file descriptor.\n\
8722 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008723
8724static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008725posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008726{
Georg Brandl306336b2012-06-24 12:55:33 +02008727 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008728 off_t length;
8729 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008730 PyObject *result = NULL;
8731 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008732
Georg Brandl306336b2012-06-24 12:55:33 +02008733 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008734 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008735#ifdef HAVE_FTRUNCATE
8736 path.allow_fd = 1;
8737#endif
8738 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8739 path_converter, &path,
8740 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008741 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742
8743 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008744#ifdef HAVE_FTRUNCATE
8745 if (path.fd != -1)
8746 res = ftruncate(path.fd, length);
8747 else
8748#endif
8749 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008750 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008751 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008752 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008753 else {
8754 Py_INCREF(Py_None);
8755 result = Py_None;
8756 }
8757 path_cleanup(&path);
8758 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008759}
8760#endif
8761
8762#ifdef HAVE_POSIX_FALLOCATE
8763PyDoc_STRVAR(posix_posix_fallocate__doc__,
8764"posix_fallocate(fd, offset, len)\n\n\
8765Ensures that enough disk space is allocated for the file specified by fd\n\
8766starting from offset and continuing for len bytes.");
8767
8768static PyObject *
8769posix_posix_fallocate(PyObject *self, PyObject *args)
8770{
8771 off_t len, offset;
8772 int res, fd;
8773
8774 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8775 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8776 return NULL;
8777
8778 Py_BEGIN_ALLOW_THREADS
8779 res = posix_fallocate(fd, offset, len);
8780 Py_END_ALLOW_THREADS
8781 if (res != 0) {
8782 errno = res;
8783 return posix_error();
8784 }
8785 Py_RETURN_NONE;
8786}
8787#endif
8788
8789#ifdef HAVE_POSIX_FADVISE
8790PyDoc_STRVAR(posix_posix_fadvise__doc__,
8791"posix_fadvise(fd, offset, len, advice)\n\n\
8792Announces an intention to access data in a specific pattern thus allowing\n\
8793the kernel to make optimizations.\n\
8794The advice applies to the region of the file specified by fd starting at\n\
8795offset and continuing for len bytes.\n\
8796advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8797POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8798POSIX_FADV_DONTNEED.");
8799
8800static PyObject *
8801posix_posix_fadvise(PyObject *self, PyObject *args)
8802{
8803 off_t len, offset;
8804 int res, fd, advice;
8805
8806 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8807 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8808 return NULL;
8809
8810 Py_BEGIN_ALLOW_THREADS
8811 res = posix_fadvise(fd, offset, len, advice);
8812 Py_END_ALLOW_THREADS
8813 if (res != 0) {
8814 errno = res;
8815 return posix_error();
8816 }
8817 Py_RETURN_NONE;
8818}
8819#endif
8820
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008821#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008822PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008823"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008824Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008825
Fred Drake762e2061999-08-26 17:23:54 +00008826/* Save putenv() parameters as values here, so we can collect them when they
8827 * get re-set with another call for the same key. */
8828static PyObject *posix_putenv_garbage;
8829
Tim Peters5aa91602002-01-30 05:46:57 +00008830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008831posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008832{
Victor Stinner84ae1182010-05-06 22:05:07 +00008833 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008834#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008835 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008836 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008837
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008839 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008840 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008842
Victor Stinner65170952011-11-22 22:16:17 +01008843 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008844 if (newstr == NULL) {
8845 PyErr_NoMemory();
8846 goto error;
8847 }
Victor Stinner65170952011-11-22 22:16:17 +01008848 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8849 PyErr_Format(PyExc_ValueError,
8850 "the environment variable is longer than %u characters",
8851 _MAX_ENV);
8852 goto error;
8853 }
8854
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008856 if (newenv == NULL)
8857 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008860 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008862#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008863 PyObject *os1, *os2;
8864 char *s1, *s2;
8865 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008866
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008867 if (!PyArg_ParseTuple(args,
8868 "O&O&:putenv",
8869 PyUnicode_FSConverter, &os1,
8870 PyUnicode_FSConverter, &os2))
8871 return NULL;
8872 s1 = PyBytes_AsString(os1);
8873 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008874
Victor Stinner65170952011-11-22 22:16:17 +01008875 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008876 if (newstr == NULL) {
8877 PyErr_NoMemory();
8878 goto error;
8879 }
8880
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008884 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008886#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008887
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 /* Install the first arg and newstr in posix_putenv_garbage;
8889 * this will cause previous value to be collected. This has to
8890 * happen after the real putenv() call because the old value
8891 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008892 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 /* really not much we can do; just leak */
8894 PyErr_Clear();
8895 }
8896 else {
8897 Py_DECREF(newstr);
8898 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008899
Martin v. Löwis011e8422009-05-05 04:43:17 +00008900#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 Py_DECREF(os1);
8902 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008903#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008904 Py_RETURN_NONE;
8905
8906error:
8907#ifndef MS_WINDOWS
8908 Py_DECREF(os1);
8909 Py_DECREF(os2);
8910#endif
8911 Py_XDECREF(newstr);
8912 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008913}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008914#endif /* putenv */
8915
Guido van Rossumc524d952001-10-19 01:31:59 +00008916#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008917PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008918"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008919Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008920
8921static PyObject *
8922posix_unsetenv(PyObject *self, PyObject *args)
8923{
Victor Stinner65170952011-11-22 22:16:17 +01008924 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008925#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008926 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008927#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008928
8929 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008930
Victor Stinner65170952011-11-22 22:16:17 +01008931 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008932 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008933
Victor Stinner984890f2011-11-24 13:53:38 +01008934#ifdef HAVE_BROKEN_UNSETENV
8935 unsetenv(PyBytes_AS_STRING(name));
8936#else
Victor Stinner65170952011-11-22 22:16:17 +01008937 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008938 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008939 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008940 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008941 }
Victor Stinner984890f2011-11-24 13:53:38 +01008942#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008943
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 /* Remove the key from posix_putenv_garbage;
8945 * this will cause it to be collected. This has to
8946 * happen after the real unsetenv() call because the
8947 * old value was still accessible until then.
8948 */
Victor Stinner65170952011-11-22 22:16:17 +01008949 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 /* really not much we can do; just leak */
8951 PyErr_Clear();
8952 }
Victor Stinner65170952011-11-22 22:16:17 +01008953 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008954 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008955}
8956#endif /* unsetenv */
8957
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008958PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008959"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008960Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008961
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008963posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008964{
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 int code;
8966 char *message;
8967 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8968 return NULL;
8969 message = strerror(code);
8970 if (message == NULL) {
8971 PyErr_SetString(PyExc_ValueError,
8972 "strerror() argument out of range");
8973 return NULL;
8974 }
Victor Stinner1b579672011-12-17 05:47:23 +01008975 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008976}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008977
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008978
Guido van Rossumc9641791998-08-04 15:26:23 +00008979#ifdef HAVE_SYS_WAIT_H
8980
Fred Drake106c1a02002-04-23 15:58:02 +00008981#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008982PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008983"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008984Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008985
8986static PyObject *
8987posix_WCOREDUMP(PyObject *self, PyObject *args)
8988{
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 WAIT_TYPE status;
8990 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008991
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8993 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008994
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008996}
8997#endif /* WCOREDUMP */
8998
8999#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009000PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009001"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009002Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009003job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009004
9005static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009006posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009007{
Victor Stinner8c62be82010-05-06 00:08:46 +00009008 WAIT_TYPE status;
9009 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009010
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9012 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009013
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009015}
9016#endif /* WIFCONTINUED */
9017
Guido van Rossumc9641791998-08-04 15:26:23 +00009018#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009019PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009020"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009021Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009022
9023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009024posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009025{
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 WAIT_TYPE status;
9027 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009028
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9030 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009031
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009033}
9034#endif /* WIFSTOPPED */
9035
9036#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009037PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009038"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009039Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009040
9041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009042posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009043{
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 WAIT_TYPE status;
9045 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009046
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9048 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009049
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009051}
9052#endif /* WIFSIGNALED */
9053
9054#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009055PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009056"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009057Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009058system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009059
9060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009061posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009062{
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 WAIT_TYPE status;
9064 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009065
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9067 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009068
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009070}
9071#endif /* WIFEXITED */
9072
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009073#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009074PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009075"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009076Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009077
9078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009079posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009080{
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 WAIT_TYPE status;
9082 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009083
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9085 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009086
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009088}
9089#endif /* WEXITSTATUS */
9090
9091#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009092PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009093"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009094Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009095value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009096
9097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009098posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009099{
Victor Stinner8c62be82010-05-06 00:08:46 +00009100 WAIT_TYPE status;
9101 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009102
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9104 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009105
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009107}
9108#endif /* WTERMSIG */
9109
9110#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009111PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009112"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009113Return the signal that stopped the process that provided\n\
9114the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009115
9116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009117posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009118{
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 WAIT_TYPE status;
9120 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009121
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9123 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009124
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009126}
9127#endif /* WSTOPSIG */
9128
9129#endif /* HAVE_SYS_WAIT_H */
9130
9131
Thomas Wouters477c8d52006-05-27 19:21:47 +00009132#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009133#ifdef _SCO_DS
9134/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9135 needed definitions in sys/statvfs.h */
9136#define _SVID3
9137#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009138#include <sys/statvfs.h>
9139
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009140static PyObject*
9141_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9143 if (v == NULL)
9144 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009145
9146#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9148 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9149 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9150 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9151 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9152 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9153 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9154 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9155 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9156 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009157#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9159 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9160 PyStructSequence_SET_ITEM(v, 2,
9161 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9162 PyStructSequence_SET_ITEM(v, 3,
9163 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9164 PyStructSequence_SET_ITEM(v, 4,
9165 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9166 PyStructSequence_SET_ITEM(v, 5,
9167 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9168 PyStructSequence_SET_ITEM(v, 6,
9169 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9170 PyStructSequence_SET_ITEM(v, 7,
9171 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9172 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9173 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009174#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009175 if (PyErr_Occurred()) {
9176 Py_DECREF(v);
9177 return NULL;
9178 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009179
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009181}
9182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009183PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009184"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009185Perform an fstatvfs system call on the given fd.\n\
9186Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009187
9188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009189posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009190{
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 int fd, res;
9192 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009193
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9195 return NULL;
9196 Py_BEGIN_ALLOW_THREADS
9197 res = fstatvfs(fd, &st);
9198 Py_END_ALLOW_THREADS
9199 if (res != 0)
9200 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009201
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009203}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009204#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009205
9206
Thomas Wouters477c8d52006-05-27 19:21:47 +00009207#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009208#include <sys/statvfs.h>
9209
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009210PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009211"statvfs(path)\n\n\
9212Perform a statvfs system call on the given path.\n\
9213\n\
9214path may always be specified as a string.\n\
9215On some platforms, path may also be specified as an open file descriptor.\n\
9216 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009217
9218static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009219posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009220{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009221 static char *keywords[] = {"path", NULL};
9222 path_t path;
9223 int result;
9224 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009226
Larry Hastings9cf065c2012-06-22 16:30:09 -07009227 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009228 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009229#ifdef HAVE_FSTATVFS
9230 path.allow_fd = 1;
9231#endif
9232 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9233 path_converter, &path
9234 ))
9235 return NULL;
9236
9237 Py_BEGIN_ALLOW_THREADS
9238#ifdef HAVE_FSTATVFS
9239 if (path.fd != -1) {
9240#ifdef __APPLE__
9241 /* handle weak-linking on Mac OS X 10.3 */
9242 if (fstatvfs == NULL) {
9243 fd_specified("statvfs", path.fd);
9244 goto exit;
9245 }
9246#endif
9247 result = fstatvfs(path.fd, &st);
9248 }
9249 else
9250#endif
9251 result = statvfs(path.narrow, &st);
9252 Py_END_ALLOW_THREADS
9253
9254 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009255 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009256 goto exit;
9257 }
9258
9259 return_value = _pystatvfs_fromstructstatvfs(st);
9260
9261exit:
9262 path_cleanup(&path);
9263 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009264}
9265#endif /* HAVE_STATVFS */
9266
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009267#ifdef MS_WINDOWS
9268PyDoc_STRVAR(win32__getdiskusage__doc__,
9269"_getdiskusage(path) -> (total, free)\n\n\
9270Return disk usage statistics about the given path as (total, free) tuple.");
9271
9272static PyObject *
9273win32__getdiskusage(PyObject *self, PyObject *args)
9274{
9275 BOOL retval;
9276 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009277 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009278
Victor Stinner6139c1b2011-11-09 22:14:14 +01009279 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009280 return NULL;
9281
9282 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009283 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009284 Py_END_ALLOW_THREADS
9285 if (retval == 0)
9286 return PyErr_SetFromWindowsErr(0);
9287
9288 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9289}
9290#endif
9291
9292
Fred Drakec9680921999-12-13 16:37:25 +00009293/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9294 * It maps strings representing configuration variable names to
9295 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009296 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009297 * rarely-used constants. There are three separate tables that use
9298 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009299 *
9300 * This code is always included, even if none of the interfaces that
9301 * need it are included. The #if hackery needed to avoid it would be
9302 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009303 */
9304struct constdef {
9305 char *name;
9306 long value;
9307};
9308
Fred Drake12c6e2d1999-12-14 21:25:03 +00009309static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009310conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009311 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009312{
Christian Heimes217cfd12007-12-02 14:31:20 +00009313 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009314 *valuep = PyLong_AS_LONG(arg);
9315 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009316 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009317 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009318 /* look up the value in the table using a binary search */
9319 size_t lo = 0;
9320 size_t mid;
9321 size_t hi = tablesize;
9322 int cmp;
9323 const char *confname;
9324 if (!PyUnicode_Check(arg)) {
9325 PyErr_SetString(PyExc_TypeError,
9326 "configuration names must be strings or integers");
9327 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009329 confname = _PyUnicode_AsString(arg);
9330 if (confname == NULL)
9331 return 0;
9332 while (lo < hi) {
9333 mid = (lo + hi) / 2;
9334 cmp = strcmp(confname, table[mid].name);
9335 if (cmp < 0)
9336 hi = mid;
9337 else if (cmp > 0)
9338 lo = mid + 1;
9339 else {
9340 *valuep = table[mid].value;
9341 return 1;
9342 }
9343 }
9344 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9345 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009347}
9348
9349
9350#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9351static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009352#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009354#endif
9355#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009357#endif
Fred Drakec9680921999-12-13 16:37:25 +00009358#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009403#ifdef _PC_ACL_ENABLED
9404 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9405#endif
9406#ifdef _PC_MIN_HOLE_SIZE
9407 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9408#endif
9409#ifdef _PC_ALLOC_SIZE_MIN
9410 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9411#endif
9412#ifdef _PC_REC_INCR_XFER_SIZE
9413 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9414#endif
9415#ifdef _PC_REC_MAX_XFER_SIZE
9416 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9417#endif
9418#ifdef _PC_REC_MIN_XFER_SIZE
9419 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9420#endif
9421#ifdef _PC_REC_XFER_ALIGN
9422 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9423#endif
9424#ifdef _PC_SYMLINK_MAX
9425 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9426#endif
9427#ifdef _PC_XATTR_ENABLED
9428 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9429#endif
9430#ifdef _PC_XATTR_EXISTS
9431 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9432#endif
9433#ifdef _PC_TIMESTAMP_RESOLUTION
9434 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9435#endif
Fred Drakec9680921999-12-13 16:37:25 +00009436};
9437
Fred Drakec9680921999-12-13 16:37:25 +00009438static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009439conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009440{
9441 return conv_confname(arg, valuep, posix_constants_pathconf,
9442 sizeof(posix_constants_pathconf)
9443 / sizeof(struct constdef));
9444}
9445#endif
9446
9447#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009448PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009449"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009450Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009451If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009452
9453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009454posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009455{
9456 PyObject *result = NULL;
9457 int name, fd;
9458
Fred Drake12c6e2d1999-12-14 21:25:03 +00009459 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9460 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009461 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009462
Stefan Krah0e803b32010-11-26 16:16:47 +00009463 errno = 0;
9464 limit = fpathconf(fd, name);
9465 if (limit == -1 && errno != 0)
9466 posix_error();
9467 else
9468 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009469 }
9470 return result;
9471}
9472#endif
9473
9474
9475#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009476PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009477"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009478Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009479If there is no limit, return -1.\n\
9480On some platforms, path may also be specified as an open file descriptor.\n\
9481 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009482
9483static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009484posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009485{
Georg Brandl306336b2012-06-24 12:55:33 +02009486 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009487 PyObject *result = NULL;
9488 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009489 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009490
Georg Brandl306336b2012-06-24 12:55:33 +02009491 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009492 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009493#ifdef HAVE_FPATHCONF
9494 path.allow_fd = 1;
9495#endif
9496 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9497 path_converter, &path,
9498 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009500
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009502#ifdef HAVE_FPATHCONF
9503 if (path.fd != -1)
9504 limit = fpathconf(path.fd, name);
9505 else
9506#endif
9507 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 if (limit == -1 && errno != 0) {
9509 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009510 /* could be a path or name problem */
9511 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009512 else
Victor Stinner292c8352012-10-30 02:17:38 +01009513 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 }
9515 else
9516 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009517 }
Georg Brandl306336b2012-06-24 12:55:33 +02009518 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009519 return result;
9520}
9521#endif
9522
9523#ifdef HAVE_CONFSTR
9524static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009525#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009527#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009528#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009530#endif
9531#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009533#endif
Fred Draked86ed291999-12-15 15:34:33 +00009534#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
9540#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009542#endif
9543#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009545#endif
Fred Drakec9680921999-12-13 16:37:25 +00009546#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
Fred Draked86ed291999-12-15 15:34:33 +00009570#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
Fred Drakec9680921999-12-13 16:37:25 +00009573#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
Fred Draked86ed291999-12-15 15:34:33 +00009576#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
9579#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
9582#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
9585#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
Fred Drakec9680921999-12-13 16:37:25 +00009588#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
Fred Draked86ed291999-12-15 15:34:33 +00009636#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
9672#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
Fred Drakec9680921999-12-13 16:37:25 +00009675};
9676
9677static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009678conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009679{
9680 return conv_confname(arg, valuep, posix_constants_confstr,
9681 sizeof(posix_constants_confstr)
9682 / sizeof(struct constdef));
9683}
9684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009685PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009686"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009687Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009688
9689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009690posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009691{
9692 PyObject *result = NULL;
9693 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009694 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009695 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009696
Victor Stinnercb043522010-09-10 23:49:04 +00009697 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9698 return NULL;
9699
9700 errno = 0;
9701 len = confstr(name, buffer, sizeof(buffer));
9702 if (len == 0) {
9703 if (errno) {
9704 posix_error();
9705 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009706 }
9707 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009708 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009709 }
9710 }
Victor Stinnercb043522010-09-10 23:49:04 +00009711
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009712 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009713 char *buf = PyMem_Malloc(len);
9714 if (buf == NULL)
9715 return PyErr_NoMemory();
9716 confstr(name, buf, len);
9717 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9718 PyMem_Free(buf);
9719 }
9720 else
9721 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009722 return result;
9723}
9724#endif
9725
9726
9727#ifdef HAVE_SYSCONF
9728static struct constdef posix_constants_sysconf[] = {
9729#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Draked86ed291999-12-15 15:34:33 +00009759#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
9762#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009764#endif
Fred Drakec9680921999-12-13 16:37:25 +00009765#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
Fred Drakec9680921999-12-13 16:37:25 +00009768#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
Fred Draked86ed291999-12-15 15:34:33 +00009783#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009785#endif
Fred Drakec9680921999-12-13 16:37:25 +00009786#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
Fred Draked86ed291999-12-15 15:34:33 +00009801#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009803#endif
Fred Drakec9680921999-12-13 16:37:25 +00009804#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
Fred Draked86ed291999-12-15 15:34:33 +00009873#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009875#endif
Fred Drakec9680921999-12-13 16:37:25 +00009876#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
Fred Draked86ed291999-12-15 15:34:33 +00009885#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009887#endif
Fred Drakec9680921999-12-13 16:37:25 +00009888#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
Fred Draked86ed291999-12-15 15:34:33 +00009891#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009893#endif
9894#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009896#endif
Fred Drakec9680921999-12-13 16:37:25 +00009897#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
Fred Draked86ed291999-12-15 15:34:33 +00009909#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
Fred Drakec9680921999-12-13 16:37:25 +00009912#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
Fred Draked86ed291999-12-15 15:34:33 +00009933#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
Fred Drakec9680921999-12-13 16:37:25 +00009936#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
Fred Draked86ed291999-12-15 15:34:33 +00009942#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009944#endif
Fred Drakec9680921999-12-13 16:37:25 +00009945#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
Fred Draked86ed291999-12-15 15:34:33 +00009972#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
9975#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009977#endif
Fred Drakec9680921999-12-13 16:37:25 +00009978#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
Fred Draked86ed291999-12-15 15:34:33 +000010083#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010085#endif
Fred Drakec9680921999-12-13 16:37:25 +000010086#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221};
10222
10223static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010224conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010225{
10226 return conv_confname(arg, valuep, posix_constants_sysconf,
10227 sizeof(posix_constants_sysconf)
10228 / sizeof(struct constdef));
10229}
10230
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010231PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010232"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010233Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010234
10235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010236posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010237{
10238 PyObject *result = NULL;
10239 int name;
10240
10241 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010242 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010243
10244 errno = 0;
10245 value = sysconf(name);
10246 if (value == -1 && errno != 0)
10247 posix_error();
10248 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010249 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010250 }
10251 return result;
10252}
10253#endif
10254
10255
Fred Drakebec628d1999-12-15 18:31:10 +000010256/* This code is used to ensure that the tables of configuration value names
10257 * are in sorted order as required by conv_confname(), and also to build the
10258 * the exported dictionaries that are used to publish information about the
10259 * names available on the host platform.
10260 *
10261 * Sorting the table at runtime ensures that the table is properly ordered
10262 * when used, even for platforms we're not able to test on. It also makes
10263 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010264 */
Fred Drakebec628d1999-12-15 18:31:10 +000010265
10266static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010267cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010268{
10269 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010271 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010273
10274 return strcmp(c1->name, c2->name);
10275}
10276
10277static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010278setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010280{
Fred Drakebec628d1999-12-15 18:31:10 +000010281 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010282 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010283
10284 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10285 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010286 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010288
Barry Warsaw3155db32000-04-13 15:20:40 +000010289 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 PyObject *o = PyLong_FromLong(table[i].value);
10291 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10292 Py_XDECREF(o);
10293 Py_DECREF(d);
10294 return -1;
10295 }
10296 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010297 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010298 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010299}
10300
Fred Drakebec628d1999-12-15 18:31:10 +000010301/* Return -1 on failure, 0 on success. */
10302static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010303setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010304{
10305#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010306 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010307 sizeof(posix_constants_pathconf)
10308 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010309 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010310 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010311#endif
10312#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010313 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010314 sizeof(posix_constants_confstr)
10315 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010316 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010317 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010318#endif
10319#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010320 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010321 sizeof(posix_constants_sysconf)
10322 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010323 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010324 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010325#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010326 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010327}
Fred Draked86ed291999-12-15 15:34:33 +000010328
10329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010330PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010331"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010332Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010333in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010334
10335static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010336posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010337{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338 abort();
10339 /*NOTREACHED*/
10340 Py_FatalError("abort() called from Python code didn't abort!");
10341 return NULL;
10342}
Fred Drakebec628d1999-12-15 18:31:10 +000010343
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010344#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010345PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010346"startfile(filepath [, operation]) - Start a file with its associated\n\
10347application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010348\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010349When \"operation\" is not specified or \"open\", this acts like\n\
10350double-clicking the file in Explorer, or giving the file name as an\n\
10351argument to the DOS \"start\" command: the file is opened with whatever\n\
10352application (if any) its extension is associated.\n\
10353When another \"operation\" is given, it specifies what should be done with\n\
10354the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010355\n\
10356startfile returns as soon as the associated application is launched.\n\
10357There is no option to wait for the application to close, and no way\n\
10358to retrieve the application's exit status.\n\
10359\n\
10360The filepath is relative to the current directory. If you want to use\n\
10361an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010362the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010363
10364static PyObject *
10365win32_startfile(PyObject *self, PyObject *args)
10366{
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 PyObject *ofilepath;
10368 char *filepath;
10369 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010370 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010372
Victor Stinnereb5657a2011-09-30 01:44:27 +020010373 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 if (!PyArg_ParseTuple(args, "U|s:startfile",
10375 &unipath, &operation)) {
10376 PyErr_Clear();
10377 goto normal;
10378 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010379
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010381 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010383 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 PyErr_Clear();
10385 operation = NULL;
10386 goto normal;
10387 }
10388 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010389
Victor Stinnereb5657a2011-09-30 01:44:27 +020010390 wpath = PyUnicode_AsUnicode(unipath);
10391 if (wpath == NULL)
10392 goto normal;
10393 if (uoperation) {
10394 woperation = PyUnicode_AsUnicode(uoperation);
10395 if (woperation == NULL)
10396 goto normal;
10397 }
10398 else
10399 woperation = NULL;
10400
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010402 rc = ShellExecuteW((HWND)0, woperation, wpath,
10403 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 Py_END_ALLOW_THREADS
10405
Victor Stinnereb5657a2011-09-30 01:44:27 +020010406 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010408 win32_error_object("startfile", unipath);
10409 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 }
10411 Py_INCREF(Py_None);
10412 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010413
10414normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10416 PyUnicode_FSConverter, &ofilepath,
10417 &operation))
10418 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010419 if (win32_warn_bytes_api()) {
10420 Py_DECREF(ofilepath);
10421 return NULL;
10422 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 filepath = PyBytes_AsString(ofilepath);
10424 Py_BEGIN_ALLOW_THREADS
10425 rc = ShellExecute((HWND)0, operation, filepath,
10426 NULL, NULL, SW_SHOWNORMAL);
10427 Py_END_ALLOW_THREADS
10428 if (rc <= (HINSTANCE)32) {
10429 PyObject *errval = win32_error("startfile", filepath);
10430 Py_DECREF(ofilepath);
10431 return errval;
10432 }
10433 Py_DECREF(ofilepath);
10434 Py_INCREF(Py_None);
10435 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010436}
10437#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010438
Martin v. Löwis438b5342002-12-27 10:16:42 +000010439#ifdef HAVE_GETLOADAVG
10440PyDoc_STRVAR(posix_getloadavg__doc__,
10441"getloadavg() -> (float, float, float)\n\n\
10442Return the number of processes in the system run queue averaged over\n\
10443the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10444was unobtainable");
10445
10446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010447posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010448{
10449 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010450 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010451 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10452 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010453 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010454 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010455}
10456#endif
10457
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010458PyDoc_STRVAR(device_encoding__doc__,
10459"device_encoding(fd) -> str\n\n\
10460Return a string describing the encoding of the device\n\
10461if the output is a terminal; else return None.");
10462
10463static PyObject *
10464device_encoding(PyObject *self, PyObject *args)
10465{
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010467
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10469 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010470
10471 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010472}
10473
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010474#ifdef HAVE_SETRESUID
10475PyDoc_STRVAR(posix_setresuid__doc__,
10476"setresuid(ruid, euid, suid)\n\n\
10477Set the current process's real, effective, and saved user ids.");
10478
10479static PyObject*
10480posix_setresuid (PyObject *self, PyObject *args)
10481{
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010483 uid_t ruid, euid, suid;
10484 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10485 _Py_Uid_Converter, &ruid,
10486 _Py_Uid_Converter, &euid,
10487 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 return NULL;
10489 if (setresuid(ruid, euid, suid) < 0)
10490 return posix_error();
10491 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010492}
10493#endif
10494
10495#ifdef HAVE_SETRESGID
10496PyDoc_STRVAR(posix_setresgid__doc__,
10497"setresgid(rgid, egid, sgid)\n\n\
10498Set the current process's real, effective, and saved group ids.");
10499
10500static PyObject*
10501posix_setresgid (PyObject *self, PyObject *args)
10502{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010503 gid_t rgid, egid, sgid;
10504 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10505 _Py_Gid_Converter, &rgid,
10506 _Py_Gid_Converter, &egid,
10507 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 return NULL;
10509 if (setresgid(rgid, egid, sgid) < 0)
10510 return posix_error();
10511 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010512}
10513#endif
10514
10515#ifdef HAVE_GETRESUID
10516PyDoc_STRVAR(posix_getresuid__doc__,
10517"getresuid() -> (ruid, euid, suid)\n\n\
10518Get tuple of the current process's real, effective, and saved user ids.");
10519
10520static PyObject*
10521posix_getresuid (PyObject *self, PyObject *noargs)
10522{
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 if (getresuid(&ruid, &euid, &suid) < 0)
10525 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010526 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10527 _PyLong_FromUid(euid),
10528 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010529}
10530#endif
10531
10532#ifdef HAVE_GETRESGID
10533PyDoc_STRVAR(posix_getresgid__doc__,
10534"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010535Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010536
10537static PyObject*
10538posix_getresgid (PyObject *self, PyObject *noargs)
10539{
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 if (getresgid(&rgid, &egid, &sgid) < 0)
10542 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010543 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10544 _PyLong_FromGid(egid),
10545 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010546}
10547#endif
10548
Benjamin Peterson9428d532011-09-14 11:45:52 -040010549#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010550
Benjamin Peterson799bd802011-08-31 22:15:17 -040010551PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010552"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10553Return the value of extended attribute attribute on path.\n\
10554\n\
10555path may be either a string or an open file descriptor.\n\
10556If follow_symlinks is False, and the last element of the path is a symbolic\n\
10557 link, getxattr will examine the symbolic link itself instead of the file\n\
10558 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010559
10560static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010561posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010562{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010563 path_t path;
10564 path_t attribute;
10565 int follow_symlinks = 1;
10566 PyObject *buffer = NULL;
10567 int i;
10568 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010569
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 memset(&path, 0, sizeof(path));
10571 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010572 path.function_name = "getxattr";
10573 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574 path.allow_fd = 1;
10575 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10576 path_converter, &path,
10577 path_converter, &attribute,
10578 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010579 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580
Larry Hastings9cf065c2012-06-22 16:30:09 -070010581 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10582 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584 for (i = 0; ; i++) {
10585 void *ptr;
10586 ssize_t result;
10587 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10588 Py_ssize_t buffer_size = buffer_sizes[i];
10589 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010590 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 goto exit;
10592 }
10593 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10594 if (!buffer)
10595 goto exit;
10596 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010597
Larry Hastings9cf065c2012-06-22 16:30:09 -070010598 Py_BEGIN_ALLOW_THREADS;
10599 if (path.fd >= 0)
10600 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10601 else if (follow_symlinks)
10602 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10603 else
10604 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10605 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010606
Larry Hastings9cf065c2012-06-22 16:30:09 -070010607 if (result < 0) {
10608 Py_DECREF(buffer);
10609 buffer = NULL;
10610 if (errno == ERANGE)
10611 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010612 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613 goto exit;
10614 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010615
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 if (result != buffer_size) {
10617 /* Can only shrink. */
10618 _PyBytes_Resize(&buffer, result);
10619 }
10620 break;
10621 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622
Larry Hastings9cf065c2012-06-22 16:30:09 -070010623exit:
10624 path_cleanup(&path);
10625 path_cleanup(&attribute);
10626 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010627}
10628
10629PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010630"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10631Set extended attribute attribute on path to value.\n\
10632path may be either a string or an open file descriptor.\n\
10633If follow_symlinks is False, and the last element of the path is a symbolic\n\
10634 link, setxattr will modify the symbolic link itself instead of the file\n\
10635 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010636
10637static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010638posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010640 path_t path;
10641 path_t attribute;
10642 Py_buffer value;
10643 int flags = 0;
10644 int follow_symlinks = 1;
10645 int result;
10646 PyObject *return_value = NULL;
10647 static char *keywords[] = {"path", "attribute", "value",
10648 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010649
Larry Hastings9cf065c2012-06-22 16:30:09 -070010650 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010651 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010652 path.allow_fd = 1;
10653 memset(&attribute, 0, sizeof(attribute));
10654 memset(&value, 0, sizeof(value));
10655 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10656 keywords,
10657 path_converter, &path,
10658 path_converter, &attribute,
10659 &value, &flags,
10660 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010661 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010662
10663 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10664 goto exit;
10665
Benjamin Peterson799bd802011-08-31 22:15:17 -040010666 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010667 if (path.fd > -1)
10668 result = fsetxattr(path.fd, attribute.narrow,
10669 value.buf, value.len, flags);
10670 else if (follow_symlinks)
10671 result = setxattr(path.narrow, attribute.narrow,
10672 value.buf, value.len, flags);
10673 else
10674 result = lsetxattr(path.narrow, attribute.narrow,
10675 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010676 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677
Larry Hastings9cf065c2012-06-22 16:30:09 -070010678 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010679 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010680 goto exit;
10681 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682
Larry Hastings9cf065c2012-06-22 16:30:09 -070010683 return_value = Py_None;
10684 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010685
Larry Hastings9cf065c2012-06-22 16:30:09 -070010686exit:
10687 path_cleanup(&path);
10688 path_cleanup(&attribute);
10689 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010690
Larry Hastings9cf065c2012-06-22 16:30:09 -070010691 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010692}
10693
10694PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010695"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10696Remove extended attribute attribute on path.\n\
10697path may be either a string or an open file descriptor.\n\
10698If follow_symlinks is False, and the last element of the path is a symbolic\n\
10699 link, removexattr will modify the symbolic link itself instead of the file\n\
10700 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010701
10702static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010703posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 path_t path;
10706 path_t attribute;
10707 int follow_symlinks = 1;
10708 int result;
10709 PyObject *return_value = NULL;
10710 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010711
Larry Hastings9cf065c2012-06-22 16:30:09 -070010712 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010713 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010714 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010715 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010716 path.allow_fd = 1;
10717 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10718 keywords,
10719 path_converter, &path,
10720 path_converter, &attribute,
10721 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010722 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010723
10724 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10725 goto exit;
10726
Benjamin Peterson799bd802011-08-31 22:15:17 -040010727 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 if (path.fd > -1)
10729 result = fremovexattr(path.fd, attribute.narrow);
10730 else if (follow_symlinks)
10731 result = removexattr(path.narrow, attribute.narrow);
10732 else
10733 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010734 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010735
Larry Hastings9cf065c2012-06-22 16:30:09 -070010736 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010737 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010738 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010739 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010740
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741 return_value = Py_None;
10742 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743
Larry Hastings9cf065c2012-06-22 16:30:09 -070010744exit:
10745 path_cleanup(&path);
10746 path_cleanup(&attribute);
10747
10748 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010749}
10750
10751PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752"listxattr(path='.', *, follow_symlinks=True)\n\n\
10753Return a list of extended attributes on path.\n\
10754\n\
10755path may be either None, a string, or an open file descriptor.\n\
10756if path is None, listxattr will examine the current directory.\n\
10757If follow_symlinks is False, and the last element of the path is a symbolic\n\
10758 link, listxattr will examine the symbolic link itself instead of the file\n\
10759 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010760
10761static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010763{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010764 path_t path;
10765 int follow_symlinks = 1;
10766 Py_ssize_t i;
10767 PyObject *result = NULL;
10768 char *buffer = NULL;
10769 char *name;
10770 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010771
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010773 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 path.allow_fd = 1;
10775 path.fd = -1;
10776 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10777 path_converter, &path,
10778 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010779 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010780
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10782 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783
Larry Hastings9cf065c2012-06-22 16:30:09 -070010784 name = path.narrow ? path.narrow : ".";
10785 for (i = 0; ; i++) {
10786 char *start, *trace, *end;
10787 ssize_t length;
10788 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10789 Py_ssize_t buffer_size = buffer_sizes[i];
10790 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010791 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010792 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010793 break;
10794 }
10795 buffer = PyMem_MALLOC(buffer_size);
10796 if (!buffer) {
10797 PyErr_NoMemory();
10798 break;
10799 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010800
Larry Hastings9cf065c2012-06-22 16:30:09 -070010801 Py_BEGIN_ALLOW_THREADS;
10802 if (path.fd > -1)
10803 length = flistxattr(path.fd, buffer, buffer_size);
10804 else if (follow_symlinks)
10805 length = listxattr(name, buffer, buffer_size);
10806 else
10807 length = llistxattr(name, buffer, buffer_size);
10808 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010811 if (errno == ERANGE) {
10812 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010813 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010815 }
Victor Stinner292c8352012-10-30 02:17:38 +010010816 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 break;
10818 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010819
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 result = PyList_New(0);
10821 if (!result) {
10822 goto exit;
10823 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010824
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 end = buffer + length;
10826 for (trace = start = buffer; trace != end; trace++) {
10827 if (!*trace) {
10828 int error;
10829 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10830 trace - start);
10831 if (!attribute) {
10832 Py_DECREF(result);
10833 result = NULL;
10834 goto exit;
10835 }
10836 error = PyList_Append(result, attribute);
10837 Py_DECREF(attribute);
10838 if (error) {
10839 Py_DECREF(result);
10840 result = NULL;
10841 goto exit;
10842 }
10843 start = trace + 1;
10844 }
10845 }
10846 break;
10847 }
10848exit:
10849 path_cleanup(&path);
10850 if (buffer)
10851 PyMem_FREE(buffer);
10852 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010853}
10854
Benjamin Peterson9428d532011-09-14 11:45:52 -040010855#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010856
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010857
Georg Brandl2fb477c2012-02-21 00:33:36 +010010858PyDoc_STRVAR(posix_urandom__doc__,
10859"urandom(n) -> str\n\n\
10860Return n random bytes suitable for cryptographic use.");
10861
10862static PyObject *
10863posix_urandom(PyObject *self, PyObject *args)
10864{
10865 Py_ssize_t size;
10866 PyObject *result;
10867 int ret;
10868
10869 /* Read arguments */
10870 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10871 return NULL;
10872 if (size < 0)
10873 return PyErr_Format(PyExc_ValueError,
10874 "negative argument not allowed");
10875 result = PyBytes_FromStringAndSize(NULL, size);
10876 if (result == NULL)
10877 return NULL;
10878
10879 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10880 PyBytes_GET_SIZE(result));
10881 if (ret == -1) {
10882 Py_DECREF(result);
10883 return NULL;
10884 }
10885 return result;
10886}
10887
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010888/* Terminal size querying */
10889
10890static PyTypeObject TerminalSizeType;
10891
10892PyDoc_STRVAR(TerminalSize_docstring,
10893 "A tuple of (columns, lines) for holding terminal window size");
10894
10895static PyStructSequence_Field TerminalSize_fields[] = {
10896 {"columns", "width of the terminal window in characters"},
10897 {"lines", "height of the terminal window in characters"},
10898 {NULL, NULL}
10899};
10900
10901static PyStructSequence_Desc TerminalSize_desc = {
10902 "os.terminal_size",
10903 TerminalSize_docstring,
10904 TerminalSize_fields,
10905 2,
10906};
10907
10908#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10909PyDoc_STRVAR(termsize__doc__,
10910 "Return the size of the terminal window as (columns, lines).\n" \
10911 "\n" \
10912 "The optional argument fd (default standard output) specifies\n" \
10913 "which file descriptor should be queried.\n" \
10914 "\n" \
10915 "If the file descriptor is not connected to a terminal, an OSError\n" \
10916 "is thrown.\n" \
10917 "\n" \
10918 "This function will only be defined if an implementation is\n" \
10919 "available for this system.\n" \
10920 "\n" \
10921 "shutil.get_terminal_size is the high-level function which should \n" \
10922 "normally be used, os.get_terminal_size is the low-level implementation.");
10923
10924static PyObject*
10925get_terminal_size(PyObject *self, PyObject *args)
10926{
10927 int columns, lines;
10928 PyObject *termsize;
10929
10930 int fd = fileno(stdout);
10931 /* Under some conditions stdout may not be connected and
10932 * fileno(stdout) may point to an invalid file descriptor. For example
10933 * GUI apps don't have valid standard streams by default.
10934 *
10935 * If this happens, and the optional fd argument is not present,
10936 * the ioctl below will fail returning EBADF. This is what we want.
10937 */
10938
10939 if (!PyArg_ParseTuple(args, "|i", &fd))
10940 return NULL;
10941
10942#ifdef TERMSIZE_USE_IOCTL
10943 {
10944 struct winsize w;
10945 if (ioctl(fd, TIOCGWINSZ, &w))
10946 return PyErr_SetFromErrno(PyExc_OSError);
10947 columns = w.ws_col;
10948 lines = w.ws_row;
10949 }
10950#endif /* TERMSIZE_USE_IOCTL */
10951
10952#ifdef TERMSIZE_USE_CONIO
10953 {
10954 DWORD nhandle;
10955 HANDLE handle;
10956 CONSOLE_SCREEN_BUFFER_INFO csbi;
10957 switch (fd) {
10958 case 0: nhandle = STD_INPUT_HANDLE;
10959 break;
10960 case 1: nhandle = STD_OUTPUT_HANDLE;
10961 break;
10962 case 2: nhandle = STD_ERROR_HANDLE;
10963 break;
10964 default:
10965 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10966 }
10967 handle = GetStdHandle(nhandle);
10968 if (handle == NULL)
10969 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10970 if (handle == INVALID_HANDLE_VALUE)
10971 return PyErr_SetFromWindowsErr(0);
10972
10973 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10974 return PyErr_SetFromWindowsErr(0);
10975
10976 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10977 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10978 }
10979#endif /* TERMSIZE_USE_CONIO */
10980
10981 termsize = PyStructSequence_New(&TerminalSizeType);
10982 if (termsize == NULL)
10983 return NULL;
10984 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10985 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10986 if (PyErr_Occurred()) {
10987 Py_DECREF(termsize);
10988 return NULL;
10989 }
10990 return termsize;
10991}
10992#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10993
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010994PyDoc_STRVAR(posix_cpu_count__doc__,
10995"cpu_count() -> integer\n\n\
10996Return the number of CPUs in the system, or None if this value cannot be\n\
10997established.");
10998
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010999static PyObject *
11000posix_cpu_count(PyObject *self)
11001{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011002 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011003#ifdef MS_WINDOWS
11004 SYSTEM_INFO sysinfo;
11005 GetSystemInfo(&sysinfo);
11006 ncpu = sysinfo.dwNumberOfProcessors;
11007#elif defined(__hpux)
11008 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11009#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11010 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011011#elif defined(__DragonFly__) || \
11012 defined(__OpenBSD__) || \
11013 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011014 defined(__NetBSD__) || \
11015 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011016 int mib[2];
11017 size_t len = sizeof(ncpu);
11018 mib[0] = CTL_HW;
11019 mib[1] = HW_NCPU;
11020 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11021 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011022#endif
11023 if (ncpu >= 1)
11024 return PyLong_FromLong(ncpu);
11025 else
11026 Py_RETURN_NONE;
11027}
11028
Victor Stinnerdaf45552013-08-28 00:53:59 +020011029PyDoc_STRVAR(get_inheritable__doc__,
11030 "get_inheritable(fd) -> bool\n" \
11031 "\n" \
11032 "Get the close-on-exe flag of the specified file descriptor.");
11033
11034static PyObject*
11035posix_get_inheritable(PyObject *self, PyObject *args)
11036{
11037 int fd;
11038 int inheritable;
11039
11040 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11041 return NULL;
11042
11043 if (!_PyVerify_fd(fd))
11044 return posix_error();
11045
11046 inheritable = _Py_get_inheritable(fd);
11047 if (inheritable < 0)
11048 return NULL;
11049 return PyBool_FromLong(inheritable);
11050}
11051
11052PyDoc_STRVAR(set_inheritable__doc__,
11053 "set_inheritable(fd, inheritable)\n" \
11054 "\n" \
11055 "Set the inheritable flag of the specified file descriptor.");
11056
11057static PyObject*
11058posix_set_inheritable(PyObject *self, PyObject *args)
11059{
11060 int fd, inheritable;
11061
11062 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11063 return NULL;
11064
11065 if (!_PyVerify_fd(fd))
11066 return posix_error();
11067
11068 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11069 return NULL;
11070 Py_RETURN_NONE;
11071}
11072
11073
11074#ifdef MS_WINDOWS
11075PyDoc_STRVAR(get_handle_inheritable__doc__,
11076 "get_handle_inheritable(fd) -> bool\n" \
11077 "\n" \
11078 "Get the close-on-exe flag of the specified file descriptor.");
11079
11080static PyObject*
11081posix_get_handle_inheritable(PyObject *self, PyObject *args)
11082{
11083 Py_intptr_t handle;
11084 DWORD flags;
11085
11086 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11087 return NULL;
11088
11089 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11090 PyErr_SetFromWindowsErr(0);
11091 return NULL;
11092 }
11093
11094 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11095}
11096
11097PyDoc_STRVAR(set_handle_inheritable__doc__,
11098 "set_handle_inheritable(fd, inheritable)\n" \
11099 "\n" \
11100 "Set the inheritable flag of the specified handle.");
11101
11102static PyObject*
11103posix_set_handle_inheritable(PyObject *self, PyObject *args)
11104{
11105 int inheritable = 1;
11106 Py_intptr_t handle;
11107 DWORD flags;
11108
11109 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11110 &handle, &inheritable))
11111 return NULL;
11112
11113 if (inheritable)
11114 flags = HANDLE_FLAG_INHERIT;
11115 else
11116 flags = 0;
11117 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11118 PyErr_SetFromWindowsErr(0);
11119 return NULL;
11120 }
11121 Py_RETURN_NONE;
11122}
11123#endif /* MS_WINDOWS */
11124
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011125
Larry Hastings7726ac92014-01-31 22:03:12 -080011126/*[clinic input]
11127dump buffer
11128[clinic start generated code]*/
11129
11130#ifndef OS_TTYNAME_METHODDEF
11131 #define OS_TTYNAME_METHODDEF
11132#endif /* !defined(OS_TTYNAME_METHODDEF) */
11133/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11134
Larry Hastings31826802013-10-19 00:09:25 -070011135
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011136static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011137
11138 OS_STAT_METHODDEF
11139 OS_ACCESS_METHODDEF
11140 OS_TTYNAME_METHODDEF
11141
Larry Hastings9cf065c2012-06-22 16:30:09 -070011142 {"chdir", (PyCFunction)posix_chdir,
11143 METH_VARARGS | METH_KEYWORDS,
11144 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011145#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011146 {"chflags", (PyCFunction)posix_chflags,
11147 METH_VARARGS | METH_KEYWORDS,
11148 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011149#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011150 {"chmod", (PyCFunction)posix_chmod,
11151 METH_VARARGS | METH_KEYWORDS,
11152 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011153#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011155#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011156#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011157 {"chown", (PyCFunction)posix_chown,
11158 METH_VARARGS | METH_KEYWORDS,
11159 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011160#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011161#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011163#endif /* HAVE_LCHMOD */
11164#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011166#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011167#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011169#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011170#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011172#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011173#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011175#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011176#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011178#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11180 METH_NOARGS, posix_getcwd__doc__},
11181 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11182 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011183#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11184 {"link", (PyCFunction)posix_link,
11185 METH_VARARGS | METH_KEYWORDS,
11186 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011187#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 {"listdir", (PyCFunction)posix_listdir,
11189 METH_VARARGS | METH_KEYWORDS,
11190 posix_listdir__doc__},
11191 {"lstat", (PyCFunction)posix_lstat,
11192 METH_VARARGS | METH_KEYWORDS,
11193 posix_lstat__doc__},
11194 {"mkdir", (PyCFunction)posix_mkdir,
11195 METH_VARARGS | METH_KEYWORDS,
11196 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011197#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011199#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011200#ifdef HAVE_GETPRIORITY
11201 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11202#endif /* HAVE_GETPRIORITY */
11203#ifdef HAVE_SETPRIORITY
11204 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11205#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011206#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011207 {"readlink", (PyCFunction)posix_readlink,
11208 METH_VARARGS | METH_KEYWORDS,
11209 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011210#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011211#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 {"readlink", (PyCFunction)win_readlink,
11213 METH_VARARGS | METH_KEYWORDS,
11214 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011215#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011216 {"rename", (PyCFunction)posix_rename,
11217 METH_VARARGS | METH_KEYWORDS,
11218 posix_rename__doc__},
11219 {"replace", (PyCFunction)posix_replace,
11220 METH_VARARGS | METH_KEYWORDS,
11221 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011222 {"rmdir", (PyCFunction)posix_rmdir,
11223 METH_VARARGS | METH_KEYWORDS,
11224 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011226#if defined(HAVE_SYMLINK)
11227 {"symlink", (PyCFunction)posix_symlink,
11228 METH_VARARGS | METH_KEYWORDS,
11229 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011230#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011231#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011233#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011235#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011237#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011238 {"unlink", (PyCFunction)posix_unlink,
11239 METH_VARARGS | METH_KEYWORDS,
11240 posix_unlink__doc__},
11241 {"remove", (PyCFunction)posix_unlink,
11242 METH_VARARGS | METH_KEYWORDS,
11243 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011244 {"utime", (PyCFunction)posix_utime,
11245 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011246#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011248#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011250#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011252 {"execve", (PyCFunction)posix_execve,
11253 METH_VARARGS | METH_KEYWORDS,
11254 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011255#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011256#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11258 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011259#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011260#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011262#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011263#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011265#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011266#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011267#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011268 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11269 {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__},
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011270#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011271#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011272 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011273#endif
11274#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011275 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011276#endif
11277#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011278 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011279#endif
11280#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011281 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011282#endif
11283#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011284 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011285#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011286 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011287#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011288 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11289 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11290#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011291#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011292#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011294#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011295#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011297#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011298#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011300#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011301#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011303#endif /* HAVE_GETEUID */
11304#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011306#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011307#ifdef HAVE_GETGROUPLIST
11308 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11309#endif
Fred Drakec9680921999-12-13 16:37:25 +000011310#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011312#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011314#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011316#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011317#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011319#endif /* HAVE_GETPPID */
11320#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011322#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011323#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011325#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011326#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011328#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011329#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011331#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011332#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011334#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011335#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11337 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011338#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011339#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011341#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011342#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011344#endif /* HAVE_SETEUID */
11345#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011347#endif /* HAVE_SETEGID */
11348#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011350#endif /* HAVE_SETREUID */
11351#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011353#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011354#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011356#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011357#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011359#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011360#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011362#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011363#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011365#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011366#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011368#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011369#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011371#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011372#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011373 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011374#endif /* HAVE_WAIT3 */
11375#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011376 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011377#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011378#if defined(HAVE_WAITID) && !defined(__APPLE__)
11379 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11380#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011381#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011383#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011384#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011386#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011387#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011389#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011390#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011392#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011393#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011395#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011396#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011398#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011399 {"open", (PyCFunction)posix_open,\
11400 METH_VARARGS | METH_KEYWORDS,
11401 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011402 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11404 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11405 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011406 {"dup2", (PyCFunction)posix_dup2,
11407 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011408#ifdef HAVE_LOCKF
11409 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11410#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11412 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011413#ifdef HAVE_READV
11414 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11415#endif
11416#ifdef HAVE_PREAD
11417 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11418#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011420#ifdef HAVE_WRITEV
11421 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11422#endif
11423#ifdef HAVE_PWRITE
11424 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11425#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011426#ifdef HAVE_SENDFILE
11427 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11428 posix_sendfile__doc__},
11429#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011430 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011431 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011432#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011434#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011435#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011436 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011437#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011438#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011439 {"mkfifo", (PyCFunction)posix_mkfifo,
11440 METH_VARARGS | METH_KEYWORDS,
11441 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011442#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011443#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 {"mknod", (PyCFunction)posix_mknod,
11445 METH_VARARGS | METH_KEYWORDS,
11446 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011447#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011448#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11450 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11451 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011452#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011453#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011455#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011456#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011457 {"truncate", (PyCFunction)posix_truncate,
11458 METH_VARARGS | METH_KEYWORDS,
11459 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011460#endif
11461#ifdef HAVE_POSIX_FALLOCATE
11462 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11463#endif
11464#ifdef HAVE_POSIX_FADVISE
11465 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11466#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011467#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011469#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011470#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011472#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011474#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011476#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011477#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011479#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011480#ifdef HAVE_SYNC
11481 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11482#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011483#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011485#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011486#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011487#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011489#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011490#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011492#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011493#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011495#endif /* WIFSTOPPED */
11496#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011498#endif /* WIFSIGNALED */
11499#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011501#endif /* WIFEXITED */
11502#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011504#endif /* WEXITSTATUS */
11505#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011507#endif /* WTERMSIG */
11508#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011510#endif /* WSTOPSIG */
11511#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011512#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011514#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011515#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011516 {"statvfs", (PyCFunction)posix_statvfs,
11517 METH_VARARGS | METH_KEYWORDS,
11518 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011519#endif
Fred Drakec9680921999-12-13 16:37:25 +000011520#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011522#endif
11523#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011525#endif
11526#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011527 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011528#endif
11529#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011530 {"pathconf", (PyCFunction)posix_pathconf,
11531 METH_VARARGS | METH_KEYWORDS,
11532 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011533#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011535#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011537 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011538 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011539 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011540 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011541#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011542#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011544#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011545 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011546#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011548#endif
11549#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011551#endif
11552#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011554#endif
11555#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011557#endif
11558
Benjamin Peterson9428d532011-09-14 11:45:52 -040011559#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011560 {"setxattr", (PyCFunction)posix_setxattr,
11561 METH_VARARGS | METH_KEYWORDS,
11562 posix_setxattr__doc__},
11563 {"getxattr", (PyCFunction)posix_getxattr,
11564 METH_VARARGS | METH_KEYWORDS,
11565 posix_getxattr__doc__},
11566 {"removexattr", (PyCFunction)posix_removexattr,
11567 METH_VARARGS | METH_KEYWORDS,
11568 posix_removexattr__doc__},
11569 {"listxattr", (PyCFunction)posix_listxattr,
11570 METH_VARARGS | METH_KEYWORDS,
11571 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011572#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011573#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11574 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11575#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011576 {"cpu_count", (PyCFunction)posix_cpu_count,
11577 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011578 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11579 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11580#ifdef MS_WINDOWS
11581 {"get_handle_inheritable", posix_get_handle_inheritable,
11582 METH_VARARGS, get_handle_inheritable__doc__},
11583 {"set_handle_inheritable", posix_set_handle_inheritable,
11584 METH_VARARGS, set_handle_inheritable__doc__},
11585#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011587};
11588
11589
Brian Curtin52173d42010-12-02 18:29:18 +000011590#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011591static int
Brian Curtin52173d42010-12-02 18:29:18 +000011592enable_symlink()
11593{
11594 HANDLE tok;
11595 TOKEN_PRIVILEGES tok_priv;
11596 LUID luid;
11597 int meth_idx = 0;
11598
11599 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011600 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011601
11602 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011603 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011604
11605 tok_priv.PrivilegeCount = 1;
11606 tok_priv.Privileges[0].Luid = luid;
11607 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11608
11609 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11610 sizeof(TOKEN_PRIVILEGES),
11611 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011612 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011613
Brian Curtin3b4499c2010-12-28 14:31:47 +000011614 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11615 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011616}
11617#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11618
Barry Warsaw4a342091996-12-19 23:50:02 +000011619static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011620all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011621{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011622#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011623 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011624#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011625#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011626 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011627#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011628#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011629 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011630#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011631#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011632 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011633#endif
Fred Drakec9680921999-12-13 16:37:25 +000011634#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011635 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011636#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011637#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011638 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011639#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011640#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011641 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011642#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011643#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011644 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011645#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011646#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011647 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011648#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011649#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011650 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011651#endif
11652#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011653 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011654#endif
11655#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011656 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011657#endif
11658#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011659 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011660#endif
11661#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011662 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011663#endif
11664#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011665 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011666#endif
11667#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011668 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011669#endif
11670#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011671 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011672#endif
11673#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011674 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011675#endif
11676#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011677 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011678#endif
11679#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011680 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011681#endif
11682#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011683 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011684#endif
11685#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011686 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011687#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011688#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011689 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011690#endif
11691#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011692 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011693#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011694#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011695 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011696#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011697#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011698 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011699#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011700#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011701 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011702#endif
11703#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011704 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011705#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011706#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011707 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011708#endif
11709#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011710 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011711#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011712#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011713 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011714#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011715#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011716 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011717#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011718#ifdef O_TMPFILE
11719 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11720#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011721#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011722 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011723#endif
11724#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011725 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011726#endif
11727#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011728 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011729#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011730#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011731 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011732#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011733#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011734 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011735#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011736
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011737
Jesus Cea94363612012-06-22 18:32:07 +020011738#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011739 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011740#endif
11741#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011742 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011743#endif
11744
Tim Peters5aa91602002-01-30 05:46:57 +000011745/* MS Windows */
11746#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011747 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011748 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011749#endif
11750#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011751 /* Optimize for short life (keep in memory). */
11752 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011753 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011754#endif
11755#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011756 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011758#endif
11759#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011760 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011761 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011762#endif
11763#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011765 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011766#endif
11767
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011768/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011769#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 /* Send a SIGIO signal whenever input or output
11771 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011772 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011773#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011774#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011775 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011776 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011777#endif
11778#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011779 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011780 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011781#endif
11782#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011783 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011784 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011785#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011786#ifdef O_NOLINKS
11787 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011788 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011789#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011790#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011791 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011792 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011793#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011794
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011796#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011797 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011798#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011799#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011800 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011801#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011802#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011803 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011804#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011805#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011806 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011807#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011808#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011809 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011810#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011811#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011812 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011813#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011814#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011815 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011816#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011817#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011818 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011819#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011820#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011821 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011822#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011823#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011824 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011825#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011826#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011827 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011828#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011829#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011830 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011831#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011832#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011833 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011834#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011835#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011836 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011837#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011838#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011839 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011840#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011841#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011842 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011843#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011844#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011845 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011846#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011847
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011848 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011849#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011850 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011851#endif /* ST_RDONLY */
11852#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011853 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011854#endif /* ST_NOSUID */
11855
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011856 /* GNU extensions */
11857#ifdef ST_NODEV
11858 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11859#endif /* ST_NODEV */
11860#ifdef ST_NOEXEC
11861 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11862#endif /* ST_NOEXEC */
11863#ifdef ST_SYNCHRONOUS
11864 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11865#endif /* ST_SYNCHRONOUS */
11866#ifdef ST_MANDLOCK
11867 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11868#endif /* ST_MANDLOCK */
11869#ifdef ST_WRITE
11870 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11871#endif /* ST_WRITE */
11872#ifdef ST_APPEND
11873 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11874#endif /* ST_APPEND */
11875#ifdef ST_NOATIME
11876 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11877#endif /* ST_NOATIME */
11878#ifdef ST_NODIRATIME
11879 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11880#endif /* ST_NODIRATIME */
11881#ifdef ST_RELATIME
11882 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11883#endif /* ST_RELATIME */
11884
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011885 /* FreeBSD sendfile() constants */
11886#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011887 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011888#endif
11889#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011890 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011891#endif
11892#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011893 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011894#endif
11895
Ross Lagerwall7807c352011-03-17 20:20:30 +020011896 /* constants for posix_fadvise */
11897#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011898 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011899#endif
11900#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011901 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011902#endif
11903#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011904 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011905#endif
11906#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011907 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011908#endif
11909#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011910 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011911#endif
11912#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011913 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011914#endif
11915
11916 /* constants for waitid */
11917#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011918 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11919 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11920 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011921#endif
11922#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011923 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011924#endif
11925#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011926 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011927#endif
11928#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011929 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011930#endif
11931#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011932 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011933#endif
11934#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011935 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011936#endif
11937#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011938 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011939#endif
11940#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011941 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011942#endif
11943
11944 /* constants for lockf */
11945#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011946 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011947#endif
11948#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011949 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011950#endif
11951#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011952 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011953#endif
11954#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011955 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011956#endif
11957
Guido van Rossum246bc171999-02-01 23:54:31 +000011958#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011959 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11960 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11961 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11962 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11963 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011964#endif
11965
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011966#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11968 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11969 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011970#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011971 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011972#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011973#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011974 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011975#endif
11976#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011977 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011978#endif
11979#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011980 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011981#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011982#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011983 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011984#endif
11985#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011986 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011987#endif
11988#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011989 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011990#endif
11991#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011992 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011993#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011994#endif
11995
Benjamin Peterson9428d532011-09-14 11:45:52 -040011996#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011997 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11998 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11999 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012000#endif
12001
Victor Stinner8b905bd2011-10-25 13:34:04 +020012002#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012003 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012004#endif
12005#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012006 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012007#endif
12008#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012009 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012010#endif
12011#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012012 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012013#endif
12014#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012015 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012016#endif
12017#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012018 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012019#endif
12020#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012021 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012022#endif
12023
Victor Stinner8c62be82010-05-06 00:08:46 +000012024 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012025}
12026
12027
Tim Peters5aa91602002-01-30 05:46:57 +000012028#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012029#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012030#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012031
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012032#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012033#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012034#define MODNAME "posix"
12035#endif
12036
Martin v. Löwis1a214512008-06-11 05:26:20 +000012037static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012038 PyModuleDef_HEAD_INIT,
12039 MODNAME,
12040 posix__doc__,
12041 -1,
12042 posix_methods,
12043 NULL,
12044 NULL,
12045 NULL,
12046 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012047};
12048
12049
Larry Hastings9cf065c2012-06-22 16:30:09 -070012050static char *have_functions[] = {
12051
12052#ifdef HAVE_FACCESSAT
12053 "HAVE_FACCESSAT",
12054#endif
12055
12056#ifdef HAVE_FCHDIR
12057 "HAVE_FCHDIR",
12058#endif
12059
12060#ifdef HAVE_FCHMOD
12061 "HAVE_FCHMOD",
12062#endif
12063
12064#ifdef HAVE_FCHMODAT
12065 "HAVE_FCHMODAT",
12066#endif
12067
12068#ifdef HAVE_FCHOWN
12069 "HAVE_FCHOWN",
12070#endif
12071
Larry Hastings00964ed2013-08-12 13:49:30 -040012072#ifdef HAVE_FCHOWNAT
12073 "HAVE_FCHOWNAT",
12074#endif
12075
Larry Hastings9cf065c2012-06-22 16:30:09 -070012076#ifdef HAVE_FEXECVE
12077 "HAVE_FEXECVE",
12078#endif
12079
12080#ifdef HAVE_FDOPENDIR
12081 "HAVE_FDOPENDIR",
12082#endif
12083
Georg Brandl306336b2012-06-24 12:55:33 +020012084#ifdef HAVE_FPATHCONF
12085 "HAVE_FPATHCONF",
12086#endif
12087
Larry Hastings9cf065c2012-06-22 16:30:09 -070012088#ifdef HAVE_FSTATAT
12089 "HAVE_FSTATAT",
12090#endif
12091
12092#ifdef HAVE_FSTATVFS
12093 "HAVE_FSTATVFS",
12094#endif
12095
Georg Brandl306336b2012-06-24 12:55:33 +020012096#ifdef HAVE_FTRUNCATE
12097 "HAVE_FTRUNCATE",
12098#endif
12099
Larry Hastings9cf065c2012-06-22 16:30:09 -070012100#ifdef HAVE_FUTIMENS
12101 "HAVE_FUTIMENS",
12102#endif
12103
12104#ifdef HAVE_FUTIMES
12105 "HAVE_FUTIMES",
12106#endif
12107
12108#ifdef HAVE_FUTIMESAT
12109 "HAVE_FUTIMESAT",
12110#endif
12111
12112#ifdef HAVE_LINKAT
12113 "HAVE_LINKAT",
12114#endif
12115
12116#ifdef HAVE_LCHFLAGS
12117 "HAVE_LCHFLAGS",
12118#endif
12119
12120#ifdef HAVE_LCHMOD
12121 "HAVE_LCHMOD",
12122#endif
12123
12124#ifdef HAVE_LCHOWN
12125 "HAVE_LCHOWN",
12126#endif
12127
12128#ifdef HAVE_LSTAT
12129 "HAVE_LSTAT",
12130#endif
12131
12132#ifdef HAVE_LUTIMES
12133 "HAVE_LUTIMES",
12134#endif
12135
12136#ifdef HAVE_MKDIRAT
12137 "HAVE_MKDIRAT",
12138#endif
12139
12140#ifdef HAVE_MKFIFOAT
12141 "HAVE_MKFIFOAT",
12142#endif
12143
12144#ifdef HAVE_MKNODAT
12145 "HAVE_MKNODAT",
12146#endif
12147
12148#ifdef HAVE_OPENAT
12149 "HAVE_OPENAT",
12150#endif
12151
12152#ifdef HAVE_READLINKAT
12153 "HAVE_READLINKAT",
12154#endif
12155
12156#ifdef HAVE_RENAMEAT
12157 "HAVE_RENAMEAT",
12158#endif
12159
12160#ifdef HAVE_SYMLINKAT
12161 "HAVE_SYMLINKAT",
12162#endif
12163
12164#ifdef HAVE_UNLINKAT
12165 "HAVE_UNLINKAT",
12166#endif
12167
12168#ifdef HAVE_UTIMENSAT
12169 "HAVE_UTIMENSAT",
12170#endif
12171
12172#ifdef MS_WINDOWS
12173 "MS_WINDOWS",
12174#endif
12175
12176 NULL
12177};
12178
12179
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012180PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012181INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012182{
Victor Stinner8c62be82010-05-06 00:08:46 +000012183 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012184 PyObject *list;
12185 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012186
Brian Curtin52173d42010-12-02 18:29:18 +000012187#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012188 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012189#endif
12190
Victor Stinner8c62be82010-05-06 00:08:46 +000012191 m = PyModule_Create(&posixmodule);
12192 if (m == NULL)
12193 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012194
Victor Stinner8c62be82010-05-06 00:08:46 +000012195 /* Initialize environ dictionary */
12196 v = convertenviron();
12197 Py_XINCREF(v);
12198 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12199 return NULL;
12200 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012201
Victor Stinner8c62be82010-05-06 00:08:46 +000012202 if (all_ins(m))
12203 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012204
Victor Stinner8c62be82010-05-06 00:08:46 +000012205 if (setup_confname_tables(m))
12206 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012207
Victor Stinner8c62be82010-05-06 00:08:46 +000012208 Py_INCREF(PyExc_OSError);
12209 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012210
Guido van Rossumb3d39562000-01-31 18:41:26 +000012211#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012212 if (posix_putenv_garbage == NULL)
12213 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012214#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012215
Victor Stinner8c62be82010-05-06 00:08:46 +000012216 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012217#if defined(HAVE_WAITID) && !defined(__APPLE__)
12218 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012219 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12220 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012221#endif
12222
Christian Heimes25827622013-10-12 01:27:08 +020012223 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012224 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12225 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12226 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012227 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12228 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012229 structseq_new = StatResultType.tp_new;
12230 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012231
Christian Heimes25827622013-10-12 01:27:08 +020012232 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012233 if (PyStructSequence_InitType2(&StatVFSResultType,
12234 &statvfs_result_desc) < 0)
12235 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012236#ifdef NEED_TICKS_PER_SECOND
12237# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012238 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012239# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012240 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012241# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012243# endif
12244#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012245
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012246#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012247 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012248 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12249 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012250 SchedParamType.tp_new = sched_param_new;
12251#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012252
12253 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012254 if (PyStructSequence_InitType2(&TerminalSizeType,
12255 &TerminalSize_desc) < 0)
12256 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012257 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012258#if defined(HAVE_WAITID) && !defined(__APPLE__)
12259 Py_INCREF((PyObject*) &WaitidResultType);
12260 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12261#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012262 Py_INCREF((PyObject*) &StatResultType);
12263 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12264 Py_INCREF((PyObject*) &StatVFSResultType);
12265 PyModule_AddObject(m, "statvfs_result",
12266 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012267
12268#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012269 Py_INCREF(&SchedParamType);
12270 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012271#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012272
Larry Hastings605a62d2012-06-24 04:33:36 -070012273 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012274 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12275 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012276 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12277
12278 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012279 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12280 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012281 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12282
Thomas Wouters477c8d52006-05-27 19:21:47 +000012283#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012284 /*
12285 * Step 2 of weak-linking support on Mac OS X.
12286 *
12287 * The code below removes functions that are not available on the
12288 * currently active platform.
12289 *
12290 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012291 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012292 * OSX 10.4.
12293 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012294#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012295 if (fstatvfs == NULL) {
12296 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12297 return NULL;
12298 }
12299 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012300#endif /* HAVE_FSTATVFS */
12301
12302#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012303 if (statvfs == NULL) {
12304 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12305 return NULL;
12306 }
12307 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012308#endif /* HAVE_STATVFS */
12309
12310# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012311 if (lchown == NULL) {
12312 if (PyObject_DelAttrString(m, "lchown") == -1) {
12313 return NULL;
12314 }
12315 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012316#endif /* HAVE_LCHOWN */
12317
12318
12319#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012320
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012321 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012322 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12323
Larry Hastings6fe20b32012-04-19 15:07:49 -070012324 billion = PyLong_FromLong(1000000000);
12325 if (!billion)
12326 return NULL;
12327
Larry Hastings9cf065c2012-06-22 16:30:09 -070012328 /* suppress "function not used" warnings */
12329 {
12330 int ignored;
12331 fd_specified("", -1);
12332 follow_symlinks_specified("", 1);
12333 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12334 dir_fd_converter(Py_None, &ignored);
12335 dir_fd_unavailable(Py_None, &ignored);
12336 }
12337
12338 /*
12339 * provide list of locally available functions
12340 * so os.py can populate support_* lists
12341 */
12342 list = PyList_New(0);
12343 if (!list)
12344 return NULL;
12345 for (trace = have_functions; *trace; trace++) {
12346 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12347 if (!unicode)
12348 return NULL;
12349 if (PyList_Append(list, unicode))
12350 return NULL;
12351 Py_DECREF(unicode);
12352 }
12353 PyModule_AddObject(m, "_have_functions", list);
12354
12355 initialized = 1;
12356
Victor Stinner8c62be82010-05-06 00:08:46 +000012357 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012358}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012359
12360#ifdef __cplusplus
12361}
12362#endif