blob: 35b9ff47ee202a5290327fa94446644080e977e8 [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"
30#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
Benjamin Peterson9428d532011-09-14 11:45:52 -040095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
96#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200113#ifdef __hpux
114#include <sys/mpctl.h>
115#endif
116
117#if defined(__DragonFly__) || \
118 defined(__OpenBSD__) || \
119 defined(__FreeBSD__) || \
120 defined(__NetBSD__) || \
121 defined(__APPLE__)
122#include <sys/sysctl.h>
123#endif
124
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100125#if defined(MS_WINDOWS)
126# define TERMSIZE_USE_CONIO
127#elif defined(HAVE_SYS_IOCTL_H)
128# include <sys/ioctl.h>
129# if defined(HAVE_TERMIOS_H)
130# include <termios.h>
131# endif
132# if defined(TIOCGWINSZ)
133# define TERMSIZE_USE_IOCTL
134# endif
135#endif /* MS_WINDOWS */
136
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000138/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#include <process.h>
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000152#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000153#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_EXECV 1
156#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#define HAVE_SYSTEM 1
158#define HAVE_CWAIT 1
159#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000160#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000161#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Unix functions that the configure script doesn't check for */
163#define HAVE_EXECV 1
164#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000166#define HAVE_FORK1 1
167#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_GETEGID 1
169#define HAVE_GETEUID 1
170#define HAVE_GETGID 1
171#define HAVE_GETPPID 1
172#define HAVE_GETUID 1
173#define HAVE_KILL 1
174#define HAVE_OPENDIR 1
175#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#endif /* _MSC_VER */
180#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000181#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000182
Victor Stinnera2f7c002012-02-08 03:36:25 +0100183
Larry Hastings61272b72014-01-07 12:41:53 -0800184/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800185module os
Larry Hastings61272b72014-01-07 12:41:53 -0800186[clinic start generated code]*/
187/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100188
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000191#if defined(__sgi)&&_COMPILER_VERSION>=700
192/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
193 (default) */
194extern char *ctermid_r(char *);
195#endif
196
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000197#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
207#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int chdir(char *);
209extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int chdir(const char *);
212extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#ifdef __BORLANDC__
215extern int chmod(const char *, int);
216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000304#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000305#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000307#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000308#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000309#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
310#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000311static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000312#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000313#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#if defined(PATH_MAX) && PATH_MAX > 1024
317#define MAXPATHLEN PATH_MAX
318#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#endif /* MAXPATHLEN */
322
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000323#ifdef UNION_WAIT
324/* Emulate some macros on systems that have a union instead of macros */
325
326#ifndef WIFEXITED
327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
328#endif
329
330#ifndef WEXITSTATUS
331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
332#endif
333
334#ifndef WTERMSIG
335#define WTERMSIG(u_wait) ((u_wait).w_termsig)
336#endif
337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338#define WAIT_TYPE union wait
339#define WAIT_STATUS_INT(s) (s.w_status)
340
341#else /* !UNION_WAIT */
342#define WAIT_TYPE int
343#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000344#endif /* UNION_WAIT */
345
Greg Wardb48bc172000-03-01 21:51:56 +0000346/* Don't use the "_r" form if we don't need it (also, won't have a
347 prototype for it, at least on Solaris -- maybe others as well?). */
348#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
349#define USE_CTERMID_R
350#endif
351
Fred Drake699f3522000-06-29 21:12:41 +0000352/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000353#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000354#undef FSTAT
355#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200356#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT win32_fstat
360# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT fstat
365# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#endif
367
Tim Peters11b23062003-04-23 02:39:17 +0000368#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000369#include <sys/mkdev.h>
370#else
371#if defined(MAJOR_IN_SYSMACROS)
372#include <sys/sysmacros.h>
373#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
375#include <sys/mkdev.h>
376#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#endif
Fred Drake699f3522000-06-29 21:12:41 +0000378
Victor Stinner6edddfa2013-11-24 19:22:57 +0100379#define DWORD_MAX 4294967295U
380
Larry Hastings9cf065c2012-06-22 16:30:09 -0700381
382#ifdef MS_WINDOWS
383static int
384win32_warn_bytes_api()
385{
386 return PyErr_WarnEx(PyExc_DeprecationWarning,
387 "The Windows bytes API has been deprecated, "
388 "use Unicode filenames instead",
389 1);
390}
391#endif
392
393
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200394#ifndef MS_WINDOWS
395PyObject *
396_PyLong_FromUid(uid_t uid)
397{
398 if (uid == (uid_t)-1)
399 return PyLong_FromLong(-1);
400 return PyLong_FromUnsignedLong(uid);
401}
402
403PyObject *
404_PyLong_FromGid(gid_t gid)
405{
406 if (gid == (gid_t)-1)
407 return PyLong_FromLong(-1);
408 return PyLong_FromUnsignedLong(gid);
409}
410
411int
412_Py_Uid_Converter(PyObject *obj, void *p)
413{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700414 uid_t uid;
415 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200417 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 unsigned long uresult;
419
420 index = PyNumber_Index(obj);
421 if (index == NULL) {
422 PyErr_Format(PyExc_TypeError,
423 "uid should be integer, not %.200s",
424 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200425 return 0;
426 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427
428 /*
429 * Handling uid_t is complicated for two reasons:
430 * * Although uid_t is (always?) unsigned, it still
431 * accepts -1.
432 * * We don't know its size in advance--it may be
433 * bigger than an int, or it may be smaller than
434 * a long.
435 *
436 * So a bit of defensive programming is in order.
437 * Start with interpreting the value passed
438 * in as a signed long and see if it works.
439 */
440
441 result = PyLong_AsLongAndOverflow(index, &overflow);
442
443 if (!overflow) {
444 uid = (uid_t)result;
445
446 if (result == -1) {
447 if (PyErr_Occurred())
448 goto fail;
449 /* It's a legitimate -1, we're done. */
450 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200451 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700452
453 /* Any other negative number is disallowed. */
454 if (result < 0)
455 goto underflow;
456
457 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200458 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700459 (long)uid != result)
460 goto underflow;
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 if (overflow < 0)
465 goto underflow;
466
467 /*
468 * Okay, the value overflowed a signed long. If it
469 * fits in an *unsigned* long, it may still be okay,
470 * as uid_t may be unsigned long on this platform.
471 */
472 uresult = PyLong_AsUnsignedLong(index);
473 if (PyErr_Occurred()) {
474 if (PyErr_ExceptionMatches(PyExc_OverflowError))
475 goto overflow;
476 goto fail;
477 }
478
479 uid = (uid_t)uresult;
480
481 /*
482 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
483 * but this value would get interpreted as (uid_t)-1 by chown
484 * and its siblings. That's not what the user meant! So we
485 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100486 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700487 */
488 if (uid == (uid_t)-1)
489 goto overflow;
490
491 /* Ensure the value wasn't truncated. */
492 if (sizeof(uid_t) < sizeof(long) &&
493 (unsigned long)uid != uresult)
494 goto overflow;
495 /* fallthrough */
496
497success:
498 Py_DECREF(index);
499 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500 return 1;
501
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700502underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200503 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 "uid is less than minimum");
505 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700507overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 "uid is greater than maximum");
510 /* fallthrough */
511
512fail:
513 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 return 0;
515}
516
517int
518_Py_Gid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 gid_t gid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "gid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling gid_t is complicated for two reasons:
536 * * Although gid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 gid = (gid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0) {
561 goto underflow;
562 }
563
564 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566 (long)gid != result)
567 goto underflow;
568 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570
571 if (overflow < 0)
572 goto underflow;
573
574 /*
575 * Okay, the value overflowed a signed long. If it
576 * fits in an *unsigned* long, it may still be okay,
577 * as gid_t may be unsigned long on this platform.
578 */
579 uresult = PyLong_AsUnsignedLong(index);
580 if (PyErr_Occurred()) {
581 if (PyErr_ExceptionMatches(PyExc_OverflowError))
582 goto overflow;
583 goto fail;
584 }
585
586 gid = (gid_t)uresult;
587
588 /*
589 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
590 * but this value would get interpreted as (gid_t)-1 by chown
591 * and its siblings. That's not what the user meant! So we
592 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100593 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594 */
595 if (gid == (gid_t)-1)
596 goto overflow;
597
598 /* Ensure the value wasn't truncated. */
599 if (sizeof(gid_t) < sizeof(long) &&
600 (unsigned long)gid != uresult)
601 goto overflow;
602 /* fallthrough */
603
604success:
605 Py_DECREF(index);
606 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 return 1;
608
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700609underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 "gid is less than minimum");
612 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "gid is greater than maximum");
617 /* fallthrough */
618
619fail:
620 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 return 0;
622}
623#endif /* MS_WINDOWS */
624
625
Larry Hastings9cf065c2012-06-22 16:30:09 -0700626#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400627/*
628 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
629 * without the int cast, the value gets interpreted as uint (4291925331),
630 * which doesn't play nicely with all the initializer lines in this file that
631 * look like this:
632 * int dir_fd = DEFAULT_DIR_FD;
633 */
634#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700635#else
636#define DEFAULT_DIR_FD (-100)
637#endif
638
639static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200640_fd_converter(PyObject *o, int *p, const char *allowed)
641{
642 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643 long long_value;
644
645 PyObject *index = PyNumber_Index(o);
646 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200647 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700648 "argument should be %s, not %.200s",
649 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700650 return 0;
651 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652
653 long_value = PyLong_AsLongAndOverflow(index, &overflow);
654 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200655 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700656 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700657 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658 return 0;
659 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200660 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700661 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700662 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663 return 0;
664 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700665
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666 *p = (int)long_value;
667 return 1;
668}
669
670static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200671dir_fd_converter(PyObject *o, void *p)
672{
673 if (o == Py_None) {
674 *(int *)p = DEFAULT_DIR_FD;
675 return 1;
676 }
677 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700678}
679
680
681
682/*
683 * A PyArg_ParseTuple "converter" function
684 * that handles filesystem paths in the manner
685 * preferred by the os module.
686 *
687 * path_converter accepts (Unicode) strings and their
688 * subclasses, and bytes and their subclasses. What
689 * it does with the argument depends on the platform:
690 *
691 * * On Windows, if we get a (Unicode) string we
692 * extract the wchar_t * and return it; if we get
693 * bytes we extract the char * and return that.
694 *
695 * * On all other platforms, strings are encoded
696 * to bytes using PyUnicode_FSConverter, then we
697 * extract the char * from the bytes object and
698 * return that.
699 *
700 * path_converter also optionally accepts signed
701 * integers (representing open file descriptors) instead
702 * of path strings.
703 *
704 * Input fields:
705 * path.nullable
706 * If nonzero, the path is permitted to be None.
707 * path.allow_fd
708 * If nonzero, the path is permitted to be a file handle
709 * (a signed int) instead of a string.
710 * path.function_name
711 * If non-NULL, path_converter will use that as the name
712 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700713 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700714 * path.argument_name
715 * If non-NULL, path_converter will use that as the name
716 * of the parameter in error messages.
717 * (If path.argument_name is NULL it uses "path".)
718 *
719 * Output fields:
720 * path.wide
721 * Points to the path if it was expressed as Unicode
722 * and was not encoded. (Only used on Windows.)
723 * path.narrow
724 * Points to the path if it was expressed as bytes,
725 * or it was Unicode and was encoded to bytes.
726 * path.fd
727 * Contains a file descriptor if path.accept_fd was true
728 * and the caller provided a signed integer instead of any
729 * sort of string.
730 *
731 * WARNING: if your "path" parameter is optional, and is
732 * unspecified, path_converter will never get called.
733 * So if you set allow_fd, you *MUST* initialize path.fd = -1
734 * yourself!
735 * path.length
736 * The length of the path in characters, if specified as
737 * a string.
738 * path.object
739 * The original object passed in.
740 * path.cleanup
741 * For internal use only. May point to a temporary object.
742 * (Pay no attention to the man behind the curtain.)
743 *
744 * At most one of path.wide or path.narrow will be non-NULL.
745 * If path was None and path.nullable was set,
746 * or if path was an integer and path.allow_fd was set,
747 * both path.wide and path.narrow will be NULL
748 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200749 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700750 * path_converter takes care to not write to the path_t
751 * unless it's successful. However it must reset the
752 * "cleanup" field each time it's called.
753 *
754 * Use as follows:
755 * path_t path;
756 * memset(&path, 0, sizeof(path));
757 * PyArg_ParseTuple(args, "O&", path_converter, &path);
758 * // ... use values from path ...
759 * path_cleanup(&path);
760 *
761 * (Note that if PyArg_Parse fails you don't need to call
762 * path_cleanup(). However it is safe to do so.)
763 */
764typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100765 const char *function_name;
766 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700767 int nullable;
768 int allow_fd;
769 wchar_t *wide;
770 char *narrow;
771 int fd;
772 Py_ssize_t length;
773 PyObject *object;
774 PyObject *cleanup;
775} path_t;
776
Larry Hastings31826802013-10-19 00:09:25 -0700777#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
778 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
779
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780static void
781path_cleanup(path_t *path) {
782 if (path->cleanup) {
783 Py_DECREF(path->cleanup);
784 path->cleanup = NULL;
785 }
786}
787
788static int
789path_converter(PyObject *o, void *p) {
790 path_t *path = (path_t *)p;
791 PyObject *unicode, *bytes;
792 Py_ssize_t length;
793 char *narrow;
794
795#define FORMAT_EXCEPTION(exc, fmt) \
796 PyErr_Format(exc, "%s%s" fmt, \
797 path->function_name ? path->function_name : "", \
798 path->function_name ? ": " : "", \
799 path->argument_name ? path->argument_name : "path")
800
801 /* Py_CLEANUP_SUPPORTED support */
802 if (o == NULL) {
803 path_cleanup(path);
804 return 1;
805 }
806
807 /* ensure it's always safe to call path_cleanup() */
808 path->cleanup = NULL;
809
810 if (o == Py_None) {
811 if (!path->nullable) {
812 FORMAT_EXCEPTION(PyExc_TypeError,
813 "can't specify None for %s argument");
814 return 0;
815 }
816 path->wide = NULL;
817 path->narrow = NULL;
818 path->length = 0;
819 path->object = o;
820 path->fd = -1;
821 return 1;
822 }
823
824 unicode = PyUnicode_FromObject(o);
825 if (unicode) {
826#ifdef MS_WINDOWS
827 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100828
829 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
830 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700831 Py_DECREF(unicode);
832 return 0;
833 }
Victor Stinner59799a82013-11-13 14:17:30 +0100834 if (length > 32767) {
835 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700836 Py_DECREF(unicode);
837 return 0;
838 }
839
840 path->wide = wide;
841 path->narrow = NULL;
842 path->length = length;
843 path->object = o;
844 path->fd = -1;
845 path->cleanup = unicode;
846 return Py_CLEANUP_SUPPORTED;
847#else
848 int converted = PyUnicode_FSConverter(unicode, &bytes);
849 Py_DECREF(unicode);
850 if (!converted)
851 bytes = NULL;
852#endif
853 }
854 else {
855 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200856 if (PyObject_CheckBuffer(o))
857 bytes = PyBytes_FromObject(o);
858 else
859 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860 if (!bytes) {
861 PyErr_Clear();
862 if (path->allow_fd) {
863 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200864 int result = _fd_converter(o, &fd,
865 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 if (result) {
867 path->wide = NULL;
868 path->narrow = NULL;
869 path->length = 0;
870 path->object = o;
871 path->fd = fd;
872 return result;
873 }
874 }
875 }
876 }
877
878 if (!bytes) {
879 if (!PyErr_Occurred())
880 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
881 return 0;
882 }
883
884#ifdef MS_WINDOWS
885 if (win32_warn_bytes_api()) {
886 Py_DECREF(bytes);
887 return 0;
888 }
889#endif
890
891 length = PyBytes_GET_SIZE(bytes);
892#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100893 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700894 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
895 Py_DECREF(bytes);
896 return 0;
897 }
898#endif
899
900 narrow = PyBytes_AS_STRING(bytes);
901 if (length != strlen(narrow)) {
902 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
903 Py_DECREF(bytes);
904 return 0;
905 }
906
907 path->wide = NULL;
908 path->narrow = narrow;
909 path->length = length;
910 path->object = o;
911 path->fd = -1;
912 path->cleanup = bytes;
913 return Py_CLEANUP_SUPPORTED;
914}
915
916static void
917argument_unavailable_error(char *function_name, char *argument_name) {
918 PyErr_Format(PyExc_NotImplementedError,
919 "%s%s%s unavailable on this platform",
920 (function_name != NULL) ? function_name : "",
921 (function_name != NULL) ? ": ": "",
922 argument_name);
923}
924
925static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200926dir_fd_unavailable(PyObject *o, void *p)
927{
928 int dir_fd;
929 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200931 if (dir_fd != DEFAULT_DIR_FD) {
932 argument_unavailable_error(NULL, "dir_fd");
933 return 0;
934 }
935 *(int *)p = dir_fd;
936 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937}
938
939static int
940fd_specified(char *function_name, int fd) {
941 if (fd == -1)
942 return 0;
943
944 argument_unavailable_error(function_name, "fd");
945 return 1;
946}
947
948static int
949follow_symlinks_specified(char *function_name, int follow_symlinks) {
950 if (follow_symlinks)
951 return 0;
952
953 argument_unavailable_error(function_name, "follow_symlinks");
954 return 1;
955}
956
957static int
958path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
959 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
960 PyErr_Format(PyExc_ValueError,
961 "%s: can't specify dir_fd without matching path",
962 function_name);
963 return 1;
964 }
965 return 0;
966}
967
968static int
969dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
970 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
971 PyErr_Format(PyExc_ValueError,
972 "%s: can't specify both dir_fd and fd",
973 function_name);
974 return 1;
975 }
976 return 0;
977}
978
979static int
980fd_and_follow_symlinks_invalid(char *function_name, int fd,
981 int follow_symlinks) {
982 if ((fd > 0) && (!follow_symlinks)) {
983 PyErr_Format(PyExc_ValueError,
984 "%s: cannot use fd and follow_symlinks together",
985 function_name);
986 return 1;
987 }
988 return 0;
989}
990
991static int
992dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
993 int follow_symlinks) {
994 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
995 PyErr_Format(PyExc_ValueError,
996 "%s: cannot use dir_fd and follow_symlinks together",
997 function_name);
998 return 1;
999 }
1000 return 0;
1001}
1002
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001003/* A helper used by a number of POSIX-only functions */
1004#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001005static int
1006_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001007{
1008#if !defined(HAVE_LARGEFILE_SUPPORT)
1009 *((off_t*)addr) = PyLong_AsLong(arg);
1010#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001011 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001012#endif
1013 if (PyErr_Occurred())
1014 return 0;
1015 return 1;
1016}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001017#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001018
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001019#if defined _MSC_VER && _MSC_VER >= 1400
1020/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001021 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001022 * Normally, an invalid fd is likely to be a C program error and therefore
1023 * an assertion can be useful, but it does contradict the POSIX standard
1024 * which for write(2) states:
1025 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1026 * "[EBADF] The fildes argument is not a valid file descriptor open for
1027 * writing."
1028 * Furthermore, python allows the user to enter any old integer
1029 * as a fd and should merely raise a python exception on error.
1030 * The Microsoft CRT doesn't provide an official way to check for the
1031 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001032 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001033 * internal structures involved.
1034 * The structures below must be updated for each version of visual studio
1035 * according to the file internal.h in the CRT source, until MS comes
1036 * up with a less hacky way to do this.
1037 * (all of this is to avoid globally modifying the CRT behaviour using
1038 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1039 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001040/* The actual size of the structure is determined at runtime.
1041 * Only the first items must be present.
1042 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001043typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001044 intptr_t osfhnd;
1045 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001046} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001047
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001048extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001049#define IOINFO_L2E 5
1050#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1051#define IOINFO_ARRAYS 64
1052#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1053#define FOPEN 0x01
1054#define _NO_CONSOLE_FILENO (intptr_t)-2
1055
1056/* This function emulates what the windows CRT does to validate file handles */
1057int
1058_PyVerify_fd(int fd)
1059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 const int i1 = fd >> IOINFO_L2E;
1061 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001062
Antoine Pitrou22e41552010-08-15 18:07:50 +00001063 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001064
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 /* Determine the actual size of the ioinfo structure,
1066 * as used by the CRT loaded in memory
1067 */
1068 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1069 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1070 }
1071 if (sizeof_ioinfo == 0) {
1072 /* This should not happen... */
1073 goto fail;
1074 }
1075
1076 /* See that it isn't a special CLEAR fileno */
1077 if (fd != _NO_CONSOLE_FILENO) {
1078 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1079 * we check pointer validity and other info
1080 */
1081 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1082 /* finally, check that the file is open */
1083 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1084 if (info->osfile & FOPEN) {
1085 return 1;
1086 }
1087 }
1088 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001089 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 errno = EBADF;
1091 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001092}
1093
1094/* the special case of checking dup2. The target fd must be in a sensible range */
1095static int
1096_PyVerify_fd_dup2(int fd1, int fd2)
1097{
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 if (!_PyVerify_fd(fd1))
1099 return 0;
1100 if (fd2 == _NO_CONSOLE_FILENO)
1101 return 0;
1102 if ((unsigned)fd2 < _NHANDLE_)
1103 return 1;
1104 else
1105 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001106}
1107#else
1108/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1109#define _PyVerify_fd_dup2(A, B) (1)
1110#endif
1111
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001112#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001113/* The following structure was copied from
1114 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1115 include doesn't seem to be present in the Windows SDK (at least as included
1116 with Visual Studio Express). */
1117typedef struct _REPARSE_DATA_BUFFER {
1118 ULONG ReparseTag;
1119 USHORT ReparseDataLength;
1120 USHORT Reserved;
1121 union {
1122 struct {
1123 USHORT SubstituteNameOffset;
1124 USHORT SubstituteNameLength;
1125 USHORT PrintNameOffset;
1126 USHORT PrintNameLength;
1127 ULONG Flags;
1128 WCHAR PathBuffer[1];
1129 } SymbolicLinkReparseBuffer;
1130
1131 struct {
1132 USHORT SubstituteNameOffset;
1133 USHORT SubstituteNameLength;
1134 USHORT PrintNameOffset;
1135 USHORT PrintNameLength;
1136 WCHAR PathBuffer[1];
1137 } MountPointReparseBuffer;
1138
1139 struct {
1140 UCHAR DataBuffer[1];
1141 } GenericReparseBuffer;
1142 };
1143} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1144
1145#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1146 GenericReparseBuffer)
1147#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1148
1149static int
Brian Curtind25aef52011-06-13 15:16:04 -05001150win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151{
1152 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1153 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1154 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001155
1156 if (0 == DeviceIoControl(
1157 reparse_point_handle,
1158 FSCTL_GET_REPARSE_POINT,
1159 NULL, 0, /* in buffer */
1160 target_buffer, sizeof(target_buffer),
1161 &n_bytes_returned,
1162 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001163 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001164
1165 if (reparse_tag)
1166 *reparse_tag = rdb->ReparseTag;
1167
Brian Curtind25aef52011-06-13 15:16:04 -05001168 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001170
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001171#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001172
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001174#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001175/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001176** environ directly, we must obtain it with _NSGetEnviron(). See also
1177** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001178*/
1179#include <crt_externs.h>
1180static char **environ;
1181#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001183#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184
Barry Warsaw53699e91996-12-10 23:23:01 +00001185static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001186convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187{
Victor Stinner8c62be82010-05-06 00:08:46 +00001188 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001189#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001190 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001191#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001193#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001194
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 d = PyDict_New();
1196 if (d == NULL)
1197 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001198#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 if (environ == NULL)
1200 environ = *_NSGetEnviron();
1201#endif
1202#ifdef MS_WINDOWS
1203 /* _wenviron must be initialized in this way if the program is started
1204 through main() instead of wmain(). */
1205 _wgetenv(L"");
1206 if (_wenviron == NULL)
1207 return d;
1208 /* This part ignores errors */
1209 for (e = _wenviron; *e != NULL; e++) {
1210 PyObject *k;
1211 PyObject *v;
1212 wchar_t *p = wcschr(*e, L'=');
1213 if (p == NULL)
1214 continue;
1215 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1216 if (k == NULL) {
1217 PyErr_Clear();
1218 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001219 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1221 if (v == NULL) {
1222 PyErr_Clear();
1223 Py_DECREF(k);
1224 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001225 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 if (PyDict_GetItem(d, k) == NULL) {
1227 if (PyDict_SetItem(d, k, v) != 0)
1228 PyErr_Clear();
1229 }
1230 Py_DECREF(k);
1231 Py_DECREF(v);
1232 }
1233#else
1234 if (environ == NULL)
1235 return d;
1236 /* This part ignores errors */
1237 for (e = environ; *e != NULL; e++) {
1238 PyObject *k;
1239 PyObject *v;
1240 char *p = strchr(*e, '=');
1241 if (p == NULL)
1242 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001243 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001244 if (k == NULL) {
1245 PyErr_Clear();
1246 continue;
1247 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001248 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 if (v == NULL) {
1250 PyErr_Clear();
1251 Py_DECREF(k);
1252 continue;
1253 }
1254 if (PyDict_GetItem(d, k) == NULL) {
1255 if (PyDict_SetItem(d, k, v) != 0)
1256 PyErr_Clear();
1257 }
1258 Py_DECREF(k);
1259 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001260 }
1261#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001262 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001263}
1264
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265/* Set a POSIX-specific error from errno, and return NULL */
1266
Barry Warsawd58d7641998-07-23 16:14:40 +00001267static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001268posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001269{
Victor Stinner8c62be82010-05-06 00:08:46 +00001270 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001271}
Mark Hammondef8b6542001-05-13 08:04:26 +00001272
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001273#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001274static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001275win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001276{
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 /* XXX We should pass the function name along in the future.
1278 (winreg.c also wants to pass the function name.)
1279 This would however require an additional param to the
1280 Windows error object, which is non-trivial.
1281 */
1282 errno = GetLastError();
1283 if (filename)
1284 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1285 else
1286 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001287}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001288
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001289static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001290win32_error_object(char* function, PyObject* filename)
1291{
1292 /* XXX - see win32_error for comments on 'function' */
1293 errno = GetLastError();
1294 if (filename)
1295 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001296 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001297 errno,
1298 filename);
1299 else
1300 return PyErr_SetFromWindowsErr(errno);
1301}
1302
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001303#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304
Larry Hastings9cf065c2012-06-22 16:30:09 -07001305static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001306path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001307{
1308#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001309 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1310 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001311#else
Victor Stinner292c8352012-10-30 02:17:38 +01001312 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001313#endif
1314}
1315
Larry Hastings31826802013-10-19 00:09:25 -07001316
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317/* POSIX generic methods */
1318
Barry Warsaw53699e91996-12-10 23:23:01 +00001319static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001320posix_fildes(PyObject *fdobj, int (*func)(int))
1321{
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 int fd;
1323 int res;
1324 fd = PyObject_AsFileDescriptor(fdobj);
1325 if (fd < 0)
1326 return NULL;
1327 if (!_PyVerify_fd(fd))
1328 return posix_error();
1329 Py_BEGIN_ALLOW_THREADS
1330 res = (*func)(fd);
1331 Py_END_ALLOW_THREADS
1332 if (res < 0)
1333 return posix_error();
1334 Py_INCREF(Py_None);
1335 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001336}
Guido van Rossum21142a01999-01-08 21:05:37 +00001337
1338static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001339posix_1str(const char *func_name, PyObject *args, char *format,
1340 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
Victor Stinner292c8352012-10-30 02:17:38 +01001342 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001344 memset(&path, 0, sizeof(path));
1345 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001347 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001350 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001352 if (res < 0) {
1353 path_error(&path);
1354 path_cleanup(&path);
1355 return NULL;
1356 }
1357 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 Py_INCREF(Py_None);
1359 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360}
1361
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001363#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001364/* This is a reimplementation of the C library's chdir function,
1365 but one that produces Win32 errors instead of DOS error codes.
1366 chdir is essentially a wrapper around SetCurrentDirectory; however,
1367 it also needs to set "magic" environment variables indicating
1368 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001369static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370win32_chdir(LPCSTR path)
1371{
Victor Stinner75875072013-11-24 19:23:25 +01001372 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 int result;
1374 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375
Victor Stinner8c62be82010-05-06 00:08:46 +00001376 if(!SetCurrentDirectoryA(path))
1377 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001378 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 if (!result)
1380 return FALSE;
1381 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001382 than MAX_PATH-1 (not including the final null character). */
1383 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 if (strncmp(new_path, "\\\\", 2) == 0 ||
1385 strncmp(new_path, "//", 2) == 0)
1386 /* UNC path, nothing to do. */
1387 return TRUE;
1388 env[1] = new_path[0];
1389 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390}
1391
1392/* The Unicode version differs from the ANSI version
1393 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001394static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395win32_wchdir(LPCWSTR path)
1396{
Victor Stinner75875072013-11-24 19:23:25 +01001397 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 int result;
1399 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 if(!SetCurrentDirectoryW(path))
1402 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001403 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 if (!result)
1405 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001406 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001407 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 if (!new_path) {
1409 SetLastError(ERROR_OUTOFMEMORY);
1410 return FALSE;
1411 }
1412 result = GetCurrentDirectoryW(result, new_path);
1413 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001414 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 return FALSE;
1416 }
1417 }
1418 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1419 wcsncmp(new_path, L"//", 2) == 0)
1420 /* UNC path, nothing to do. */
1421 return TRUE;
1422 env[1] = new_path[0];
1423 result = SetEnvironmentVariableW(env, new_path);
1424 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001425 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427}
1428#endif
1429
Martin v. Löwis14694662006-02-03 12:54:16 +00001430#ifdef MS_WINDOWS
1431/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1432 - time stamps are restricted to second resolution
1433 - file modification times suffer from forth-and-back conversions between
1434 UTC and local time
1435 Therefore, we implement our own stat, based on the Win32 API directly.
1436*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001437#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001438
1439struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001440 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001441 __int64 st_ino;
1442 unsigned short st_mode;
1443 int st_nlink;
1444 int st_uid;
1445 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001446 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001447 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001448 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001449 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001450 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001451 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001452 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 int st_ctime_nsec;
1454};
1455
1456static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1457
1458static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001459FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001460{
Victor Stinner8c62be82010-05-06 00:08:46 +00001461 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1462 /* Cannot simply cast and dereference in_ptr,
1463 since it might not be aligned properly */
1464 __int64 in;
1465 memcpy(&in, in_ptr, sizeof(in));
1466 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001467 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001468}
1469
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001471time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001472{
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 /* XXX endianness */
1474 __int64 out;
1475 out = time_in + secs_between_epochs;
1476 out = out * 10000000 + nsec_in / 100;
1477 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001478}
1479
Martin v. Löwis14694662006-02-03 12:54:16 +00001480/* Below, we *know* that ugo+r is 0444 */
1481#if _S_IREAD != 0400
1482#error Unsupported C library
1483#endif
1484static int
1485attributes_to_mode(DWORD attr)
1486{
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 int m = 0;
1488 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1489 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1490 else
1491 m |= _S_IFREG;
1492 if (attr & FILE_ATTRIBUTE_READONLY)
1493 m |= 0444;
1494 else
1495 m |= 0666;
1496 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001497}
1498
1499static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001500attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001501{
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 memset(result, 0, sizeof(*result));
1503 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1504 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001505 result->st_dev = info->dwVolumeSerialNumber;
1506 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1508 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1509 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001511 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1513 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001514 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001515 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001516 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001518
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001520}
1521
Guido van Rossumd8faa362007-04-27 19:54:29 +00001522static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001523attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001524{
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 HANDLE hFindFile;
1526 WIN32_FIND_DATAA FileData;
1527 hFindFile = FindFirstFileA(pszFile, &FileData);
1528 if (hFindFile == INVALID_HANDLE_VALUE)
1529 return FALSE;
1530 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001531 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001532 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 info->dwFileAttributes = FileData.dwFileAttributes;
1534 info->ftCreationTime = FileData.ftCreationTime;
1535 info->ftLastAccessTime = FileData.ftLastAccessTime;
1536 info->ftLastWriteTime = FileData.ftLastWriteTime;
1537 info->nFileSizeHigh = FileData.nFileSizeHigh;
1538 info->nFileSizeLow = FileData.nFileSizeLow;
1539/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001540 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1541 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001543}
1544
1545static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001546attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001547{
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 HANDLE hFindFile;
1549 WIN32_FIND_DATAW FileData;
1550 hFindFile = FindFirstFileW(pszFile, &FileData);
1551 if (hFindFile == INVALID_HANDLE_VALUE)
1552 return FALSE;
1553 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001554 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556 info->dwFileAttributes = FileData.dwFileAttributes;
1557 info->ftCreationTime = FileData.ftCreationTime;
1558 info->ftLastAccessTime = FileData.ftLastAccessTime;
1559 info->ftLastWriteTime = FileData.ftLastWriteTime;
1560 info->nFileSizeHigh = FileData.nFileSizeHigh;
1561 info->nFileSizeLow = FileData.nFileSizeLow;
1562/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001563 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1564 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001566}
1567
Brian Curtind25aef52011-06-13 15:16:04 -05001568/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001569static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001570static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1571 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001572static int
Brian Curtind25aef52011-06-13 15:16:04 -05001573check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574{
Brian Curtind25aef52011-06-13 15:16:04 -05001575 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001576 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1577 DWORD);
1578
Brian Curtind25aef52011-06-13 15:16:04 -05001579 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001580 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001581 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001582 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001583 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1584 "GetFinalPathNameByHandleA");
1585 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1586 "GetFinalPathNameByHandleW");
1587 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1588 Py_GetFinalPathNameByHandleW;
1589 }
1590 return has_GetFinalPathNameByHandle;
1591}
1592
1593static BOOL
1594get_target_path(HANDLE hdl, wchar_t **target_path)
1595{
1596 int buf_size, result_length;
1597 wchar_t *buf;
1598
1599 /* We have a good handle to the target, use it to determine
1600 the target path name (then we'll call lstat on it). */
1601 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1602 VOLUME_NAME_DOS);
1603 if(!buf_size)
1604 return FALSE;
1605
Victor Stinnerb6404912013-07-07 16:21:41 +02001606 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001607 if (!buf) {
1608 SetLastError(ERROR_OUTOFMEMORY);
1609 return FALSE;
1610 }
1611
Brian Curtind25aef52011-06-13 15:16:04 -05001612 result_length = Py_GetFinalPathNameByHandleW(hdl,
1613 buf, buf_size, VOLUME_NAME_DOS);
1614
1615 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001616 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001617 return FALSE;
1618 }
1619
1620 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001621 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001622 return FALSE;
1623 }
1624
1625 buf[result_length] = 0;
1626
1627 *target_path = buf;
1628 return TRUE;
1629}
1630
1631static int
1632win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1633 BOOL traverse);
1634static int
1635win32_xstat_impl(const char *path, struct win32_stat *result,
1636 BOOL traverse)
1637{
Victor Stinner26de69d2011-06-17 15:15:38 +02001638 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001639 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001641 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001642 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001643 const char *dot;
1644
Brian Curtind25aef52011-06-13 15:16:04 -05001645 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001646 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1647 traverse reparse point. */
1648 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001649 }
1650
Brian Curtinf5e76d02010-11-24 13:14:05 +00001651 hFile = CreateFileA(
1652 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001653 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 0, /* share mode */
1655 NULL, /* security attributes */
1656 OPEN_EXISTING,
1657 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001658 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1659 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001660 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001661 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1662 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 NULL);
1664
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 /* Either the target doesn't exist, or we don't have access to
1667 get a handle to it. If the former, we need to return an error.
1668 If the latter, we can use attributes_from_dir. */
1669 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 return -1;
1671 /* Could not get attributes on open file. Fall back to
1672 reading the directory. */
1673 if (!attributes_from_dir(path, &info, &reparse_tag))
1674 /* Very strange. This should not fail now */
1675 return -1;
1676 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1677 if (traverse) {
1678 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001681 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683 } else {
1684 if (!GetFileInformationByHandle(hFile, &info)) {
1685 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001686 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 }
1688 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001689 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1690 return -1;
1691
1692 /* Close the outer open file handle now that we're about to
1693 reopen it with different flags. */
1694 if (!CloseHandle(hFile))
1695 return -1;
1696
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001697 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001698 /* In order to call GetFinalPathNameByHandle we need to open
1699 the file without the reparse handling flag set. */
1700 hFile2 = CreateFileA(
1701 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1702 NULL, OPEN_EXISTING,
1703 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1704 NULL);
1705 if (hFile2 == INVALID_HANDLE_VALUE)
1706 return -1;
1707
1708 if (!get_target_path(hFile2, &target_path))
1709 return -1;
1710
1711 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001712 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001713 return code;
1714 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001715 } else
1716 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719
1720 /* Set S_IEXEC if it is an .exe, .bat, ... */
1721 dot = strrchr(path, '.');
1722 if (dot) {
1723 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1724 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1725 result->st_mode |= 0111;
1726 }
1727 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728}
1729
1730static int
Brian Curtind25aef52011-06-13 15:16:04 -05001731win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1732 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001733{
1734 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001735 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001738 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 const wchar_t *dot;
1740
Brian Curtind25aef52011-06-13 15:16:04 -05001741 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001742 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1743 traverse reparse point. */
1744 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001745 }
1746
Brian Curtinf5e76d02010-11-24 13:14:05 +00001747 hFile = CreateFileW(
1748 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001749 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750 0, /* share mode */
1751 NULL, /* security attributes */
1752 OPEN_EXISTING,
1753 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001754 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1755 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001756 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001757 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001758 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759 NULL);
1760
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001761 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001762 /* Either the target doesn't exist, or we don't have access to
1763 get a handle to it. If the former, we need to return an error.
1764 If the latter, we can use attributes_from_dir. */
1765 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001766 return -1;
1767 /* Could not get attributes on open file. Fall back to
1768 reading the directory. */
1769 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1770 /* Very strange. This should not fail now */
1771 return -1;
1772 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1773 if (traverse) {
1774 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001775 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001776 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001777 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779 } else {
1780 if (!GetFileInformationByHandle(hFile, &info)) {
1781 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001782 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001783 }
1784 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001785 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1786 return -1;
1787
1788 /* Close the outer open file handle now that we're about to
1789 reopen it with different flags. */
1790 if (!CloseHandle(hFile))
1791 return -1;
1792
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001793 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001794 /* In order to call GetFinalPathNameByHandle we need to open
1795 the file without the reparse handling flag set. */
1796 hFile2 = CreateFileW(
1797 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1798 NULL, OPEN_EXISTING,
1799 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1800 NULL);
1801 if (hFile2 == INVALID_HANDLE_VALUE)
1802 return -1;
1803
1804 if (!get_target_path(hFile2, &target_path))
1805 return -1;
1806
1807 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001808 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809 return code;
1810 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001811 } else
1812 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001813 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001814 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001815
1816 /* Set S_IEXEC if it is an .exe, .bat, ... */
1817 dot = wcsrchr(path, '.');
1818 if (dot) {
1819 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1820 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1821 result->st_mode |= 0111;
1822 }
1823 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001824}
1825
1826static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001827win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001828{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001829 /* Protocol violation: we explicitly clear errno, instead of
1830 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001831 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001832 errno = 0;
1833 return code;
1834}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001835
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001836static int
1837win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1838{
1839 /* Protocol violation: we explicitly clear errno, instead of
1840 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001841 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001842 errno = 0;
1843 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001844}
Brian Curtind25aef52011-06-13 15:16:04 -05001845/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001846
1847 In Posix, stat automatically traverses symlinks and returns the stat
1848 structure for the target. In Windows, the equivalent GetFileAttributes by
1849 default does not traverse symlinks and instead returns attributes for
1850 the symlink.
1851
1852 Therefore, win32_lstat will get the attributes traditionally, and
1853 win32_stat will first explicitly resolve the symlink target and then will
1854 call win32_lstat on that result.
1855
Ezio Melotti4969f702011-03-15 05:59:46 +02001856 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001857
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001858static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001859win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001860{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001861 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001862}
1863
Victor Stinner8c62be82010-05-06 00:08:46 +00001864static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001865win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001866{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001868}
1869
1870static int
1871win32_stat(const char* path, struct win32_stat *result)
1872{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001873 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001874}
1875
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001876static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001877win32_stat_w(const wchar_t* path, struct win32_stat *result)
1878{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001879 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001880}
1881
1882static int
1883win32_fstat(int file_number, struct win32_stat *result)
1884{
Victor Stinner8c62be82010-05-06 00:08:46 +00001885 BY_HANDLE_FILE_INFORMATION info;
1886 HANDLE h;
1887 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001888
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001889 if (!_PyVerify_fd(file_number))
1890 h = INVALID_HANDLE_VALUE;
1891 else
1892 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001893
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 /* Protocol violation: we explicitly clear errno, instead of
1895 setting it to a POSIX error. Callers should use GetLastError. */
1896 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001897
Victor Stinner8c62be82010-05-06 00:08:46 +00001898 if (h == INVALID_HANDLE_VALUE) {
1899 /* This is really a C library error (invalid file handle).
1900 We set the Win32 error to the closes one matching. */
1901 SetLastError(ERROR_INVALID_HANDLE);
1902 return -1;
1903 }
1904 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 type = GetFileType(h);
1907 if (type == FILE_TYPE_UNKNOWN) {
1908 DWORD error = GetLastError();
1909 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001910 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 }
1912 /* else: valid but unknown file */
1913 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001914
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 if (type != FILE_TYPE_DISK) {
1916 if (type == FILE_TYPE_CHAR)
1917 result->st_mode = _S_IFCHR;
1918 else if (type == FILE_TYPE_PIPE)
1919 result->st_mode = _S_IFIFO;
1920 return 0;
1921 }
1922
1923 if (!GetFileInformationByHandle(h, &info)) {
1924 return -1;
1925 }
1926
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001927 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1930 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001931}
1932
1933#endif /* MS_WINDOWS */
1934
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001935PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001936"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001937This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001938 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1940\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001941Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1942or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001943\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001944See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001945
1946static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 {"st_mode", "protection bits"},
1948 {"st_ino", "inode"},
1949 {"st_dev", "device"},
1950 {"st_nlink", "number of hard links"},
1951 {"st_uid", "user ID of owner"},
1952 {"st_gid", "group ID of owner"},
1953 {"st_size", "total size, in bytes"},
1954 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1955 {NULL, "integer time of last access"},
1956 {NULL, "integer time of last modification"},
1957 {NULL, "integer time of last change"},
1958 {"st_atime", "time of last access"},
1959 {"st_mtime", "time of last modification"},
1960 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001961 {"st_atime_ns", "time of last access in nanoseconds"},
1962 {"st_mtime_ns", "time of last modification in nanoseconds"},
1963 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001964#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001966#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001967#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001970#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001973#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001975#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001976#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001978#endif
1979#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001981#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983};
1984
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001985#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001986#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001988#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001989#endif
1990
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001991#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1993#else
1994#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1995#endif
1996
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001997#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001998#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1999#else
2000#define ST_RDEV_IDX ST_BLOCKS_IDX
2001#endif
2002
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002003#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2004#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2005#else
2006#define ST_FLAGS_IDX ST_RDEV_IDX
2007#endif
2008
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002009#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002010#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002012#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#endif
2014
2015#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2016#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2017#else
2018#define ST_BIRTHTIME_IDX ST_GEN_IDX
2019#endif
2020
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002021static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 "stat_result", /* name */
2023 stat_result__doc__, /* doc */
2024 stat_result_fields,
2025 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002026};
2027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2030This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002031 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002032or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002033\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035
2036static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 {"f_bsize", },
2038 {"f_frsize", },
2039 {"f_blocks", },
2040 {"f_bfree", },
2041 {"f_bavail", },
2042 {"f_files", },
2043 {"f_ffree", },
2044 {"f_favail", },
2045 {"f_flag", },
2046 {"f_namemax",},
2047 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048};
2049
2050static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 "statvfs_result", /* name */
2052 statvfs_result__doc__, /* doc */
2053 statvfs_result_fields,
2054 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002055};
2056
Ross Lagerwall7807c352011-03-17 20:20:30 +02002057#if defined(HAVE_WAITID) && !defined(__APPLE__)
2058PyDoc_STRVAR(waitid_result__doc__,
2059"waitid_result: Result from waitid.\n\n\
2060This object may be accessed either as a tuple of\n\
2061 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2062or via the attributes si_pid, si_uid, and so on.\n\
2063\n\
2064See os.waitid for more information.");
2065
2066static PyStructSequence_Field waitid_result_fields[] = {
2067 {"si_pid", },
2068 {"si_uid", },
2069 {"si_signo", },
2070 {"si_status", },
2071 {"si_code", },
2072 {0}
2073};
2074
2075static PyStructSequence_Desc waitid_result_desc = {
2076 "waitid_result", /* name */
2077 waitid_result__doc__, /* doc */
2078 waitid_result_fields,
2079 5
2080};
2081static PyTypeObject WaitidResultType;
2082#endif
2083
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002084static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002085static PyTypeObject StatResultType;
2086static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002087#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002088static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002089#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002090static newfunc structseq_new;
2091
2092static PyObject *
2093statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2094{
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence *result;
2096 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002097
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 result = (PyStructSequence*)structseq_new(type, args, kwds);
2099 if (!result)
2100 return NULL;
2101 /* If we have been initialized from a tuple,
2102 st_?time might be set to None. Initialize it
2103 from the int slots. */
2104 for (i = 7; i <= 9; i++) {
2105 if (result->ob_item[i+3] == Py_None) {
2106 Py_DECREF(Py_None);
2107 Py_INCREF(result->ob_item[i]);
2108 result->ob_item[i+3] = result->ob_item[i];
2109 }
2110 }
2111 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002112}
2113
2114
2115
2116/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002117static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002118
2119PyDoc_STRVAR(stat_float_times__doc__,
2120"stat_float_times([newval]) -> oldval\n\n\
2121Determine whether os.[lf]stat represents time stamps as float objects.\n\
2122If newval is True, future calls to stat() return floats, if it is False,\n\
2123future calls return ints. \n\
2124If newval is omitted, return the current setting.\n");
2125
2126static PyObject*
2127stat_float_times(PyObject* self, PyObject *args)
2128{
Victor Stinner8c62be82010-05-06 00:08:46 +00002129 int newval = -1;
2130 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2131 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002132 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2133 "stat_float_times() is deprecated",
2134 1))
2135 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 if (newval == -1)
2137 /* Return old value */
2138 return PyBool_FromLong(_stat_float_times);
2139 _stat_float_times = newval;
2140 Py_INCREF(Py_None);
2141 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002142}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002143
Larry Hastings6fe20b32012-04-19 15:07:49 -07002144static PyObject *billion = NULL;
2145
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002146static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002147fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002148{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002149 PyObject *s = _PyLong_FromTime_t(sec);
2150 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2151 PyObject *s_in_ns = NULL;
2152 PyObject *ns_total = NULL;
2153 PyObject *float_s = NULL;
2154
2155 if (!(s && ns_fractional))
2156 goto exit;
2157
2158 s_in_ns = PyNumber_Multiply(s, billion);
2159 if (!s_in_ns)
2160 goto exit;
2161
2162 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2163 if (!ns_total)
2164 goto exit;
2165
Victor Stinner4195b5c2012-02-08 23:03:19 +01002166 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002167 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2168 if (!float_s)
2169 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002171 else {
2172 float_s = s;
2173 Py_INCREF(float_s);
2174 }
2175
2176 PyStructSequence_SET_ITEM(v, index, s);
2177 PyStructSequence_SET_ITEM(v, index+3, float_s);
2178 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2179 s = NULL;
2180 float_s = NULL;
2181 ns_total = NULL;
2182exit:
2183 Py_XDECREF(s);
2184 Py_XDECREF(ns_fractional);
2185 Py_XDECREF(s_in_ns);
2186 Py_XDECREF(ns_total);
2187 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002188}
2189
Tim Peters5aa91602002-01-30 05:46:57 +00002190/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002191 (used by posix_stat() and posix_fstat()) */
2192static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002193_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002194{
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 unsigned long ansec, mnsec, cnsec;
2196 PyObject *v = PyStructSequence_New(&StatResultType);
2197 if (v == NULL)
2198 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002199
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002201#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 PyStructSequence_SET_ITEM(v, 1,
2203 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002204#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002206#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002207#ifdef MS_WINDOWS
2208 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2209#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 PyStructSequence_SET_ITEM(v, 2,
2211 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002212#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002213 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002214#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002216#if defined(MS_WINDOWS)
2217 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2218 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2219#else
2220 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2221 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2222#endif
Fred Drake699f3522000-06-29 21:12:41 +00002223#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002224 PyStructSequence_SET_ITEM(v, 6,
2225 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002226#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002228#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002229
Martin v. Löwis14694662006-02-03 12:54:16 +00002230#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002231 ansec = st->st_atim.tv_nsec;
2232 mnsec = st->st_mtim.tv_nsec;
2233 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002234#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 ansec = st->st_atimespec.tv_nsec;
2236 mnsec = st->st_mtimespec.tv_nsec;
2237 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002238#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 ansec = st->st_atime_nsec;
2240 mnsec = st->st_mtime_nsec;
2241 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002242#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002243 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002244#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002245 fill_time(v, 7, st->st_atime, ansec);
2246 fill_time(v, 8, st->st_mtime, mnsec);
2247 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002248
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002249#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2251 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002252#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002253#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2255 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002256#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002257#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2259 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002260#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002261#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2263 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002264#endif
2265#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002266 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002267 PyObject *val;
2268 unsigned long bsec,bnsec;
2269 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002270#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002271 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002272#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002273 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002274#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002275 if (_stat_float_times) {
2276 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2277 } else {
2278 val = PyLong_FromLong((long)bsec);
2279 }
2280 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2281 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002282 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002283#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002284#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002285 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2286 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002287#endif
Fred Drake699f3522000-06-29 21:12:41 +00002288
Victor Stinner8c62be82010-05-06 00:08:46 +00002289 if (PyErr_Occurred()) {
2290 Py_DECREF(v);
2291 return NULL;
2292 }
Fred Drake699f3522000-06-29 21:12:41 +00002293
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002295}
2296
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002297/* POSIX methods */
2298
Guido van Rossum94f6f721999-01-06 18:42:14 +00002299
2300static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002301posix_do_stat(char *function_name, path_t *path,
2302 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002304 STRUCT_STAT st;
2305 int result;
2306
2307#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2308 if (follow_symlinks_specified(function_name, follow_symlinks))
2309 return NULL;
2310#endif
2311
2312 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2313 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2314 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2315 return NULL;
2316
2317 Py_BEGIN_ALLOW_THREADS
2318 if (path->fd != -1)
2319 result = FSTAT(path->fd, &st);
2320 else
2321#ifdef MS_WINDOWS
2322 if (path->wide) {
2323 if (follow_symlinks)
2324 result = win32_stat_w(path->wide, &st);
2325 else
2326 result = win32_lstat_w(path->wide, &st);
2327 }
2328 else
2329#endif
2330#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2331 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2332 result = LSTAT(path->narrow, &st);
2333 else
2334#endif
2335#ifdef HAVE_FSTATAT
2336 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2337 result = fstatat(dir_fd, path->narrow, &st,
2338 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2339 else
2340#endif
2341 result = STAT(path->narrow, &st);
2342 Py_END_ALLOW_THREADS
2343
Victor Stinner292c8352012-10-30 02:17:38 +01002344 if (result != 0) {
2345 return path_error(path);
2346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002347
2348 return _pystat_fromstructstat(&st);
2349}
2350
Larry Hastings31826802013-10-19 00:09:25 -07002351#ifdef HAVE_FSTATAT
2352 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2353#else
2354 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2355#endif
2356
2357
Larry Hastings61272b72014-01-07 12:41:53 -08002358/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002359
2360class path_t_converter(CConverter):
2361
2362 type = "path_t"
2363 impl_by_reference = True
2364 parse_by_reference = True
2365
2366 converter = 'path_converter'
2367
2368 def converter_init(self, *, allow_fd=False, nullable=False):
2369 def strify(value):
2370 return str(int(bool(value)))
2371
2372 # right now path_t doesn't support default values.
2373 # to support a default value, you'll need to override initialize().
2374
2375 assert self.default is unspecified
2376
2377 self.nullable = nullable
2378 self.allow_fd = allow_fd
2379
2380 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2381 self.function.name,
2382 strify(nullable),
2383 strify(allow_fd),
2384 )
2385
2386 def cleanup(self):
2387 return "path_cleanup(&" + self.name + ");\n"
2388
2389
2390class dir_fd_converter(CConverter):
2391 type = 'int'
2392 converter = 'OS_STAT_DIR_FD_CONVERTER'
2393
2394 def converter_init(self):
2395 if self.default in (unspecified, None):
2396 self.c_default = 'DEFAULT_DIR_FD'
2397
2398
Larry Hastings61272b72014-01-07 12:41:53 -08002399[python start generated code]*/
2400/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
Larry Hastings31826802013-10-19 00:09:25 -07002401
Larry Hastings61272b72014-01-07 12:41:53 -08002402/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002403
Larry Hastings2a727912014-01-16 11:32:01 -08002404os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002405
2406 path : path_t(allow_fd=True)
2407 Path to be examined; can be string, bytes, or open-file-descriptor int.
2408
2409 *
2410
2411 dir_fd : dir_fd = None
2412 If not None, it should be a file descriptor open to a directory,
2413 and path should be a relative string; path will then be relative to
2414 that directory.
2415
2416 follow_symlinks: bool = True
2417 If False, and the last element of the path is a symbolic link,
2418 stat will examine the symbolic link itself instead of the file
2419 the link points to.
2420
2421Perform a stat system call on the given path.
2422
2423dir_fd and follow_symlinks may not be implemented
2424 on your platform. If they are unavailable, using them will raise a
2425 NotImplementedError.
2426
2427It's an error to use dir_fd or follow_symlinks when specifying path as
2428 an open file descriptor.
2429
Larry Hastings61272b72014-01-07 12:41:53 -08002430[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002431
2432PyDoc_STRVAR(os_stat__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002433"stat(path, *, dir_fd=None, follow_symlinks=True)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002434"Perform a stat system call on the given path.\n"
2435"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002436" path\n"
2437" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2438" dir_fd\n"
2439" If not None, it should be a file descriptor open to a directory,\n"
2440" and path should be a relative string; path will then be relative to\n"
2441" that directory.\n"
2442" follow_symlinks\n"
2443" If False, and the last element of the path is a symbolic link,\n"
2444" stat will examine the symbolic link itself instead of the file\n"
2445" the link points to.\n"
2446"\n"
2447"dir_fd and follow_symlinks may not be implemented\n"
2448" on your platform. If they are unavailable, using them will raise a\n"
2449" NotImplementedError.\n"
2450"\n"
2451"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2452" an open file descriptor.");
2453
2454#define OS_STAT_METHODDEF \
2455 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002456
2457static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002458os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002459
2460static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002461os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462{
Larry Hastings31826802013-10-19 00:09:25 -07002463 PyObject *return_value = NULL;
2464 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2465 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002466 int dir_fd = DEFAULT_DIR_FD;
2467 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468
Larry Hastings31826802013-10-19 00:09:25 -07002469 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2470 "O&|$O&p:stat", _keywords,
2471 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2472 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002473 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002474
2475exit:
2476 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002477 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002478
Larry Hastings9cf065c2012-06-22 16:30:09 -07002479 return return_value;
2480}
2481
Larry Hastings31826802013-10-19 00:09:25 -07002482static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002483os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings61272b72014-01-07 12:41:53 -08002484/*[clinic end generated code: checksum=85a71ad602e89f8e280118da976f70cd2f9abdf1]*/
Larry Hastings31826802013-10-19 00:09:25 -07002485{
2486 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2487}
2488
Larry Hastings9cf065c2012-06-22 16:30:09 -07002489PyDoc_STRVAR(posix_lstat__doc__,
2490"lstat(path, *, dir_fd=None) -> stat result\n\n\
2491Like stat(), but do not follow symbolic links.\n\
2492Equivalent to stat(path, follow_symlinks=False).");
2493
2494static PyObject *
2495posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2496{
2497 static char *keywords[] = {"path", "dir_fd", NULL};
2498 path_t path;
2499 int dir_fd = DEFAULT_DIR_FD;
2500 int follow_symlinks = 0;
2501 PyObject *return_value;
2502
2503 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002504 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002505 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2506 path_converter, &path,
2507#ifdef HAVE_FSTATAT
2508 dir_fd_converter, &dir_fd
2509#else
2510 dir_fd_unavailable, &dir_fd
2511#endif
2512 ))
2513 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002514 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002515 path_cleanup(&path);
2516 return return_value;
2517}
2518
Larry Hastings31826802013-10-19 00:09:25 -07002519
2520#ifdef HAVE_FACCESSAT
2521 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2522#else
2523 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2524#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002525/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002526os.access
Larry Hastings31826802013-10-19 00:09:25 -07002527
2528 path: path_t(allow_fd=True)
2529 Path to be tested; can be string, bytes, or open-file-descriptor int.
2530
2531 mode: int
2532 Operating-system mode bitfield. Can be F_OK to test existence,
2533 or the inclusive-OR of R_OK, W_OK, and X_OK.
2534
2535 *
2536
2537 dir_fd : dir_fd = None
2538 If not None, it should be a file descriptor open to a directory,
2539 and path should be relative; path will then be relative to that
2540 directory.
2541
2542 effective_ids: bool = False
2543 If True, access will use the effective uid/gid instead of
2544 the real uid/gid.
2545
2546 follow_symlinks: bool = True
2547 If False, and the last element of the path is a symbolic link,
2548 access will examine the symbolic link itself instead of the file
2549 the link points to.
2550
2551Use the real uid/gid to test for access to a path.
2552
2553{parameters}
2554dir_fd, effective_ids, and follow_symlinks may not be implemented
2555 on your platform. If they are unavailable, using them will raise a
2556 NotImplementedError.
2557
2558Note that most operations will use the effective uid/gid, therefore this
2559 routine can be used in a suid/sgid environment to test if the invoking user
2560 has the specified access to the path.
2561
Larry Hastings61272b72014-01-07 12:41:53 -08002562[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002563
2564PyDoc_STRVAR(os_access__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002565"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002566"Use the real uid/gid to test for access to a path.\n"
2567"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002568" path\n"
2569" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2570" mode\n"
2571" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2572" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2573" dir_fd\n"
2574" If not None, it should be a file descriptor open to a directory,\n"
2575" and path should be relative; path will then be relative to that\n"
2576" directory.\n"
2577" effective_ids\n"
2578" If True, access will use the effective uid/gid instead of\n"
2579" the real uid/gid.\n"
2580" follow_symlinks\n"
2581" If False, and the last element of the path is a symbolic link,\n"
2582" access will examine the symbolic link itself instead of the file\n"
2583" the link points to.\n"
2584"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002585"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2586" on your platform. If they are unavailable, using them will raise a\n"
2587" NotImplementedError.\n"
2588"\n"
2589"Note that most operations will use the effective uid/gid, therefore this\n"
2590" routine can be used in a suid/sgid environment to test if the invoking user\n"
2591" has the specified access to the path.");
2592
2593#define OS_ACCESS_METHODDEF \
2594 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595
2596static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002597os_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 -07002598
2599static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002600os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601{
Larry Hastings31826802013-10-19 00:09:25 -07002602 PyObject *return_value = NULL;
2603 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2604 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002605 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002606 int dir_fd = DEFAULT_DIR_FD;
2607 int effective_ids = 0;
2608 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002609
2610 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2611 "O&i|$O&pp:access", _keywords,
2612 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2613 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002614 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002615
2616exit:
2617 /* Cleanup for path */
2618 path_cleanup(&path);
2619
2620 return return_value;
2621}
2622
2623static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002624os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings61272b72014-01-07 12:41:53 -08002625/*[clinic end generated code: checksum=636e835c36562a2fc11acab75314634127fdf769]*/
Larry Hastings31826802013-10-19 00:09:25 -07002626{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002628
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002629#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002630 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002631#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002633#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634
Larry Hastings9cf065c2012-06-22 16:30:09 -07002635#ifndef HAVE_FACCESSAT
2636 if (follow_symlinks_specified("access", follow_symlinks))
2637 goto exit;
2638
2639 if (effective_ids) {
2640 argument_unavailable_error("access", "effective_ids");
2641 goto exit;
2642 }
2643#endif
2644
2645#ifdef MS_WINDOWS
2646 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002647 if (path->wide != NULL)
2648 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002650 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002651 Py_END_ALLOW_THREADS
2652
2653 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002654 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002655 * * we didn't get a -1, and
2656 * * write access wasn't requested,
2657 * * or the file isn't read-only,
2658 * * or it's a directory.
2659 * (Directories cannot be read-only on Windows.)
2660 */
2661 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002662 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002663 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002664 !(attr & FILE_ATTRIBUTE_READONLY) ||
2665 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2666#else
2667
2668 Py_BEGIN_ALLOW_THREADS
2669#ifdef HAVE_FACCESSAT
2670 if ((dir_fd != DEFAULT_DIR_FD) ||
2671 effective_ids ||
2672 !follow_symlinks) {
2673 int flags = 0;
2674 if (!follow_symlinks)
2675 flags |= AT_SYMLINK_NOFOLLOW;
2676 if (effective_ids)
2677 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002678 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002679 }
2680 else
2681#endif
Larry Hastings31826802013-10-19 00:09:25 -07002682 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002683 Py_END_ALLOW_THREADS
2684 return_value = PyBool_FromLong(!result);
2685#endif
2686
2687#ifndef HAVE_FACCESSAT
2688exit:
2689#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002691}
2692
Guido van Rossumd371ff11999-01-25 16:12:23 +00002693#ifndef F_OK
2694#define F_OK 0
2695#endif
2696#ifndef R_OK
2697#define R_OK 4
2698#endif
2699#ifndef W_OK
2700#define W_OK 2
2701#endif
2702#ifndef X_OK
2703#define X_OK 1
2704#endif
2705
Larry Hastings31826802013-10-19 00:09:25 -07002706
Guido van Rossumd371ff11999-01-25 16:12:23 +00002707#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002708
Larry Hastings61272b72014-01-07 12:41:53 -08002709/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002710os.ttyname -> DecodeFSDefault
2711
2712 fd: int
2713 Integer file descriptor handle.
2714
2715 /
2716
2717Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002718[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002719
2720PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002721"ttyname(fd)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002722"Return the name of the terminal device connected to \'fd\'.\n"
2723"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002724" fd\n"
2725" Integer file descriptor handle.");
2726
2727#define OS_TTYNAME_METHODDEF \
2728 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2729
2730static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002731os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002732
2733static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002734os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002735{
Larry Hastings31826802013-10-19 00:09:25 -07002736 PyObject *return_value = NULL;
2737 int fd;
2738 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002739
Larry Hastings31826802013-10-19 00:09:25 -07002740 if (!PyArg_ParseTuple(args,
2741 "i:ttyname",
2742 &fd))
2743 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002744 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002745 if (_return_value == NULL)
2746 goto exit;
2747 return_value = PyUnicode_DecodeFSDefault(_return_value);
2748
2749exit:
2750 return return_value;
2751}
2752
2753static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002754os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings61272b72014-01-07 12:41:53 -08002755/*[clinic end generated code: checksum=0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002756{
2757 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002758
Larry Hastings31826802013-10-19 00:09:25 -07002759 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002760 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002761 posix_error();
2762 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002763}
Larry Hastings31826802013-10-19 00:09:25 -07002764#else
2765#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002766#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002767
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002768#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002770"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002771Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002772
2773static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002774posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002775{
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 char *ret;
2777 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002778
Greg Wardb48bc172000-03-01 21:51:56 +00002779#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002780 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002781#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002782 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002783#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 if (ret == NULL)
2785 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002786 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002787}
2788#endif
2789
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002791"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792Change the current working directory to the specified path.\n\
2793\n\
2794path may always be specified as a string.\n\
2795On some platforms, path may also be specified as an open file descriptor.\n\
2796 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002797
Barry Warsaw53699e91996-12-10 23:23:01 +00002798static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002800{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801 path_t path;
2802 int result;
2803 PyObject *return_value = NULL;
2804 static char *keywords[] = {"path", NULL};
2805
2806 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002807 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808#ifdef HAVE_FCHDIR
2809 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002810#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2812 path_converter, &path
2813 ))
2814 return NULL;
2815
2816 Py_BEGIN_ALLOW_THREADS
2817#ifdef MS_WINDOWS
2818 if (path.wide)
2819 result = win32_wchdir(path.wide);
2820 else
2821 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002822 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823#else
2824#ifdef HAVE_FCHDIR
2825 if (path.fd != -1)
2826 result = fchdir(path.fd);
2827 else
2828#endif
2829 result = chdir(path.narrow);
2830#endif
2831 Py_END_ALLOW_THREADS
2832
2833 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002834 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 goto exit;
2836 }
2837
2838 return_value = Py_None;
2839 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002840
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841exit:
2842 path_cleanup(&path);
2843 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002844}
2845
Fred Drake4d1e64b2002-04-15 19:40:07 +00002846#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002847PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848"fchdir(fd)\n\n\
2849Change to the directory of the given file descriptor. fd must be\n\
2850opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002851
2852static PyObject *
2853posix_fchdir(PyObject *self, PyObject *fdobj)
2854{
Victor Stinner8c62be82010-05-06 00:08:46 +00002855 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002856}
2857#endif /* HAVE_FCHDIR */
2858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002859
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002860PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2862Change the access permissions of a file.\n\
2863\n\
2864path may always be specified as a string.\n\
2865On some platforms, path may also be specified as an open file descriptor.\n\
2866 If this functionality is unavailable, using it raises an exception.\n\
2867If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2868 and path should be relative; path will then be relative to that directory.\n\
2869If follow_symlinks is False, and the last element of the path is a symbolic\n\
2870 link, chmod will modify the symbolic link itself instead of the file the\n\
2871 link points to.\n\
2872It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2873 an open file descriptor.\n\
2874dir_fd and follow_symlinks may not be implemented on your platform.\n\
2875 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002879{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880 path_t path;
2881 int mode;
2882 int dir_fd = DEFAULT_DIR_FD;
2883 int follow_symlinks = 1;
2884 int result;
2885 PyObject *return_value = NULL;
2886 static char *keywords[] = {"path", "mode", "dir_fd",
2887 "follow_symlinks", NULL};
2888
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002889#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002890 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002892
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893#ifdef HAVE_FCHMODAT
2894 int fchmodat_nofollow_unsupported = 0;
2895#endif
2896
2897 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002898 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899#ifdef HAVE_FCHMOD
2900 path.allow_fd = 1;
2901#endif
2902 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2903 path_converter, &path,
2904 &mode,
2905#ifdef HAVE_FCHMODAT
2906 dir_fd_converter, &dir_fd,
2907#else
2908 dir_fd_unavailable, &dir_fd,
2909#endif
2910 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002912
2913#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2914 if (follow_symlinks_specified("chmod", follow_symlinks))
2915 goto exit;
2916#endif
2917
2918#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002919 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002920 if (path.wide)
2921 attr = GetFileAttributesW(path.wide);
2922 else
2923 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002924 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002925 result = 0;
2926 else {
2927 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 attr &= ~FILE_ATTRIBUTE_READONLY;
2929 else
2930 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931 if (path.wide)
2932 result = SetFileAttributesW(path.wide, attr);
2933 else
2934 result = SetFileAttributesA(path.narrow, attr);
2935 }
2936 Py_END_ALLOW_THREADS
2937
2938 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002939 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940 goto exit;
2941 }
2942#else /* MS_WINDOWS */
2943 Py_BEGIN_ALLOW_THREADS
2944#ifdef HAVE_FCHMOD
2945 if (path.fd != -1)
2946 result = fchmod(path.fd, mode);
2947 else
2948#endif
2949#ifdef HAVE_LCHMOD
2950 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2951 result = lchmod(path.narrow, mode);
2952 else
2953#endif
2954#ifdef HAVE_FCHMODAT
2955 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2956 /*
2957 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2958 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002959 * and then says it isn't implemented yet.
2960 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002961 *
2962 * Once it is supported, os.chmod will automatically
2963 * support dir_fd and follow_symlinks=False. (Hopefully.)
2964 * Until then, we need to be careful what exception we raise.
2965 */
2966 result = fchmodat(dir_fd, path.narrow, mode,
2967 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2968 /*
2969 * But wait! We can't throw the exception without allowing threads,
2970 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2971 */
2972 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002973 result &&
2974 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2975 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002976 }
2977 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002978#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979 result = chmod(path.narrow, mode);
2980 Py_END_ALLOW_THREADS
2981
2982 if (result) {
2983#ifdef HAVE_FCHMODAT
2984 if (fchmodat_nofollow_unsupported) {
2985 if (dir_fd != DEFAULT_DIR_FD)
2986 dir_fd_and_follow_symlinks_invalid("chmod",
2987 dir_fd, follow_symlinks);
2988 else
2989 follow_symlinks_specified("chmod", follow_symlinks);
2990 }
2991 else
2992#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002993 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994 goto exit;
2995 }
2996#endif
2997
2998 Py_INCREF(Py_None);
2999 return_value = Py_None;
3000exit:
3001 path_cleanup(&path);
3002 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003003}
3004
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005
Christian Heimes4e30a842007-11-30 22:12:06 +00003006#ifdef HAVE_FCHMOD
3007PyDoc_STRVAR(posix_fchmod__doc__,
3008"fchmod(fd, mode)\n\n\
3009Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003011
3012static PyObject *
3013posix_fchmod(PyObject *self, PyObject *args)
3014{
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 int fd, mode, res;
3016 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3017 return NULL;
3018 Py_BEGIN_ALLOW_THREADS
3019 res = fchmod(fd, mode);
3020 Py_END_ALLOW_THREADS
3021 if (res < 0)
3022 return posix_error();
3023 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003024}
3025#endif /* HAVE_FCHMOD */
3026
3027#ifdef HAVE_LCHMOD
3028PyDoc_STRVAR(posix_lchmod__doc__,
3029"lchmod(path, mode)\n\n\
3030Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003031affects the link itself rather than the target.\n\
3032Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003033
3034static PyObject *
3035posix_lchmod(PyObject *self, PyObject *args)
3036{
Victor Stinner292c8352012-10-30 02:17:38 +01003037 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 int i;
3039 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003040 memset(&path, 0, sizeof(path));
3041 path.function_name = "lchmod";
3042 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3043 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003044 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003046 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003048 if (res < 0) {
3049 path_error(&path);
3050 path_cleanup(&path);
3051 return NULL;
3052 }
3053 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003054 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003055}
3056#endif /* HAVE_LCHMOD */
3057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003058
Thomas Wouterscf297e42007-02-23 15:07:44 +00003059#ifdef HAVE_CHFLAGS
3060PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003061"chflags(path, flags, *, follow_symlinks=True)\n\n\
3062Set file flags.\n\
3063\n\
3064If follow_symlinks is False, and the last element of the path is a symbolic\n\
3065 link, chflags will change flags on the symbolic link itself instead of the\n\
3066 file the link points to.\n\
3067follow_symlinks may not be implemented on your platform. If it is\n\
3068unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003069
3070static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003071posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003072{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003073 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003074 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075 int follow_symlinks = 1;
3076 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003077 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3079
3080 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003081 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3083 path_converter, &path,
3084 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003085 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003086
3087#ifndef HAVE_LCHFLAGS
3088 if (follow_symlinks_specified("chflags", follow_symlinks))
3089 goto exit;
3090#endif
3091
Victor Stinner8c62be82010-05-06 00:08:46 +00003092 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093#ifdef HAVE_LCHFLAGS
3094 if (!follow_symlinks)
3095 result = lchflags(path.narrow, flags);
3096 else
3097#endif
3098 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003099 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100
3101 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003102 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103 goto exit;
3104 }
3105
3106 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003107 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108
3109exit:
3110 path_cleanup(&path);
3111 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003112}
3113#endif /* HAVE_CHFLAGS */
3114
3115#ifdef HAVE_LCHFLAGS
3116PyDoc_STRVAR(posix_lchflags__doc__,
3117"lchflags(path, flags)\n\n\
3118Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119This function will not follow symbolic links.\n\
3120Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003121
3122static PyObject *
3123posix_lchflags(PyObject *self, PyObject *args)
3124{
Victor Stinner292c8352012-10-30 02:17:38 +01003125 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 unsigned long flags;
3127 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003128 memset(&path, 0, sizeof(path));
3129 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003130 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003131 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003132 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003134 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003136 if (res < 0) {
3137 path_error(&path);
3138 path_cleanup(&path);
3139 return NULL;
3140 }
3141 path_cleanup(&path);
3142 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003143}
3144#endif /* HAVE_LCHFLAGS */
3145
Martin v. Löwis244edc82001-10-04 22:44:26 +00003146#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003147PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003148"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003149Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003150
3151static PyObject *
3152posix_chroot(PyObject *self, PyObject *args)
3153{
Victor Stinner292c8352012-10-30 02:17:38 +01003154 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003155}
3156#endif
3157
Guido van Rossum21142a01999-01-08 21:05:37 +00003158#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003159PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003160"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003161force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003162
3163static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003164posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003165{
Stefan Krah0e803b32010-11-26 16:16:47 +00003166 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003167}
3168#endif /* HAVE_FSYNC */
3169
Ross Lagerwall7807c352011-03-17 20:20:30 +02003170#ifdef HAVE_SYNC
3171PyDoc_STRVAR(posix_sync__doc__,
3172"sync()\n\n\
3173Force write of everything to disk.");
3174
3175static PyObject *
3176posix_sync(PyObject *self, PyObject *noargs)
3177{
3178 Py_BEGIN_ALLOW_THREADS
3179 sync();
3180 Py_END_ALLOW_THREADS
3181 Py_RETURN_NONE;
3182}
3183#endif
3184
Guido van Rossum21142a01999-01-08 21:05:37 +00003185#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003186
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003187#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003188extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3189#endif
3190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003191PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003192"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003193force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003194 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003195
3196static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003197posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003198{
Stefan Krah0e803b32010-11-26 16:16:47 +00003199 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003200}
3201#endif /* HAVE_FDATASYNC */
3202
3203
Fredrik Lundh10723342000-07-10 16:38:09 +00003204#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003205PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3207Change the owner and group id of path to the numeric uid and gid.\n\
3208\n\
3209path may always be specified as a string.\n\
3210On some platforms, path may also be specified as an open file descriptor.\n\
3211 If this functionality is unavailable, using it raises an exception.\n\
3212If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3213 and path should be relative; path will then be relative to that directory.\n\
3214If follow_symlinks is False, and the last element of the path is a symbolic\n\
3215 link, chown will modify the symbolic link itself instead of the file the\n\
3216 link points to.\n\
3217It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3218 an open file descriptor.\n\
3219dir_fd and follow_symlinks may not be implemented on your platform.\n\
3220 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221
Barry Warsaw53699e91996-12-10 23:23:01 +00003222static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003224{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003226 uid_t uid;
3227 gid_t gid;
3228 int dir_fd = DEFAULT_DIR_FD;
3229 int follow_symlinks = 1;
3230 int result;
3231 PyObject *return_value = NULL;
3232 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3233 "follow_symlinks", NULL};
3234
3235 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003236 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003237#ifdef HAVE_FCHOWN
3238 path.allow_fd = 1;
3239#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003240 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003241 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003242 _Py_Uid_Converter, &uid,
3243 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003244#ifdef HAVE_FCHOWNAT
3245 dir_fd_converter, &dir_fd,
3246#else
3247 dir_fd_unavailable, &dir_fd,
3248#endif
3249 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003251
3252#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3253 if (follow_symlinks_specified("chown", follow_symlinks))
3254 goto exit;
3255#endif
3256 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3257 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3258 goto exit;
3259
3260#ifdef __APPLE__
3261 /*
3262 * This is for Mac OS X 10.3, which doesn't have lchown.
3263 * (But we still have an lchown symbol because of weak-linking.)
3264 * It doesn't have fchownat either. So there's no possibility
3265 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003266 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267 if ((!follow_symlinks) && (lchown == NULL)) {
3268 follow_symlinks_specified("chown", follow_symlinks);
3269 goto exit;
3270 }
3271#endif
3272
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274#ifdef HAVE_FCHOWN
3275 if (path.fd != -1)
3276 result = fchown(path.fd, uid, gid);
3277 else
3278#endif
3279#ifdef HAVE_LCHOWN
3280 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3281 result = lchown(path.narrow, uid, gid);
3282 else
3283#endif
3284#ifdef HAVE_FCHOWNAT
3285 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3286 result = fchownat(dir_fd, path.narrow, uid, gid,
3287 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3288 else
3289#endif
3290 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292
3293 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003294 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 goto exit;
3296 }
3297
3298 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300
3301exit:
3302 path_cleanup(&path);
3303 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003305#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003306
Christian Heimes4e30a842007-11-30 22:12:06 +00003307#ifdef HAVE_FCHOWN
3308PyDoc_STRVAR(posix_fchown__doc__,
3309"fchown(fd, uid, gid)\n\n\
3310Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003312
3313static PyObject *
3314posix_fchown(PyObject *self, PyObject *args)
3315{
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003317 uid_t uid;
3318 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003320 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3321 _Py_Uid_Converter, &uid,
3322 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 return NULL;
3324 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003325 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 Py_END_ALLOW_THREADS
3327 if (res < 0)
3328 return posix_error();
3329 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003330}
3331#endif /* HAVE_FCHOWN */
3332
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003333#ifdef HAVE_LCHOWN
3334PyDoc_STRVAR(posix_lchown__doc__,
3335"lchown(path, uid, gid)\n\n\
3336Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337This function will not follow symbolic links.\n\
3338Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003339
3340static PyObject *
3341posix_lchown(PyObject *self, PyObject *args)
3342{
Victor Stinner292c8352012-10-30 02:17:38 +01003343 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003344 uid_t uid;
3345 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003347 memset(&path, 0, sizeof(path));
3348 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003349 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003350 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003351 _Py_Uid_Converter, &uid,
3352 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003355 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003357 if (res < 0) {
3358 path_error(&path);
3359 path_cleanup(&path);
3360 return NULL;
3361 }
3362 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 Py_INCREF(Py_None);
3364 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003365}
3366#endif /* HAVE_LCHOWN */
3367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003368
Barry Warsaw53699e91996-12-10 23:23:01 +00003369static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003370posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003371{
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 char buf[1026];
3373 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003374
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003375#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 if (!use_bytes) {
3377 wchar_t wbuf[1026];
3378 wchar_t *wbuf2 = wbuf;
3379 PyObject *resobj;
3380 DWORD len;
3381 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003382 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003383 /* If the buffer is large enough, len does not include the
3384 terminating \0. If the buffer is too small, len includes
3385 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003386 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003387 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 if (wbuf2)
3389 len = GetCurrentDirectoryW(len, wbuf2);
3390 }
3391 Py_END_ALLOW_THREADS
3392 if (!wbuf2) {
3393 PyErr_NoMemory();
3394 return NULL;
3395 }
3396 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003397 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003398 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003399 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 }
3401 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003402 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003403 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 return resobj;
3405 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003406
3407 if (win32_warn_bytes_api())
3408 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003409#endif
3410
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 Py_END_ALLOW_THREADS
3414 if (res == NULL)
3415 return posix_error();
3416 if (use_bytes)
3417 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003418 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003419}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003420
3421PyDoc_STRVAR(posix_getcwd__doc__,
3422"getcwd() -> path\n\n\
3423Return a unicode string representing the current working directory.");
3424
3425static PyObject *
3426posix_getcwd_unicode(PyObject *self)
3427{
3428 return posix_getcwd(0);
3429}
3430
3431PyDoc_STRVAR(posix_getcwdb__doc__,
3432"getcwdb() -> path\n\n\
3433Return a bytes string representing the current working directory.");
3434
3435static PyObject *
3436posix_getcwd_bytes(PyObject *self)
3437{
3438 return posix_getcwd(1);
3439}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003440
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3442#define HAVE_LINK 1
3443#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003444
Guido van Rossumb6775db1994-08-01 11:34:53 +00003445#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003446PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3448Create a hard link to a file.\n\
3449\n\
3450If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3451 descriptor open to a directory, and the respective path string (src or dst)\n\
3452 should be relative; the path will then be relative to that directory.\n\
3453If follow_symlinks is False, and the last element of src is a symbolic\n\
3454 link, link will create a link to the symbolic link itself instead of the\n\
3455 file the link points to.\n\
3456src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3457 platform. If they are unavailable, using them will raise a\n\
3458 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003459
Barry Warsaw53699e91996-12-10 23:23:01 +00003460static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003462{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 path_t src, dst;
3464 int src_dir_fd = DEFAULT_DIR_FD;
3465 int dst_dir_fd = DEFAULT_DIR_FD;
3466 int follow_symlinks = 1;
3467 PyObject *return_value = NULL;
3468 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3469 "follow_symlinks", NULL};
3470#ifdef MS_WINDOWS
3471 BOOL result;
3472#else
3473 int result;
3474#endif
3475
3476 memset(&src, 0, sizeof(src));
3477 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003478 src.function_name = "link";
3479 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3481 path_converter, &src,
3482 path_converter, &dst,
3483 dir_fd_converter, &src_dir_fd,
3484 dir_fd_converter, &dst_dir_fd,
3485 &follow_symlinks))
3486 return NULL;
3487
3488#ifndef HAVE_LINKAT
3489 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3490 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3491 goto exit;
3492 }
3493#endif
3494
3495 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3496 PyErr_SetString(PyExc_NotImplementedError,
3497 "link: src and dst must be the same type");
3498 goto exit;
3499 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003500
Brian Curtin1b9df392010-11-24 20:24:31 +00003501#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_BEGIN_ALLOW_THREADS
3503 if (src.wide)
3504 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3505 else
3506 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3507 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003508
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003510 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003512 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513#else
3514 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003515#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3517 (dst_dir_fd != DEFAULT_DIR_FD) ||
3518 (!follow_symlinks))
3519 result = linkat(src_dir_fd, src.narrow,
3520 dst_dir_fd, dst.narrow,
3521 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3522 else
3523#endif
3524 result = link(src.narrow, dst.narrow);
3525 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003526
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003528 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003530 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531#endif
3532
3533 return_value = Py_None;
3534 Py_INCREF(Py_None);
3535
3536exit:
3537 path_cleanup(&src);
3538 path_cleanup(&dst);
3539 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003540}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541#endif
3542
Brian Curtin1b9df392010-11-24 20:24:31 +00003543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003545PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003546"listdir(path='.') -> list_of_filenames\n\n\
3547Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549entries '.' and '..' even if they are present in the directory.\n\
3550\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003551path can be specified as either str or bytes. If path is bytes,\n\
3552 the filenames returned will also be bytes; in all other circumstances\n\
3553 the filenames returned will be str.\n\
3554On some platforms, path may also be specified as an open file descriptor;\n\
3555 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003557
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003558#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003559static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003560_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003561{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 PyObject *v;
3564 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3565 BOOL result;
3566 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003567 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568 char *bufptr = namebuf;
3569 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003570 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 PyObject *po = NULL;
3572 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573
Gregory P. Smith40a21602013-03-20 20:52:50 -07003574 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003577
Gregory P. Smith40a21602013-03-20 20:52:50 -07003578 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003579 po_wchars = L".";
3580 len = 1;
3581 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003582 po_wchars = path->wide;
3583 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003584 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003586 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 if (!wnamebuf) {
3588 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003591 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003593 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003594 if (wch != SEP && wch != ALTSEP && wch != L':')
3595 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 wcscpy(wnamebuf + len, L"*.*");
3597 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 if ((list = PyList_New(0)) == NULL) {
3599 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003601 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003603 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 if (hFindFile == INVALID_HANDLE_VALUE) {
3605 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 if (error == ERROR_FILE_NOT_FOUND)
3607 goto exit;
3608 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003609 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 }
3612 do {
3613 /* Skip over . and .. */
3614 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3615 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 v = PyUnicode_FromWideChar(wFileData.cFileName,
3617 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 Py_DECREF(list);
3620 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 break;
3622 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 Py_DECREF(list);
3626 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 break;
3628 }
3629 Py_DECREF(v);
3630 }
3631 Py_BEGIN_ALLOW_THREADS
3632 result = FindNextFileW(hFindFile, &wFileData);
3633 Py_END_ALLOW_THREADS
3634 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3635 it got to the end of the directory. */
3636 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003638 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 }
3641 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003642
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003645 strcpy(namebuf, path->narrow);
3646 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 if (len > 0) {
3648 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003649 if (ch != '\\' && ch != '/' && ch != ':')
3650 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 strcpy(namebuf + len, "*.*");
3652 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003653
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003656
Antoine Pitroub73caab2010-08-09 23:39:31 +00003657 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003659 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 if (hFindFile == INVALID_HANDLE_VALUE) {
3661 int error = GetLastError();
3662 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 goto exit;
3664 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003665 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 }
3668 do {
3669 /* Skip over . and .. */
3670 if (strcmp(FileData.cFileName, ".") != 0 &&
3671 strcmp(FileData.cFileName, "..") != 0) {
3672 v = PyBytes_FromString(FileData.cFileName);
3673 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_DECREF(list);
3675 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 break;
3677 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 Py_DECREF(list);
3681 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 break;
3683 }
3684 Py_DECREF(v);
3685 }
3686 Py_BEGIN_ALLOW_THREADS
3687 result = FindNextFile(hFindFile, &FileData);
3688 Py_END_ALLOW_THREADS
3689 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3690 it got to the end of the directory. */
3691 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003693 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 }
3696 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003697
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698exit:
3699 if (hFindFile != INVALID_HANDLE_VALUE) {
3700 if (FindClose(hFindFile) == FALSE) {
3701 if (list != NULL) {
3702 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003703 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704 }
3705 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003707 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003708
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003710} /* end of _listdir_windows_no_opendir */
3711
3712#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3713
3714static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003715_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003716{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003717 PyObject *v;
3718 DIR *dirp = NULL;
3719 struct dirent *ep;
3720 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003721#ifdef HAVE_FDOPENDIR
3722 int fd = -1;
3723#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003724
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003727 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003729 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003730 if (fd == -1)
3731 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003732
Larry Hastingsfdaea062012-06-25 04:42:23 -07003733 return_str = 1;
3734
Larry Hastings9cf065c2012-06-22 16:30:09 -07003735 Py_BEGIN_ALLOW_THREADS
3736 dirp = fdopendir(fd);
3737 Py_END_ALLOW_THREADS
3738 }
3739 else
3740#endif
3741 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003742 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003743 if (path->narrow) {
3744 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003745 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003746 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003747 }
3748 else {
3749 name = ".";
3750 return_str = 1;
3751 }
3752
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 Py_BEGIN_ALLOW_THREADS
3754 dirp = opendir(name);
3755 Py_END_ALLOW_THREADS
3756 }
3757
3758 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003759 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003760#ifdef HAVE_FDOPENDIR
3761 if (fd != -1) {
3762 Py_BEGIN_ALLOW_THREADS
3763 close(fd);
3764 Py_END_ALLOW_THREADS
3765 }
3766#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003767 goto exit;
3768 }
3769 if ((list = PyList_New(0)) == NULL) {
3770 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 }
3772 for (;;) {
3773 errno = 0;
3774 Py_BEGIN_ALLOW_THREADS
3775 ep = readdir(dirp);
3776 Py_END_ALLOW_THREADS
3777 if (ep == NULL) {
3778 if (errno == 0) {
3779 break;
3780 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003781 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003782 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003783 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 }
3785 }
3786 if (ep->d_name[0] == '.' &&
3787 (NAMLEN(ep) == 1 ||
3788 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3789 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003790 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003791 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3792 else
3793 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003795 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 break;
3797 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003798 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 break;
3802 }
3803 Py_DECREF(v);
3804 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003805
Larry Hastings9cf065c2012-06-22 16:30:09 -07003806exit:
3807 if (dirp != NULL) {
3808 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003809#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003810 if (fd > -1)
3811 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003812#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003813 closedir(dirp);
3814 Py_END_ALLOW_THREADS
3815 }
3816
Larry Hastings9cf065c2012-06-22 16:30:09 -07003817 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003818} /* end of _posix_listdir */
3819#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003820
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003821static PyObject *
3822posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3823{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003824 path_t path;
3825 PyObject *list = NULL;
3826 static char *keywords[] = {"path", NULL};
3827 PyObject *return_value;
3828
3829 memset(&path, 0, sizeof(path));
3830 path.function_name = "listdir";
3831 path.nullable = 1;
3832#ifdef HAVE_FDOPENDIR
3833 path.allow_fd = 1;
3834 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003835#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003836
3837 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3838 path_converter, &path)) {
3839 return NULL;
3840 }
3841
3842#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3843 return_value = _listdir_windows_no_opendir(&path, list);
3844#else
3845 return_value = _posix_listdir(&path, list);
3846#endif
3847 path_cleanup(&path);
3848 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003849}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003850
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003851#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003852/* A helper function for abspath on win32 */
3853static PyObject *
3854posix__getfullpathname(PyObject *self, PyObject *args)
3855{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003856 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003857 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003858 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003859 PyObject *po;
3860
3861 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3862 {
3863 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003864 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003865 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003866 DWORD result;
3867 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003868
3869 wpath = PyUnicode_AsUnicode(po);
3870 if (wpath == NULL)
3871 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003873 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003875 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003876 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 if (!woutbufp)
3878 return PyErr_NoMemory();
3879 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3880 }
3881 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003882 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003884 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003886 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 return v;
3888 }
3889 /* Drop the argument parsing error as narrow strings
3890 are also valid. */
3891 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003892
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003893 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3894 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003896 if (win32_warn_bytes_api())
3897 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003898 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 outbuf, &temp)) {
3900 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 return NULL;
3902 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3904 return PyUnicode_Decode(outbuf, strlen(outbuf),
3905 Py_FileSystemDefaultEncoding, NULL);
3906 }
3907 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003908} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003909
Brian Curtind25aef52011-06-13 15:16:04 -05003910
Brian Curtinf5e76d02010-11-24 13:14:05 +00003911
Brian Curtind40e6f72010-07-08 21:39:08 +00003912/* A helper function for samepath on windows */
3913static PyObject *
3914posix__getfinalpathname(PyObject *self, PyObject *args)
3915{
3916 HANDLE hFile;
3917 int buf_size;
3918 wchar_t *target_path;
3919 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003920 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003921 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003922
Victor Stinnereb5657a2011-09-30 01:44:27 +02003923 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003924 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003925 path = PyUnicode_AsUnicode(po);
3926 if (path == NULL)
3927 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003928
3929 if(!check_GetFinalPathNameByHandle()) {
3930 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3931 NotImplementedError. */
3932 return PyErr_Format(PyExc_NotImplementedError,
3933 "GetFinalPathNameByHandle not available on this platform");
3934 }
3935
3936 hFile = CreateFileW(
3937 path,
3938 0, /* desired access */
3939 0, /* share mode */
3940 NULL, /* security attributes */
3941 OPEN_EXISTING,
3942 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3943 FILE_FLAG_BACKUP_SEMANTICS,
3944 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003945
Victor Stinnereb5657a2011-09-30 01:44:27 +02003946 if(hFile == INVALID_HANDLE_VALUE)
3947 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003948
3949 /* We have a good handle to the target, use it to determine the
3950 target path name. */
3951 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3952
3953 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003954 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003955
Victor Stinnerb6404912013-07-07 16:21:41 +02003956 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003957 if(!target_path)
3958 return PyErr_NoMemory();
3959
3960 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3961 buf_size, VOLUME_NAME_DOS);
3962 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003963 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003964
3965 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003966 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003967
3968 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003969 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003970 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003971 return result;
3972
3973} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003974
Brian Curtin95d028f2011-06-09 09:10:38 -05003975PyDoc_STRVAR(posix__isdir__doc__,
3976"Return true if the pathname refers to an existing directory.");
3977
Brian Curtin9c669cc2011-06-08 18:17:18 -05003978static PyObject *
3979posix__isdir(PyObject *self, PyObject *args)
3980{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003981 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003982 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003983 DWORD attributes;
3984
3985 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003986 wchar_t *wpath = PyUnicode_AsUnicode(po);
3987 if (wpath == NULL)
3988 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003989
3990 attributes = GetFileAttributesW(wpath);
3991 if (attributes == INVALID_FILE_ATTRIBUTES)
3992 Py_RETURN_FALSE;
3993 goto check;
3994 }
3995 /* Drop the argument parsing error as narrow strings
3996 are also valid. */
3997 PyErr_Clear();
3998
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003999 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004000 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004001 if (win32_warn_bytes_api())
4002 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004003 attributes = GetFileAttributesA(path);
4004 if (attributes == INVALID_FILE_ATTRIBUTES)
4005 Py_RETURN_FALSE;
4006
4007check:
4008 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4009 Py_RETURN_TRUE;
4010 else
4011 Py_RETURN_FALSE;
4012}
Tim Golden6b528062013-08-01 12:44:00 +01004013
4014PyDoc_STRVAR(posix__getvolumepathname__doc__,
4015"Return volume mount point of the specified path.");
4016
4017/* A helper function for ismount on windows */
4018static PyObject *
4019posix__getvolumepathname(PyObject *self, PyObject *args)
4020{
4021 PyObject *po, *result;
4022 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004023 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004024 BOOL ret;
4025
4026 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4027 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004028 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004029 if (path == NULL)
4030 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004031 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004032
4033 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004034 buflen = Py_MAX(buflen, MAX_PATH);
4035
4036 if (buflen > DWORD_MAX) {
4037 PyErr_SetString(PyExc_OverflowError, "path too long");
4038 return NULL;
4039 }
4040
4041 mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
Tim Golden6b528062013-08-01 12:44:00 +01004042 if (mountpath == NULL)
4043 return PyErr_NoMemory();
4044
4045 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004046 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004047 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004048 Py_END_ALLOW_THREADS
4049
4050 if (!ret) {
4051 result = win32_error_object("_getvolumepathname", po);
4052 goto exit;
4053 }
4054 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4055
4056exit:
4057 PyMem_Free(mountpath);
4058 return result;
4059}
4060/* end of posix__getvolumepathname */
4061
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004062#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004064PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4066Create a directory.\n\
4067\n\
4068If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4069 and path should be relative; path will then be relative to that directory.\n\
4070dir_fd may not be implemented on your platform.\n\
4071 If it is unavailable, using it will raise a NotImplementedError.\n\
4072\n\
4073The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Barry Warsaw53699e91996-12-10 23:23:01 +00004075static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004077{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080 int dir_fd = DEFAULT_DIR_FD;
4081 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4082 PyObject *return_value = NULL;
4083 int result;
4084
4085 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004086 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4088 path_converter, &path, &mode,
4089#ifdef HAVE_MKDIRAT
4090 dir_fd_converter, &dir_fd
4091#else
4092 dir_fd_unavailable, &dir_fd
4093#endif
4094 ))
4095 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004096
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004097#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004098 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004099 if (path.wide)
4100 result = CreateDirectoryW(path.wide, NULL);
4101 else
4102 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004103 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004104
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004106 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107 goto exit;
4108 }
4109#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004110 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111#if HAVE_MKDIRAT
4112 if (dir_fd != DEFAULT_DIR_FD)
4113 result = mkdirat(dir_fd, path.narrow, mode);
4114 else
4115#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004116#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004117 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004118#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004120#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004121 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004123 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 goto exit;
4125 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004126#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 return_value = Py_None;
4128 Py_INCREF(Py_None);
4129exit:
4130 path_cleanup(&path);
4131 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004132}
4133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004134
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004135/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4136#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004137#include <sys/resource.h>
4138#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004139
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004140
4141#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004142PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004143"nice(inc) -> new_priority\n\n\
4144Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Barry Warsaw53699e91996-12-10 23:23:01 +00004146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004147posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004148{
Victor Stinner8c62be82010-05-06 00:08:46 +00004149 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004150
Victor Stinner8c62be82010-05-06 00:08:46 +00004151 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4152 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004153
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 /* There are two flavours of 'nice': one that returns the new
4155 priority (as required by almost all standards out there) and the
4156 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4157 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004158
Victor Stinner8c62be82010-05-06 00:08:46 +00004159 If we are of the nice family that returns the new priority, we
4160 need to clear errno before the call, and check if errno is filled
4161 before calling posix_error() on a returnvalue of -1, because the
4162 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004163
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 errno = 0;
4165 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004166#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 if (value == 0)
4168 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004169#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 if (value == -1 && errno != 0)
4171 /* either nice() or getpriority() returned an error */
4172 return posix_error();
4173 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004174}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004175#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004176
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004177
4178#ifdef HAVE_GETPRIORITY
4179PyDoc_STRVAR(posix_getpriority__doc__,
4180"getpriority(which, who) -> current_priority\n\n\
4181Get program scheduling priority.");
4182
4183static PyObject *
4184posix_getpriority(PyObject *self, PyObject *args)
4185{
4186 int which, who, retval;
4187
4188 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4189 return NULL;
4190 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004191 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004192 if (errno != 0)
4193 return posix_error();
4194 return PyLong_FromLong((long)retval);
4195}
4196#endif /* HAVE_GETPRIORITY */
4197
4198
4199#ifdef HAVE_SETPRIORITY
4200PyDoc_STRVAR(posix_setpriority__doc__,
4201"setpriority(which, who, prio) -> None\n\n\
4202Set program scheduling priority.");
4203
4204static PyObject *
4205posix_setpriority(PyObject *self, PyObject *args)
4206{
4207 int which, who, prio, retval;
4208
4209 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4210 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004211 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004212 if (retval == -1)
4213 return posix_error();
4214 Py_RETURN_NONE;
4215}
4216#endif /* HAVE_SETPRIORITY */
4217
4218
Barry Warsaw53699e91996-12-10 23:23:01 +00004219static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004220internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004221{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004222 char *function_name = is_replace ? "replace" : "rename";
4223 path_t src;
4224 path_t dst;
4225 int src_dir_fd = DEFAULT_DIR_FD;
4226 int dst_dir_fd = DEFAULT_DIR_FD;
4227 int dir_fd_specified;
4228 PyObject *return_value = NULL;
4229 char format[24];
4230 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4231
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004232#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004234 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004235#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004236 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004237#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004238
4239 memset(&src, 0, sizeof(src));
4240 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004241 src.function_name = function_name;
4242 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243 strcpy(format, "O&O&|$O&O&:");
4244 strcat(format, function_name);
4245 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4246 path_converter, &src,
4247 path_converter, &dst,
4248 dir_fd_converter, &src_dir_fd,
4249 dir_fd_converter, &dst_dir_fd))
4250 return NULL;
4251
4252 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4253 (dst_dir_fd != DEFAULT_DIR_FD);
4254#ifndef HAVE_RENAMEAT
4255 if (dir_fd_specified) {
4256 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4257 goto exit;
4258 }
4259#endif
4260
4261 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4262 PyErr_Format(PyExc_ValueError,
4263 "%s: src and dst must be the same type", function_name);
4264 goto exit;
4265 }
4266
4267#ifdef MS_WINDOWS
4268 Py_BEGIN_ALLOW_THREADS
4269 if (src.wide)
4270 result = MoveFileExW(src.wide, dst.wide, flags);
4271 else
4272 result = MoveFileExA(src.narrow, dst.narrow, flags);
4273 Py_END_ALLOW_THREADS
4274
4275 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004276 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277 goto exit;
4278 }
4279
4280#else
4281 Py_BEGIN_ALLOW_THREADS
4282#ifdef HAVE_RENAMEAT
4283 if (dir_fd_specified)
4284 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4285 else
4286#endif
4287 result = rename(src.narrow, dst.narrow);
4288 Py_END_ALLOW_THREADS
4289
4290 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004291 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004292 goto exit;
4293 }
4294#endif
4295
4296 Py_INCREF(Py_None);
4297 return_value = Py_None;
4298exit:
4299 path_cleanup(&src);
4300 path_cleanup(&dst);
4301 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004302}
4303
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004304PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4306Rename a file or directory.\n\
4307\n\
4308If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4309 descriptor open to a directory, and the respective path string (src or dst)\n\
4310 should be relative; the path will then be relative to that directory.\n\
4311src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4312 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004313
4314static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004316{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004318}
4319
4320PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004321"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4322Rename a file or directory, overwriting the destination.\n\
4323\n\
4324If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4325 descriptor open to a directory, and the respective path string (src or dst)\n\
4326 should be relative; the path will then be relative to that directory.\n\
4327src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4328 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004329
4330static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004332{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004333 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004334}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004336PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004337"rmdir(path, *, dir_fd=None)\n\n\
4338Remove a directory.\n\
4339\n\
4340If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4341 and path should be relative; path will then be relative to that directory.\n\
4342dir_fd may not be implemented on your platform.\n\
4343 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004344
Barry Warsaw53699e91996-12-10 23:23:01 +00004345static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004346posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004347{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004348 path_t path;
4349 int dir_fd = DEFAULT_DIR_FD;
4350 static char *keywords[] = {"path", "dir_fd", NULL};
4351 int result;
4352 PyObject *return_value = NULL;
4353
4354 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004355 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4357 path_converter, &path,
4358#ifdef HAVE_UNLINKAT
4359 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004360#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004361 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004362#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004363 ))
4364 return NULL;
4365
4366 Py_BEGIN_ALLOW_THREADS
4367#ifdef MS_WINDOWS
4368 if (path.wide)
4369 result = RemoveDirectoryW(path.wide);
4370 else
4371 result = RemoveDirectoryA(path.narrow);
4372 result = !result; /* Windows, success=1, UNIX, success=0 */
4373#else
4374#ifdef HAVE_UNLINKAT
4375 if (dir_fd != DEFAULT_DIR_FD)
4376 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4377 else
4378#endif
4379 result = rmdir(path.narrow);
4380#endif
4381 Py_END_ALLOW_THREADS
4382
4383 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004384 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004385 goto exit;
4386 }
4387
4388 return_value = Py_None;
4389 Py_INCREF(Py_None);
4390
4391exit:
4392 path_cleanup(&path);
4393 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004394}
4395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004396
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004397#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004398PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004399"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004400Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004401
Barry Warsaw53699e91996-12-10 23:23:01 +00004402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004403posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004404{
Victor Stinner8c62be82010-05-06 00:08:46 +00004405 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004406#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004407 wchar_t *command;
4408 if (!PyArg_ParseTuple(args, "u:system", &command))
4409 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004410
Victor Stinner8c62be82010-05-06 00:08:46 +00004411 Py_BEGIN_ALLOW_THREADS
4412 sts = _wsystem(command);
4413 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004414#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 PyObject *command_obj;
4416 char *command;
4417 if (!PyArg_ParseTuple(args, "O&:system",
4418 PyUnicode_FSConverter, &command_obj))
4419 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004420
Victor Stinner8c62be82010-05-06 00:08:46 +00004421 command = PyBytes_AsString(command_obj);
4422 Py_BEGIN_ALLOW_THREADS
4423 sts = system(command);
4424 Py_END_ALLOW_THREADS
4425 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004426#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004427 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004428}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004429#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004431
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004432PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004433"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004434Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004435
Barry Warsaw53699e91996-12-10 23:23:01 +00004436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004437posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004438{
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 int i;
4440 if (!PyArg_ParseTuple(args, "i:umask", &i))
4441 return NULL;
4442 i = (int)umask(i);
4443 if (i < 0)
4444 return posix_error();
4445 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004446}
4447
Brian Curtind40e6f72010-07-08 21:39:08 +00004448#ifdef MS_WINDOWS
4449
4450/* override the default DeleteFileW behavior so that directory
4451symlinks can be removed with this function, the same as with
4452Unix symlinks */
4453BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4454{
4455 WIN32_FILE_ATTRIBUTE_DATA info;
4456 WIN32_FIND_DATAW find_data;
4457 HANDLE find_data_handle;
4458 int is_directory = 0;
4459 int is_link = 0;
4460
4461 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4462 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004463
Brian Curtind40e6f72010-07-08 21:39:08 +00004464 /* Get WIN32_FIND_DATA structure for the path to determine if
4465 it is a symlink */
4466 if(is_directory &&
4467 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4468 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4469
4470 if(find_data_handle != INVALID_HANDLE_VALUE) {
4471 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4472 FindClose(find_data_handle);
4473 }
4474 }
4475 }
4476
4477 if (is_directory && is_link)
4478 return RemoveDirectoryW(lpFileName);
4479
4480 return DeleteFileW(lpFileName);
4481}
4482#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004484PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004485"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486Remove a file (same as remove()).\n\
4487\n\
4488If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4489 and path should be relative; path will then be relative to that directory.\n\
4490dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004491 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004493PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004494"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004495Remove a file (same as unlink()).\n\
4496\n\
4497If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4498 and path should be relative; path will then be relative to that directory.\n\
4499dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004500 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
Barry Warsaw53699e91996-12-10 23:23:01 +00004502static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004503posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004504{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004505 path_t path;
4506 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004507 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508 int result;
4509 PyObject *return_value = NULL;
4510
4511 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004512 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514 path_converter, &path,
4515#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004516 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004517#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004518 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004519#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004520 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521 return NULL;
4522
4523 Py_BEGIN_ALLOW_THREADS
4524#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004525 if (path.wide)
4526 result = Py_DeleteFileW(path.wide);
4527 else
4528 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 result = !result; /* Windows, success=1, UNIX, success=0 */
4530#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531#ifdef HAVE_UNLINKAT
4532 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004533 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534 else
4535#endif /* HAVE_UNLINKAT */
4536 result = unlink(path.narrow);
4537#endif
4538 Py_END_ALLOW_THREADS
4539
4540 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004541 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 goto exit;
4543 }
4544
4545 return_value = Py_None;
4546 Py_INCREF(Py_None);
4547
4548exit:
4549 path_cleanup(&path);
4550 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004551}
4552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004554PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004555"uname() -> uname_result\n\n\
4556Return an object identifying the current operating system.\n\
4557The object behaves like a named tuple with the following fields:\n\
4558 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004559
Larry Hastings605a62d2012-06-24 04:33:36 -07004560static PyStructSequence_Field uname_result_fields[] = {
4561 {"sysname", "operating system name"},
4562 {"nodename", "name of machine on network (implementation-defined)"},
4563 {"release", "operating system release"},
4564 {"version", "operating system version"},
4565 {"machine", "hardware identifier"},
4566 {NULL}
4567};
4568
4569PyDoc_STRVAR(uname_result__doc__,
4570"uname_result: Result from os.uname().\n\n\
4571This object may be accessed either as a tuple of\n\
4572 (sysname, nodename, release, version, machine),\n\
4573or via the attributes sysname, nodename, release, version, and machine.\n\
4574\n\
4575See os.uname for more information.");
4576
4577static PyStructSequence_Desc uname_result_desc = {
4578 "uname_result", /* name */
4579 uname_result__doc__, /* doc */
4580 uname_result_fields,
4581 5
4582};
4583
4584static PyTypeObject UnameResultType;
4585
4586
4587#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004588static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004589posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004590{
Victor Stinner8c62be82010-05-06 00:08:46 +00004591 struct utsname u;
4592 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004593 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004594
Victor Stinner8c62be82010-05-06 00:08:46 +00004595 Py_BEGIN_ALLOW_THREADS
4596 res = uname(&u);
4597 Py_END_ALLOW_THREADS
4598 if (res < 0)
4599 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004600
4601 value = PyStructSequence_New(&UnameResultType);
4602 if (value == NULL)
4603 return NULL;
4604
4605#define SET(i, field) \
4606 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004607 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004608 if (!o) { \
4609 Py_DECREF(value); \
4610 return NULL; \
4611 } \
4612 PyStructSequence_SET_ITEM(value, i, o); \
4613 } \
4614
4615 SET(0, u.sysname);
4616 SET(1, u.nodename);
4617 SET(2, u.release);
4618 SET(3, u.version);
4619 SET(4, u.machine);
4620
4621#undef SET
4622
4623 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004624}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004625#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004626
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004627
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628PyDoc_STRVAR(posix_utime__doc__,
4629"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4630Set the access and modified time of path.\n\
4631\n\
4632path may always be specified as a string.\n\
4633On some platforms, path may also be specified as an open file descriptor.\n\
4634 If this functionality is unavailable, using it raises an exception.\n\
4635\n\
4636If times is not None, it must be a tuple (atime, mtime);\n\
4637 atime and mtime should be expressed as float seconds since the epoch.\n\
4638If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4639 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4640 since the epoch.\n\
4641If both times and ns are None, utime uses the current time.\n\
4642Specifying tuples for both times and ns is an error.\n\
4643\n\
4644If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4645 and path should be relative; path will then be relative to that directory.\n\
4646If follow_symlinks is False, and the last element of the path is a symbolic\n\
4647 link, utime will modify the symbolic link itself instead of the file the\n\
4648 link points to.\n\
4649It is an error to use dir_fd or follow_symlinks when specifying path\n\
4650 as an open file descriptor.\n\
4651dir_fd and follow_symlinks may not be available on your platform.\n\
4652 If they are unavailable, using them will raise a NotImplementedError.");
4653
4654typedef struct {
4655 int now;
4656 time_t atime_s;
4657 long atime_ns;
4658 time_t mtime_s;
4659 long mtime_ns;
4660} utime_t;
4661
4662/*
4663 * these macros assume that "utime" is a pointer to a utime_t
4664 * they also intentionally leak the declaration of a pointer named "time"
4665 */
4666#define UTIME_TO_TIMESPEC \
4667 struct timespec ts[2]; \
4668 struct timespec *time; \
4669 if (utime->now) \
4670 time = NULL; \
4671 else { \
4672 ts[0].tv_sec = utime->atime_s; \
4673 ts[0].tv_nsec = utime->atime_ns; \
4674 ts[1].tv_sec = utime->mtime_s; \
4675 ts[1].tv_nsec = utime->mtime_ns; \
4676 time = ts; \
4677 } \
4678
4679#define UTIME_TO_TIMEVAL \
4680 struct timeval tv[2]; \
4681 struct timeval *time; \
4682 if (utime->now) \
4683 time = NULL; \
4684 else { \
4685 tv[0].tv_sec = utime->atime_s; \
4686 tv[0].tv_usec = utime->atime_ns / 1000; \
4687 tv[1].tv_sec = utime->mtime_s; \
4688 tv[1].tv_usec = utime->mtime_ns / 1000; \
4689 time = tv; \
4690 } \
4691
4692#define UTIME_TO_UTIMBUF \
4693 struct utimbuf u[2]; \
4694 struct utimbuf *time; \
4695 if (utime->now) \
4696 time = NULL; \
4697 else { \
4698 u.actime = utime->atime_s; \
4699 u.modtime = utime->mtime_s; \
4700 time = u; \
4701 }
4702
4703#define UTIME_TO_TIME_T \
4704 time_t timet[2]; \
4705 struct timet time; \
4706 if (utime->now) \
4707 time = NULL; \
4708 else { \
4709 timet[0] = utime->atime_s; \
4710 timet[1] = utime->mtime_s; \
4711 time = &timet; \
4712 } \
4713
4714
4715#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4716
4717#if UTIME_HAVE_DIR_FD
4718
4719static int
4720utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4721{
4722#ifdef HAVE_UTIMENSAT
4723 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4724 UTIME_TO_TIMESPEC;
4725 return utimensat(dir_fd, path, time, flags);
4726#elif defined(HAVE_FUTIMESAT)
4727 UTIME_TO_TIMEVAL;
4728 /*
4729 * follow_symlinks will never be false here;
4730 * we only allow !follow_symlinks and dir_fd together
4731 * if we have utimensat()
4732 */
4733 assert(follow_symlinks);
4734 return futimesat(dir_fd, path, time);
4735#endif
4736}
4737
4738#endif
4739
4740#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4741
4742#if UTIME_HAVE_FD
4743
4744static int
4745utime_fd(utime_t *utime, int fd)
4746{
4747#ifdef HAVE_FUTIMENS
4748 UTIME_TO_TIMESPEC;
4749 return futimens(fd, time);
4750#else
4751 UTIME_TO_TIMEVAL;
4752 return futimes(fd, time);
4753#endif
4754}
4755
4756#endif
4757
4758
4759#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4760 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4761
4762#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4763
4764static int
4765utime_nofollow_symlinks(utime_t *utime, char *path)
4766{
4767#ifdef HAVE_UTIMENSAT
4768 UTIME_TO_TIMESPEC;
4769 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4770#else
4771 UTIME_TO_TIMEVAL;
4772 return lutimes(path, time);
4773#endif
4774}
4775
4776#endif
4777
4778#ifndef MS_WINDOWS
4779
4780static int
4781utime_default(utime_t *utime, char *path)
4782{
4783#ifdef HAVE_UTIMENSAT
4784 UTIME_TO_TIMESPEC;
4785 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4786#elif defined(HAVE_UTIMES)
4787 UTIME_TO_TIMEVAL;
4788 return utimes(path, time);
4789#elif defined(HAVE_UTIME_H)
4790 UTIME_TO_UTIMBUF;
4791 return utime(path, time);
4792#else
4793 UTIME_TO_TIME_T;
4794 return utime(path, time);
4795#endif
4796}
4797
4798#endif
4799
Larry Hastings76ad59b2012-05-03 00:30:07 -07004800static int
4801split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4802{
4803 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004804 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004805 divmod = PyNumber_Divmod(py_long, billion);
4806 if (!divmod)
4807 goto exit;
4808 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4809 if ((*s == -1) && PyErr_Occurred())
4810 goto exit;
4811 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004812 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004813 goto exit;
4814
4815 result = 1;
4816exit:
4817 Py_XDECREF(divmod);
4818 return result;
4819}
4820
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821static PyObject *
4822posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004823{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004825 PyObject *times = NULL;
4826 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 int dir_fd = DEFAULT_DIR_FD;
4828 int follow_symlinks = 1;
4829 char *keywords[] = {"path", "times", "ns", "dir_fd",
4830 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004831
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004833
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834#ifdef MS_WINDOWS
4835 HANDLE hFile;
4836 FILETIME atime, mtime;
4837#else
4838 int result;
4839#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004840
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004842
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004844 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004845 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846#if UTIME_HAVE_FD
4847 path.allow_fd = 1;
4848#endif
4849 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4850 "O&|O$OO&p:utime", keywords,
4851 path_converter, &path,
4852 &times, &ns,
4853#if UTIME_HAVE_DIR_FD
4854 dir_fd_converter, &dir_fd,
4855#else
4856 dir_fd_unavailable, &dir_fd,
4857#endif
4858 &follow_symlinks
4859 ))
4860 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004861
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862 if (times && (times != Py_None) && ns) {
4863 PyErr_SetString(PyExc_ValueError,
4864 "utime: you may specify either 'times'"
4865 " or 'ns' but not both");
4866 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004867 }
4868
4869 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004870 time_t a_sec, m_sec;
4871 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004873 PyErr_SetString(PyExc_TypeError,
4874 "utime: 'times' must be either"
4875 " a tuple of two ints or None");
4876 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004877 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004878 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004879 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004880 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004881 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004882 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004884 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004885 utime.atime_s = a_sec;
4886 utime.atime_ns = a_nsec;
4887 utime.mtime_s = m_sec;
4888 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004889 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004891 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 PyErr_SetString(PyExc_TypeError,
4893 "utime: 'ns' must be a tuple of two ints");
4894 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004895 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004896 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004897 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004898 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004899 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 &utime.mtime_s, &utime.mtime_ns)) {
4901 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004902 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903 }
4904 else {
4905 /* times and ns are both None/unspecified. use "now". */
4906 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004907 }
4908
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4910 if (follow_symlinks_specified("utime", follow_symlinks))
4911 goto exit;
4912#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004913
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4915 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4916 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4917 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004918
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919#if !defined(HAVE_UTIMENSAT)
4920 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004921 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922 "utime: cannot use dir_fd and follow_symlinks "
4923 "together on this platform");
4924 goto exit;
4925 }
4926#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004927
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004928#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004929 Py_BEGIN_ALLOW_THREADS
4930 if (path.wide)
4931 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 NULL, OPEN_EXISTING,
4933 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004934 else
4935 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 NULL, OPEN_EXISTING,
4937 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004938 Py_END_ALLOW_THREADS
4939 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004940 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004942 }
4943
Larry Hastings9cf065c2012-06-22 16:30:09 -07004944 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004945 GetSystemTimeAsFileTime(&mtime);
4946 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4950 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 }
4952 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4953 /* Avoid putting the file name into the error here,
4954 as that may confuse the user into believing that
4955 something is wrong with the file, when it also
4956 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004957 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004960#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004962
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4964 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4965 result = utime_nofollow_symlinks(&utime, path.narrow);
4966 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004967#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968
4969#if UTIME_HAVE_DIR_FD
4970 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4971 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4972 else
4973#endif
4974
4975#if UTIME_HAVE_FD
4976 if (path.fd != -1)
4977 result = utime_fd(&utime, path.fd);
4978 else
4979#endif
4980
4981 result = utime_default(&utime, path.narrow);
4982
4983 Py_END_ALLOW_THREADS
4984
4985 if (result < 0) {
4986 /* see previous comment about not putting filename in error here */
4987 return_value = posix_error();
4988 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004990
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004991#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992
4993 Py_INCREF(Py_None);
4994 return_value = Py_None;
4995
4996exit:
4997 path_cleanup(&path);
4998#ifdef MS_WINDOWS
4999 if (hFile != INVALID_HANDLE_VALUE)
5000 CloseHandle(hFile);
5001#endif
5002 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005003}
5004
Guido van Rossum3b066191991-06-04 19:40:25 +00005005/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005007PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005008"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005009Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005010
Barry Warsaw53699e91996-12-10 23:23:01 +00005011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005012posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005013{
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 int sts;
5015 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5016 return NULL;
5017 _exit(sts);
5018 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005019}
5020
Martin v. Löwis114619e2002-10-07 06:44:21 +00005021#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5022static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005023free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005024{
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 Py_ssize_t i;
5026 for (i = 0; i < count; i++)
5027 PyMem_Free(array[i]);
5028 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005029}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005030
Antoine Pitrou69f71142009-05-24 21:25:49 +00005031static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005032int fsconvert_strdup(PyObject *o, char**out)
5033{
Victor Stinner8c62be82010-05-06 00:08:46 +00005034 PyObject *bytes;
5035 Py_ssize_t size;
5036 if (!PyUnicode_FSConverter(o, &bytes))
5037 return 0;
5038 size = PyBytes_GET_SIZE(bytes);
5039 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005040 if (!*out) {
5041 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005043 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 memcpy(*out, PyBytes_AsString(bytes), size+1);
5045 Py_DECREF(bytes);
5046 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005047}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005048#endif
5049
Ross Lagerwall7807c352011-03-17 20:20:30 +02005050#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005051static char**
5052parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5053{
Victor Stinner8c62be82010-05-06 00:08:46 +00005054 char **envlist;
5055 Py_ssize_t i, pos, envc;
5056 PyObject *keys=NULL, *vals=NULL;
5057 PyObject *key, *val, *key2, *val2;
5058 char *p, *k, *v;
5059 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 i = PyMapping_Size(env);
5062 if (i < 0)
5063 return NULL;
5064 envlist = PyMem_NEW(char *, i + 1);
5065 if (envlist == NULL) {
5066 PyErr_NoMemory();
5067 return NULL;
5068 }
5069 envc = 0;
5070 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005071 if (!keys)
5072 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005074 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 goto error;
5076 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5077 PyErr_Format(PyExc_TypeError,
5078 "env.keys() or env.values() is not a list");
5079 goto error;
5080 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005081
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 for (pos = 0; pos < i; pos++) {
5083 key = PyList_GetItem(keys, pos);
5084 val = PyList_GetItem(vals, pos);
5085 if (!key || !val)
5086 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005087
Victor Stinner8c62be82010-05-06 00:08:46 +00005088 if (PyUnicode_FSConverter(key, &key2) == 0)
5089 goto error;
5090 if (PyUnicode_FSConverter(val, &val2) == 0) {
5091 Py_DECREF(key2);
5092 goto error;
5093 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 k = PyBytes_AsString(key2);
5096 v = PyBytes_AsString(val2);
5097 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005098
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 p = PyMem_NEW(char, len);
5100 if (p == NULL) {
5101 PyErr_NoMemory();
5102 Py_DECREF(key2);
5103 Py_DECREF(val2);
5104 goto error;
5105 }
5106 PyOS_snprintf(p, len, "%s=%s", k, v);
5107 envlist[envc++] = p;
5108 Py_DECREF(key2);
5109 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 }
5111 Py_DECREF(vals);
5112 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 envlist[envc] = 0;
5115 *envc_ptr = envc;
5116 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005117
5118error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 Py_XDECREF(keys);
5120 Py_XDECREF(vals);
5121 while (--envc >= 0)
5122 PyMem_DEL(envlist[envc]);
5123 PyMem_DEL(envlist);
5124 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005125}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005126
Ross Lagerwall7807c352011-03-17 20:20:30 +02005127static char**
5128parse_arglist(PyObject* argv, Py_ssize_t *argc)
5129{
5130 int i;
5131 char **argvlist = PyMem_NEW(char *, *argc+1);
5132 if (argvlist == NULL) {
5133 PyErr_NoMemory();
5134 return NULL;
5135 }
5136 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005137 PyObject* item = PySequence_ITEM(argv, i);
5138 if (item == NULL)
5139 goto fail;
5140 if (!fsconvert_strdup(item, &argvlist[i])) {
5141 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 goto fail;
5143 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005144 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005145 }
5146 argvlist[*argc] = NULL;
5147 return argvlist;
5148fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005149 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005150 free_string_array(argvlist, *argc);
5151 return NULL;
5152}
5153#endif
5154
5155#ifdef HAVE_EXECV
5156PyDoc_STRVAR(posix_execv__doc__,
5157"execv(path, args)\n\n\
5158Execute an executable path with arguments, replacing current process.\n\
5159\n\
5160 path: path of executable file\n\
5161 args: tuple or list of strings");
5162
5163static PyObject *
5164posix_execv(PyObject *self, PyObject *args)
5165{
5166 PyObject *opath;
5167 char *path;
5168 PyObject *argv;
5169 char **argvlist;
5170 Py_ssize_t argc;
5171
5172 /* execv has two arguments: (path, argv), where
5173 argv is a list or tuple of strings. */
5174
5175 if (!PyArg_ParseTuple(args, "O&O:execv",
5176 PyUnicode_FSConverter,
5177 &opath, &argv))
5178 return NULL;
5179 path = PyBytes_AsString(opath);
5180 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5181 PyErr_SetString(PyExc_TypeError,
5182 "execv() arg 2 must be a tuple or list");
5183 Py_DECREF(opath);
5184 return NULL;
5185 }
5186 argc = PySequence_Size(argv);
5187 if (argc < 1) {
5188 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5189 Py_DECREF(opath);
5190 return NULL;
5191 }
5192
5193 argvlist = parse_arglist(argv, &argc);
5194 if (argvlist == NULL) {
5195 Py_DECREF(opath);
5196 return NULL;
5197 }
5198
5199 execv(path, argvlist);
5200
5201 /* If we get here it's definitely an error */
5202
5203 free_string_array(argvlist, argc);
5204 Py_DECREF(opath);
5205 return posix_error();
5206}
5207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005209"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005210Execute a path with arguments and environment, replacing current process.\n\
5211\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 path: path of executable file\n\
5213 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005214 env: dictionary of strings mapping to strings\n\
5215\n\
5216On some platforms, you may specify an open file descriptor for path;\n\
5217 execve will execute the program the file descriptor is open to.\n\
5218 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005219
Barry Warsaw53699e91996-12-10 23:23:01 +00005220static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005221posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005222{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005223 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005225 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005227 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005228 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005229
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 /* execve has three arguments: (path, argv, env), where
5231 argv is a list or tuple of strings and env is a dictionary
5232 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005233
Larry Hastings9cf065c2012-06-22 16:30:09 -07005234 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005235 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005236#ifdef HAVE_FEXECVE
5237 path.allow_fd = 1;
5238#endif
5239 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5240 path_converter, &path,
5241 &argv, &env
5242 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005244
Ross Lagerwall7807c352011-03-17 20:20:30 +02005245 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005247 "execve: argv must be a tuple or list");
5248 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005250 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 if (!PyMapping_Check(env)) {
5252 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005253 "execve: environment must be a mapping object");
5254 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005256
Ross Lagerwall7807c352011-03-17 20:20:30 +02005257 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005259 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005261
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 envlist = parse_envlist(env, &envc);
5263 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005264 goto fail;
5265
Larry Hastings9cf065c2012-06-22 16:30:09 -07005266#ifdef HAVE_FEXECVE
5267 if (path.fd > -1)
5268 fexecve(path.fd, argvlist, envlist);
5269 else
5270#endif
5271 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005272
5273 /* If we get here it's definitely an error */
5274
Victor Stinner292c8352012-10-30 02:17:38 +01005275 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005276
5277 while (--envc >= 0)
5278 PyMem_DEL(envlist[envc]);
5279 PyMem_DEL(envlist);
5280 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005281 if (argvlist)
5282 free_string_array(argvlist, argc);
5283 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005284 return NULL;
5285}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005286#endif /* HAVE_EXECV */
5287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005288
Guido van Rossuma1065681999-01-25 23:20:23 +00005289#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005290PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005291"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005292Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005293\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 mode: mode of process creation\n\
5295 path: path of executable file\n\
5296 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
5298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005299posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005300{
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 PyObject *opath;
5302 char *path;
5303 PyObject *argv;
5304 char **argvlist;
5305 int mode, i;
5306 Py_ssize_t argc;
5307 Py_intptr_t spawnval;
5308 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005309
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 /* spawnv has three arguments: (mode, path, argv), where
5311 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005312
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5314 PyUnicode_FSConverter,
5315 &opath, &argv))
5316 return NULL;
5317 path = PyBytes_AsString(opath);
5318 if (PyList_Check(argv)) {
5319 argc = PyList_Size(argv);
5320 getitem = PyList_GetItem;
5321 }
5322 else if (PyTuple_Check(argv)) {
5323 argc = PyTuple_Size(argv);
5324 getitem = PyTuple_GetItem;
5325 }
5326 else {
5327 PyErr_SetString(PyExc_TypeError,
5328 "spawnv() arg 2 must be a tuple or list");
5329 Py_DECREF(opath);
5330 return NULL;
5331 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005332
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 argvlist = PyMem_NEW(char *, argc+1);
5334 if (argvlist == NULL) {
5335 Py_DECREF(opath);
5336 return PyErr_NoMemory();
5337 }
5338 for (i = 0; i < argc; i++) {
5339 if (!fsconvert_strdup((*getitem)(argv, i),
5340 &argvlist[i])) {
5341 free_string_array(argvlist, i);
5342 PyErr_SetString(
5343 PyExc_TypeError,
5344 "spawnv() arg 2 must contain only strings");
5345 Py_DECREF(opath);
5346 return NULL;
5347 }
5348 }
5349 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005350
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 if (mode == _OLD_P_OVERLAY)
5352 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005353
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 Py_BEGIN_ALLOW_THREADS
5355 spawnval = _spawnv(mode, path, argvlist);
5356 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 free_string_array(argvlist, argc);
5359 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005360
Victor Stinner8c62be82010-05-06 00:08:46 +00005361 if (spawnval == -1)
5362 return posix_error();
5363 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005364 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005365}
5366
5367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005369"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005370Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005371\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 mode: mode of process creation\n\
5373 path: path of executable file\n\
5374 args: tuple or list of arguments\n\
5375 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005376
5377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005378posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005379{
Victor Stinner8c62be82010-05-06 00:08:46 +00005380 PyObject *opath;
5381 char *path;
5382 PyObject *argv, *env;
5383 char **argvlist;
5384 char **envlist;
5385 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005386 int mode;
5387 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 Py_intptr_t spawnval;
5389 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5390 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005391
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 /* spawnve has four arguments: (mode, path, argv, env), where
5393 argv is a list or tuple of strings and env is a dictionary
5394 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005395
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5397 PyUnicode_FSConverter,
5398 &opath, &argv, &env))
5399 return NULL;
5400 path = PyBytes_AsString(opath);
5401 if (PyList_Check(argv)) {
5402 argc = PyList_Size(argv);
5403 getitem = PyList_GetItem;
5404 }
5405 else if (PyTuple_Check(argv)) {
5406 argc = PyTuple_Size(argv);
5407 getitem = PyTuple_GetItem;
5408 }
5409 else {
5410 PyErr_SetString(PyExc_TypeError,
5411 "spawnve() arg 2 must be a tuple or list");
5412 goto fail_0;
5413 }
5414 if (!PyMapping_Check(env)) {
5415 PyErr_SetString(PyExc_TypeError,
5416 "spawnve() arg 3 must be a mapping object");
5417 goto fail_0;
5418 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005419
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 argvlist = PyMem_NEW(char *, argc+1);
5421 if (argvlist == NULL) {
5422 PyErr_NoMemory();
5423 goto fail_0;
5424 }
5425 for (i = 0; i < argc; i++) {
5426 if (!fsconvert_strdup((*getitem)(argv, i),
5427 &argvlist[i]))
5428 {
5429 lastarg = i;
5430 goto fail_1;
5431 }
5432 }
5433 lastarg = argc;
5434 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005435
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 envlist = parse_envlist(env, &envc);
5437 if (envlist == NULL)
5438 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005439
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 if (mode == _OLD_P_OVERLAY)
5441 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005442
Victor Stinner8c62be82010-05-06 00:08:46 +00005443 Py_BEGIN_ALLOW_THREADS
5444 spawnval = _spawnve(mode, path, argvlist, envlist);
5445 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005446
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 if (spawnval == -1)
5448 (void) posix_error();
5449 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005450 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005451
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 while (--envc >= 0)
5453 PyMem_DEL(envlist[envc]);
5454 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005455 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005457 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 Py_DECREF(opath);
5459 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005460}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005461
Guido van Rossuma1065681999-01-25 23:20:23 +00005462#endif /* HAVE_SPAWNV */
5463
5464
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005465#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005467"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005468Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5469\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005471
5472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005473posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005474{
Victor Stinner8c62be82010-05-06 00:08:46 +00005475 pid_t pid;
5476 int result = 0;
5477 _PyImport_AcquireLock();
5478 pid = fork1();
5479 if (pid == 0) {
5480 /* child: this clobbers and resets the import lock. */
5481 PyOS_AfterFork();
5482 } else {
5483 /* parent: release the import lock. */
5484 result = _PyImport_ReleaseLock();
5485 }
5486 if (pid == -1)
5487 return posix_error();
5488 if (result < 0) {
5489 /* Don't clobber the OSError if the fork failed. */
5490 PyErr_SetString(PyExc_RuntimeError,
5491 "not holding the import lock");
5492 return NULL;
5493 }
5494 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005495}
5496#endif
5497
5498
Guido van Rossumad0ee831995-03-01 10:34:45 +00005499#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005501"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005502Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005504
Barry Warsaw53699e91996-12-10 23:23:01 +00005505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005506posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005507{
Victor Stinner8c62be82010-05-06 00:08:46 +00005508 pid_t pid;
5509 int result = 0;
5510 _PyImport_AcquireLock();
5511 pid = fork();
5512 if (pid == 0) {
5513 /* child: this clobbers and resets the import lock. */
5514 PyOS_AfterFork();
5515 } else {
5516 /* parent: release the import lock. */
5517 result = _PyImport_ReleaseLock();
5518 }
5519 if (pid == -1)
5520 return posix_error();
5521 if (result < 0) {
5522 /* Don't clobber the OSError if the fork failed. */
5523 PyErr_SetString(PyExc_RuntimeError,
5524 "not holding the import lock");
5525 return NULL;
5526 }
5527 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005528}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005529#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005530
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005531#ifdef HAVE_SCHED_H
5532
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005533#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5534
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005535PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5536"sched_get_priority_max(policy)\n\n\
5537Get the maximum scheduling priority for *policy*.");
5538
5539static PyObject *
5540posix_sched_get_priority_max(PyObject *self, PyObject *args)
5541{
5542 int policy, max;
5543
5544 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5545 return NULL;
5546 max = sched_get_priority_max(policy);
5547 if (max < 0)
5548 return posix_error();
5549 return PyLong_FromLong(max);
5550}
5551
5552PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5553"sched_get_priority_min(policy)\n\n\
5554Get the minimum scheduling priority for *policy*.");
5555
5556static PyObject *
5557posix_sched_get_priority_min(PyObject *self, PyObject *args)
5558{
5559 int policy, min;
5560
5561 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5562 return NULL;
5563 min = sched_get_priority_min(policy);
5564 if (min < 0)
5565 return posix_error();
5566 return PyLong_FromLong(min);
5567}
5568
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005569#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5570
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005571#ifdef HAVE_SCHED_SETSCHEDULER
5572
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005573PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5574"sched_getscheduler(pid)\n\n\
5575Get the scheduling policy for the process with a PID of *pid*.\n\
5576Passing a PID of 0 returns the scheduling policy for the calling process.");
5577
5578static PyObject *
5579posix_sched_getscheduler(PyObject *self, PyObject *args)
5580{
5581 pid_t pid;
5582 int policy;
5583
5584 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5585 return NULL;
5586 policy = sched_getscheduler(pid);
5587 if (policy < 0)
5588 return posix_error();
5589 return PyLong_FromLong(policy);
5590}
5591
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005592#endif
5593
5594#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5595
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596static PyObject *
5597sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5598{
5599 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005600 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005601
5602 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5603 return NULL;
5604 res = PyStructSequence_New(type);
5605 if (!res)
5606 return NULL;
5607 Py_INCREF(priority);
5608 PyStructSequence_SET_ITEM(res, 0, priority);
5609 return res;
5610}
5611
5612PyDoc_STRVAR(sched_param__doc__,
5613"sched_param(sched_priority): A scheduling parameter.\n\n\
5614Current has only one field: sched_priority");
5615
5616static PyStructSequence_Field sched_param_fields[] = {
5617 {"sched_priority", "the scheduling priority"},
5618 {0}
5619};
5620
5621static PyStructSequence_Desc sched_param_desc = {
5622 "sched_param", /* name */
5623 sched_param__doc__, /* doc */
5624 sched_param_fields,
5625 1
5626};
5627
5628static int
5629convert_sched_param(PyObject *param, struct sched_param *res)
5630{
5631 long priority;
5632
5633 if (Py_TYPE(param) != &SchedParamType) {
5634 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5635 return 0;
5636 }
5637 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5638 if (priority == -1 && PyErr_Occurred())
5639 return 0;
5640 if (priority > INT_MAX || priority < INT_MIN) {
5641 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5642 return 0;
5643 }
5644 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5645 return 1;
5646}
5647
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005648#endif
5649
5650#ifdef HAVE_SCHED_SETSCHEDULER
5651
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005652PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5653"sched_setscheduler(pid, policy, param)\n\n\
5654Set the scheduling policy, *policy*, for *pid*.\n\
5655If *pid* is 0, the calling process is changed.\n\
5656*param* is an instance of sched_param.");
5657
5658static PyObject *
5659posix_sched_setscheduler(PyObject *self, PyObject *args)
5660{
5661 pid_t pid;
5662 int policy;
5663 struct sched_param param;
5664
5665 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5666 &pid, &policy, &convert_sched_param, &param))
5667 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005668
5669 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005670 ** sched_setscheduler() returns 0 in Linux, but the previous
5671 ** scheduling policy under Solaris/Illumos, and others.
5672 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005673 */
5674 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005675 return posix_error();
5676 Py_RETURN_NONE;
5677}
5678
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005679#endif
5680
5681#ifdef HAVE_SCHED_SETPARAM
5682
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005683PyDoc_STRVAR(posix_sched_getparam__doc__,
5684"sched_getparam(pid) -> sched_param\n\n\
5685Returns scheduling parameters for the process with *pid* as an instance of the\n\
5686sched_param class. A PID of 0 means the calling process.");
5687
5688static PyObject *
5689posix_sched_getparam(PyObject *self, PyObject *args)
5690{
5691 pid_t pid;
5692 struct sched_param param;
5693 PyObject *res, *priority;
5694
5695 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5696 return NULL;
5697 if (sched_getparam(pid, &param))
5698 return posix_error();
5699 res = PyStructSequence_New(&SchedParamType);
5700 if (!res)
5701 return NULL;
5702 priority = PyLong_FromLong(param.sched_priority);
5703 if (!priority) {
5704 Py_DECREF(res);
5705 return NULL;
5706 }
5707 PyStructSequence_SET_ITEM(res, 0, priority);
5708 return res;
5709}
5710
5711PyDoc_STRVAR(posix_sched_setparam__doc__,
5712"sched_setparam(pid, param)\n\n\
5713Set scheduling parameters for a process with PID *pid*.\n\
5714A PID of 0 means the calling process.");
5715
5716static PyObject *
5717posix_sched_setparam(PyObject *self, PyObject *args)
5718{
5719 pid_t pid;
5720 struct sched_param param;
5721
5722 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5723 &pid, &convert_sched_param, &param))
5724 return NULL;
5725 if (sched_setparam(pid, &param))
5726 return posix_error();
5727 Py_RETURN_NONE;
5728}
5729
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005730#endif
5731
5732#ifdef HAVE_SCHED_RR_GET_INTERVAL
5733
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005734PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5735"sched_rr_get_interval(pid) -> float\n\n\
5736Return the round-robin quantum for the process with PID *pid* in seconds.");
5737
5738static PyObject *
5739posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5740{
5741 pid_t pid;
5742 struct timespec interval;
5743
5744 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5745 return NULL;
5746 if (sched_rr_get_interval(pid, &interval))
5747 return posix_error();
5748 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5749}
5750
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005751#endif
5752
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005753PyDoc_STRVAR(posix_sched_yield__doc__,
5754"sched_yield()\n\n\
5755Voluntarily relinquish the CPU.");
5756
5757static PyObject *
5758posix_sched_yield(PyObject *self, PyObject *noargs)
5759{
5760 if (sched_yield())
5761 return posix_error();
5762 Py_RETURN_NONE;
5763}
5764
Benjamin Peterson2740af82011-08-02 17:41:34 -05005765#ifdef HAVE_SCHED_SETAFFINITY
5766
Antoine Pitrou84869872012-08-04 16:16:35 +02005767/* The minimum number of CPUs allocated in a cpu_set_t */
5768static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005769
5770PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5771"sched_setaffinity(pid, cpu_set)\n\n\
5772Set the affinity of the process with PID *pid* to *cpu_set*.");
5773
5774static PyObject *
5775posix_sched_setaffinity(PyObject *self, PyObject *args)
5776{
5777 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005778 int ncpus;
5779 size_t setsize;
5780 cpu_set_t *mask = NULL;
5781 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005782
Antoine Pitrou84869872012-08-04 16:16:35 +02005783 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5784 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005785 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005786
5787 iterator = PyObject_GetIter(iterable);
5788 if (iterator == NULL)
5789 return NULL;
5790
5791 ncpus = NCPUS_START;
5792 setsize = CPU_ALLOC_SIZE(ncpus);
5793 mask = CPU_ALLOC(ncpus);
5794 if (mask == NULL) {
5795 PyErr_NoMemory();
5796 goto error;
5797 }
5798 CPU_ZERO_S(setsize, mask);
5799
5800 while ((item = PyIter_Next(iterator))) {
5801 long cpu;
5802 if (!PyLong_Check(item)) {
5803 PyErr_Format(PyExc_TypeError,
5804 "expected an iterator of ints, "
5805 "but iterator yielded %R",
5806 Py_TYPE(item));
5807 Py_DECREF(item);
5808 goto error;
5809 }
5810 cpu = PyLong_AsLong(item);
5811 Py_DECREF(item);
5812 if (cpu < 0) {
5813 if (!PyErr_Occurred())
5814 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5815 goto error;
5816 }
5817 if (cpu > INT_MAX - 1) {
5818 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5819 goto error;
5820 }
5821 if (cpu >= ncpus) {
5822 /* Grow CPU mask to fit the CPU number */
5823 int newncpus = ncpus;
5824 cpu_set_t *newmask;
5825 size_t newsetsize;
5826 while (newncpus <= cpu) {
5827 if (newncpus > INT_MAX / 2)
5828 newncpus = cpu + 1;
5829 else
5830 newncpus = newncpus * 2;
5831 }
5832 newmask = CPU_ALLOC(newncpus);
5833 if (newmask == NULL) {
5834 PyErr_NoMemory();
5835 goto error;
5836 }
5837 newsetsize = CPU_ALLOC_SIZE(newncpus);
5838 CPU_ZERO_S(newsetsize, newmask);
5839 memcpy(newmask, mask, setsize);
5840 CPU_FREE(mask);
5841 setsize = newsetsize;
5842 mask = newmask;
5843 ncpus = newncpus;
5844 }
5845 CPU_SET_S(cpu, setsize, mask);
5846 }
5847 Py_CLEAR(iterator);
5848
5849 if (sched_setaffinity(pid, setsize, mask)) {
5850 posix_error();
5851 goto error;
5852 }
5853 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005854 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005855
5856error:
5857 if (mask)
5858 CPU_FREE(mask);
5859 Py_XDECREF(iterator);
5860 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005861}
5862
5863PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5864"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5865Return the affinity of the process with PID *pid*.\n\
5866The returned cpu_set will be of size *ncpus*.");
5867
5868static PyObject *
5869posix_sched_getaffinity(PyObject *self, PyObject *args)
5870{
5871 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005872 int cpu, ncpus, count;
5873 size_t setsize;
5874 cpu_set_t *mask = NULL;
5875 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005876
Antoine Pitrou84869872012-08-04 16:16:35 +02005877 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5878 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005880
5881 ncpus = NCPUS_START;
5882 while (1) {
5883 setsize = CPU_ALLOC_SIZE(ncpus);
5884 mask = CPU_ALLOC(ncpus);
5885 if (mask == NULL)
5886 return PyErr_NoMemory();
5887 if (sched_getaffinity(pid, setsize, mask) == 0)
5888 break;
5889 CPU_FREE(mask);
5890 if (errno != EINVAL)
5891 return posix_error();
5892 if (ncpus > INT_MAX / 2) {
5893 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5894 "a large enough CPU set");
5895 return NULL;
5896 }
5897 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005898 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005899
5900 res = PySet_New(NULL);
5901 if (res == NULL)
5902 goto error;
5903 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5904 if (CPU_ISSET_S(cpu, setsize, mask)) {
5905 PyObject *cpu_num = PyLong_FromLong(cpu);
5906 --count;
5907 if (cpu_num == NULL)
5908 goto error;
5909 if (PySet_Add(res, cpu_num)) {
5910 Py_DECREF(cpu_num);
5911 goto error;
5912 }
5913 Py_DECREF(cpu_num);
5914 }
5915 }
5916 CPU_FREE(mask);
5917 return res;
5918
5919error:
5920 if (mask)
5921 CPU_FREE(mask);
5922 Py_XDECREF(res);
5923 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005924}
5925
Benjamin Peterson2740af82011-08-02 17:41:34 -05005926#endif /* HAVE_SCHED_SETAFFINITY */
5927
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005928#endif /* HAVE_SCHED_H */
5929
Neal Norwitzb59798b2003-03-21 01:43:31 +00005930/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005931/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5932#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005933#define DEV_PTY_FILE "/dev/ptc"
5934#define HAVE_DEV_PTMX
5935#else
5936#define DEV_PTY_FILE "/dev/ptmx"
5937#endif
5938
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005939#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005940#ifdef HAVE_PTY_H
5941#include <pty.h>
5942#else
5943#ifdef HAVE_LIBUTIL_H
5944#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005945#else
5946#ifdef HAVE_UTIL_H
5947#include <util.h>
5948#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005949#endif /* HAVE_LIBUTIL_H */
5950#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005951#ifdef HAVE_STROPTS_H
5952#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005953#endif
5954#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005955
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005956#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005958"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005959Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005960
5961static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005962posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005963{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005965#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005967#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005968#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005970#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005972#endif
5973#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005974
Thomas Wouters70c21a12000-07-14 14:28:33 +00005975#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
5978
5979 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5980 goto error;
5981 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5982 goto error;
5983
Neal Norwitzb59798b2003-03-21 01:43:31 +00005984#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5986 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005987 goto posix_error;
5988 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5989 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005990
Victor Stinnerdaf45552013-08-28 00:53:59 +02005991 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005993 goto posix_error;
5994
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005995#else
Victor Stinner000de532013-11-25 23:19:58 +01005996 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005998 goto posix_error;
5999
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 /* change permission of slave */
6003 if (grantpt(master_fd) < 0) {
6004 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006005 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006007
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 /* unlock slave */
6009 if (unlockpt(master_fd) < 0) {
6010 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006011 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006013
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 slave_name = ptsname(master_fd); /* get name of slave */
6017 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006018 goto posix_error;
6019
6020 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006022 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006023
6024 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6025 goto posix_error;
6026
Neal Norwitzb59798b2003-03-21 01:43:31 +00006027#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6029 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006030#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006032#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006034#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006035
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006037
Victor Stinnerdaf45552013-08-28 00:53:59 +02006038posix_error:
6039 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006040#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006041error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006042#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006043 if (master_fd != -1)
6044 close(master_fd);
6045 if (slave_fd != -1)
6046 close(slave_fd);
6047 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006048}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006049#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006050
6051#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006053"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006054Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6055Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006057
6058static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006059posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006060{
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 int master_fd = -1, result = 0;
6062 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006063
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 _PyImport_AcquireLock();
6065 pid = forkpty(&master_fd, NULL, NULL, NULL);
6066 if (pid == 0) {
6067 /* child: this clobbers and resets the import lock. */
6068 PyOS_AfterFork();
6069 } else {
6070 /* parent: release the import lock. */
6071 result = _PyImport_ReleaseLock();
6072 }
6073 if (pid == -1)
6074 return posix_error();
6075 if (result < 0) {
6076 /* Don't clobber the OSError if the fork failed. */
6077 PyErr_SetString(PyExc_RuntimeError,
6078 "not holding the import lock");
6079 return NULL;
6080 }
6081 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006082}
6083#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006084
Ross Lagerwall7807c352011-03-17 20:20:30 +02006085
Guido van Rossumad0ee831995-03-01 10:34:45 +00006086#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006088"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006090
Barry Warsaw53699e91996-12-10 23:23:01 +00006091static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006092posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006093{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006094 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006096#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Guido van Rossumad0ee831995-03-01 10:34:45 +00006099#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006101"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Barry Warsaw53699e91996-12-10 23:23:01 +00006104static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006105posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006106{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006107 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006108}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006109#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Guido van Rossumad0ee831995-03-01 10:34:45 +00006112#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006114"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Barry Warsaw53699e91996-12-10 23:23:01 +00006117static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006118posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006119{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006120 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006121}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006122#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006126"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006128
Barry Warsaw53699e91996-12-10 23:23:01 +00006129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006130posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006131{
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006133}
6134
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006135#ifdef HAVE_GETGROUPLIST
6136PyDoc_STRVAR(posix_getgrouplist__doc__,
6137"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6138Returns a list of groups to which a user belongs.\n\n\
6139 user: username to lookup\n\
6140 group: base group id of the user");
6141
6142static PyObject *
6143posix_getgrouplist(PyObject *self, PyObject *args)
6144{
6145#ifdef NGROUPS_MAX
6146#define MAX_GROUPS NGROUPS_MAX
6147#else
6148 /* defined to be 16 on Solaris7, so this should be a small number */
6149#define MAX_GROUPS 64
6150#endif
6151
6152 const char *user;
6153 int i, ngroups;
6154 PyObject *list;
6155#ifdef __APPLE__
6156 int *groups, basegid;
6157#else
6158 gid_t *groups, basegid;
6159#endif
6160 ngroups = MAX_GROUPS;
6161
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006162#ifdef __APPLE__
6163 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006164 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006165#else
6166 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6167 _Py_Gid_Converter, &basegid))
6168 return NULL;
6169#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006170
6171#ifdef __APPLE__
6172 groups = PyMem_Malloc(ngroups * sizeof(int));
6173#else
6174 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6175#endif
6176 if (groups == NULL)
6177 return PyErr_NoMemory();
6178
6179 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6180 PyMem_Del(groups);
6181 return posix_error();
6182 }
6183
6184 list = PyList_New(ngroups);
6185 if (list == NULL) {
6186 PyMem_Del(groups);
6187 return NULL;
6188 }
6189
6190 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006191#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006192 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006193#else
6194 PyObject *o = _PyLong_FromGid(groups[i]);
6195#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006196 if (o == NULL) {
6197 Py_DECREF(list);
6198 PyMem_Del(groups);
6199 return NULL;
6200 }
6201 PyList_SET_ITEM(list, i, o);
6202 }
6203
6204 PyMem_Del(groups);
6205
6206 return list;
6207}
6208#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006209
Fred Drakec9680921999-12-13 16:37:25 +00006210#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006212"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006214
6215static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006216posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006217{
6218 PyObject *result = NULL;
6219
Fred Drakec9680921999-12-13 16:37:25 +00006220#ifdef NGROUPS_MAX
6221#define MAX_GROUPS NGROUPS_MAX
6222#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006224#define MAX_GROUPS 64
6225#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006227
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006228 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006229 * This is a helper variable to store the intermediate result when
6230 * that happens.
6231 *
6232 * To keep the code readable the OSX behaviour is unconditional,
6233 * according to the POSIX spec this should be safe on all unix-y
6234 * systems.
6235 */
6236 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006238
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006239#ifdef __APPLE__
6240 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6241 * there are more groups than can fit in grouplist. Therefore, on OS X
6242 * always first call getgroups with length 0 to get the actual number
6243 * of groups.
6244 */
6245 n = getgroups(0, NULL);
6246 if (n < 0) {
6247 return posix_error();
6248 } else if (n <= MAX_GROUPS) {
6249 /* groups will fit in existing array */
6250 alt_grouplist = grouplist;
6251 } else {
6252 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6253 if (alt_grouplist == NULL) {
6254 errno = EINVAL;
6255 return posix_error();
6256 }
6257 }
6258
6259 n = getgroups(n, alt_grouplist);
6260 if (n == -1) {
6261 if (alt_grouplist != grouplist) {
6262 PyMem_Free(alt_grouplist);
6263 }
6264 return posix_error();
6265 }
6266#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006268 if (n < 0) {
6269 if (errno == EINVAL) {
6270 n = getgroups(0, NULL);
6271 if (n == -1) {
6272 return posix_error();
6273 }
6274 if (n == 0) {
6275 /* Avoid malloc(0) */
6276 alt_grouplist = grouplist;
6277 } else {
6278 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6279 if (alt_grouplist == NULL) {
6280 errno = EINVAL;
6281 return posix_error();
6282 }
6283 n = getgroups(n, alt_grouplist);
6284 if (n == -1) {
6285 PyMem_Free(alt_grouplist);
6286 return posix_error();
6287 }
6288 }
6289 } else {
6290 return posix_error();
6291 }
6292 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006293#endif
6294
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006295 result = PyList_New(n);
6296 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 int i;
6298 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006299 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006301 Py_DECREF(result);
6302 result = NULL;
6303 break;
Fred Drakec9680921999-12-13 16:37:25 +00006304 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006306 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006307 }
6308
6309 if (alt_grouplist != grouplist) {
6310 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006312
Fred Drakec9680921999-12-13 16:37:25 +00006313 return result;
6314}
6315#endif
6316
Antoine Pitroub7572f02009-12-02 20:46:48 +00006317#ifdef HAVE_INITGROUPS
6318PyDoc_STRVAR(posix_initgroups__doc__,
6319"initgroups(username, gid) -> None\n\n\
6320Call the system initgroups() to initialize the group access list with all of\n\
6321the groups of which the specified username is a member, plus the specified\n\
6322group id.");
6323
6324static PyObject *
6325posix_initgroups(PyObject *self, PyObject *args)
6326{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006327 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006329 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006330#ifdef __APPLE__
6331 int gid;
6332#else
6333 gid_t gid;
6334#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006335
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006336#ifdef __APPLE__
6337 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6338 PyUnicode_FSConverter, &oname,
6339 &gid))
6340#else
6341 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6342 PyUnicode_FSConverter, &oname,
6343 _Py_Gid_Converter, &gid))
6344#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006346 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006347
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006348 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006349 Py_DECREF(oname);
6350 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006352
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 Py_INCREF(Py_None);
6354 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006355}
6356#endif
6357
Martin v. Löwis606edc12002-06-13 21:09:11 +00006358#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006359PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006360"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006361Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006362
6363static PyObject *
6364posix_getpgid(PyObject *self, PyObject *args)
6365{
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 pid_t pid, pgid;
6367 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6368 return NULL;
6369 pgid = getpgid(pid);
6370 if (pgid < 0)
6371 return posix_error();
6372 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006373}
6374#endif /* HAVE_GETPGID */
6375
6376
Guido van Rossumb6775db1994-08-01 11:34:53 +00006377#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006378PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006379"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006380Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006381
Barry Warsaw53699e91996-12-10 23:23:01 +00006382static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006383posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006384{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006385#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006387#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006389#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006390}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006391#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006393
Guido van Rossumb6775db1994-08-01 11:34:53 +00006394#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006395PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006396"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006397Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006398
Barry Warsaw53699e91996-12-10 23:23:01 +00006399static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006400posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006401{
Guido van Rossum64933891994-10-20 21:56:42 +00006402#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006404#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006406#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 return posix_error();
6408 Py_INCREF(Py_None);
6409 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006410}
6411
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#endif /* HAVE_SETPGRP */
6413
Guido van Rossumad0ee831995-03-01 10:34:45 +00006414#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006415
6416#ifdef MS_WINDOWS
6417#include <tlhelp32.h>
6418
6419static PyObject*
6420win32_getppid()
6421{
6422 HANDLE snapshot;
6423 pid_t mypid;
6424 PyObject* result = NULL;
6425 BOOL have_record;
6426 PROCESSENTRY32 pe;
6427
6428 mypid = getpid(); /* This function never fails */
6429
6430 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6431 if (snapshot == INVALID_HANDLE_VALUE)
6432 return PyErr_SetFromWindowsErr(GetLastError());
6433
6434 pe.dwSize = sizeof(pe);
6435 have_record = Process32First(snapshot, &pe);
6436 while (have_record) {
6437 if (mypid == (pid_t)pe.th32ProcessID) {
6438 /* We could cache the ulong value in a static variable. */
6439 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6440 break;
6441 }
6442
6443 have_record = Process32Next(snapshot, &pe);
6444 }
6445
6446 /* If our loop exits and our pid was not found (result will be NULL)
6447 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6448 * error anyway, so let's raise it. */
6449 if (!result)
6450 result = PyErr_SetFromWindowsErr(GetLastError());
6451
6452 CloseHandle(snapshot);
6453
6454 return result;
6455}
6456#endif /*MS_WINDOWS*/
6457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006458PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006459"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006460Return the parent's process id. If the parent process has already exited,\n\
6461Windows machines will still return its id; others systems will return the id\n\
6462of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006463
Barry Warsaw53699e91996-12-10 23:23:01 +00006464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006465posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006466{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006467#ifdef MS_WINDOWS
6468 return win32_getppid();
6469#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006471#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006472}
6473#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006475
Fred Drake12c6e2d1999-12-14 21:25:03 +00006476#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006477PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006478"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006479Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006480
6481static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006482posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483{
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006485#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006486 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006487 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006488
6489 if (GetUserNameW(user_name, &num_chars)) {
6490 /* num_chars is the number of unicode chars plus null terminator */
6491 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006492 }
6493 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494 result = PyErr_SetFromWindowsErr(GetLastError());
6495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 char *name;
6497 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006498
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 errno = 0;
6500 name = getlogin();
6501 if (name == NULL) {
6502 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006503 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006505 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 }
6507 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006508 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006510#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006511 return result;
6512}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006513#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514
Guido van Rossumad0ee831995-03-01 10:34:45 +00006515#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006517"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006518Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006519
Barry Warsaw53699e91996-12-10 23:23:01 +00006520static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006521posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006522{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006523 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006524}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006525#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Guido van Rossumad0ee831995-03-01 10:34:45 +00006528#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006529PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006530"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006532
Barry Warsaw53699e91996-12-10 23:23:01 +00006533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006534posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006535{
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 pid_t pid;
6537 int sig;
6538 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6539 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 if (kill(pid, sig) == -1)
6541 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 Py_INCREF(Py_None);
6543 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006544}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006545#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006546
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006547#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006549"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006551
6552static PyObject *
6553posix_killpg(PyObject *self, PyObject *args)
6554{
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 int sig;
6556 pid_t pgid;
6557 /* XXX some man pages make the `pgid` parameter an int, others
6558 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6559 take the same type. Moreover, pid_t is always at least as wide as
6560 int (else compilation of this module fails), which is safe. */
6561 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6562 return NULL;
6563 if (killpg(pgid, sig) == -1)
6564 return posix_error();
6565 Py_INCREF(Py_None);
6566 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006567}
6568#endif
6569
Brian Curtineb24d742010-04-12 17:16:38 +00006570#ifdef MS_WINDOWS
6571PyDoc_STRVAR(win32_kill__doc__,
6572"kill(pid, sig)\n\n\
6573Kill a process with a signal.");
6574
6575static PyObject *
6576win32_kill(PyObject *self, PyObject *args)
6577{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006578 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006579 pid_t pid;
6580 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006582
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006583 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006585
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 /* Console processes which share a common console can be sent CTRL+C or
6587 CTRL+BREAK events, provided they handle said events. */
6588 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006589 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 err = GetLastError();
6591 PyErr_SetFromWindowsErr(err);
6592 }
6593 else
6594 Py_RETURN_NONE;
6595 }
Brian Curtineb24d742010-04-12 17:16:38 +00006596
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6598 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006599 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 if (handle == NULL) {
6601 err = GetLastError();
6602 return PyErr_SetFromWindowsErr(err);
6603 }
Brian Curtineb24d742010-04-12 17:16:38 +00006604
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 if (TerminateProcess(handle, sig) == 0) {
6606 err = GetLastError();
6607 result = PyErr_SetFromWindowsErr(err);
6608 } else {
6609 Py_INCREF(Py_None);
6610 result = Py_None;
6611 }
Brian Curtineb24d742010-04-12 17:16:38 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 CloseHandle(handle);
6614 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006615}
6616#endif /* MS_WINDOWS */
6617
Guido van Rossumc0125471996-06-28 18:55:32 +00006618#ifdef HAVE_PLOCK
6619
6620#ifdef HAVE_SYS_LOCK_H
6621#include <sys/lock.h>
6622#endif
6623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006625"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006626Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006627
Barry Warsaw53699e91996-12-10 23:23:01 +00006628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006629posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006630{
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 int op;
6632 if (!PyArg_ParseTuple(args, "i:plock", &op))
6633 return NULL;
6634 if (plock(op) == -1)
6635 return posix_error();
6636 Py_INCREF(Py_None);
6637 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006638}
6639#endif
6640
Guido van Rossumb6775db1994-08-01 11:34:53 +00006641#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006642PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006643"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644Set the current process's user id.");
6645
Barry Warsaw53699e91996-12-10 23:23:01 +00006646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006647posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006648{
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006650 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 if (setuid(uid) < 0)
6653 return posix_error();
6654 Py_INCREF(Py_None);
6655 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006656}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006657#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006659
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006660#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006662"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663Set the current process's effective user id.");
6664
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006665static PyObject *
6666posix_seteuid (PyObject *self, PyObject *args)
6667{
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006669 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 if (seteuid(euid) < 0) {
6672 return posix_error();
6673 } else {
6674 Py_INCREF(Py_None);
6675 return Py_None;
6676 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006677}
6678#endif /* HAVE_SETEUID */
6679
6680#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006681PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006682"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683Set the current process's effective group id.");
6684
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006685static PyObject *
6686posix_setegid (PyObject *self, PyObject *args)
6687{
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006689 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 if (setegid(egid) < 0) {
6692 return posix_error();
6693 } else {
6694 Py_INCREF(Py_None);
6695 return Py_None;
6696 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006697}
6698#endif /* HAVE_SETEGID */
6699
6700#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006702"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006703Set the current process's real and effective user ids.");
6704
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006705static PyObject *
6706posix_setreuid (PyObject *self, PyObject *args)
6707{
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006709 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6710 _Py_Uid_Converter, &ruid,
6711 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 if (setreuid(ruid, euid) < 0) {
6714 return posix_error();
6715 } else {
6716 Py_INCREF(Py_None);
6717 return Py_None;
6718 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006719}
6720#endif /* HAVE_SETREUID */
6721
6722#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006724"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725Set the current process's real and effective group ids.");
6726
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006727static PyObject *
6728posix_setregid (PyObject *self, PyObject *args)
6729{
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006731 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6732 _Py_Gid_Converter, &rgid,
6733 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 if (setregid(rgid, egid) < 0) {
6736 return posix_error();
6737 } else {
6738 Py_INCREF(Py_None);
6739 return Py_None;
6740 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006741}
6742#endif /* HAVE_SETREGID */
6743
Guido van Rossumb6775db1994-08-01 11:34:53 +00006744#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006745PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006746"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006748
Barry Warsaw53699e91996-12-10 23:23:01 +00006749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006750posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006751{
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006753 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 if (setgid(gid) < 0)
6756 return posix_error();
6757 Py_INCREF(Py_None);
6758 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006759}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006760#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006761
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006762#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006763PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006764"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006765Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006766
6767static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006768posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006769{
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 int i, len;
6771 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006772
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 if (!PySequence_Check(groups)) {
6774 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6775 return NULL;
6776 }
6777 len = PySequence_Size(groups);
6778 if (len > MAX_GROUPS) {
6779 PyErr_SetString(PyExc_ValueError, "too many groups");
6780 return NULL;
6781 }
6782 for(i = 0; i < len; i++) {
6783 PyObject *elem;
6784 elem = PySequence_GetItem(groups, i);
6785 if (!elem)
6786 return NULL;
6787 if (!PyLong_Check(elem)) {
6788 PyErr_SetString(PyExc_TypeError,
6789 "groups must be integers");
6790 Py_DECREF(elem);
6791 return NULL;
6792 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006793 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 Py_DECREF(elem);
6795 return NULL;
6796 }
6797 }
6798 Py_DECREF(elem);
6799 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006800
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (setgroups(len, grouplist) < 0)
6802 return posix_error();
6803 Py_INCREF(Py_None);
6804 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006805}
6806#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006807
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6809static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006810wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811{
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 PyObject *result;
6813 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006814 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 if (pid == -1)
6817 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 if (struct_rusage == NULL) {
6820 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6821 if (m == NULL)
6822 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006823 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 Py_DECREF(m);
6825 if (struct_rusage == NULL)
6826 return NULL;
6827 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6830 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6831 if (!result)
6832 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833
6834#ifndef doubletime
6835#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6836#endif
6837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006839 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006841 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6844 SET_INT(result, 2, ru->ru_maxrss);
6845 SET_INT(result, 3, ru->ru_ixrss);
6846 SET_INT(result, 4, ru->ru_idrss);
6847 SET_INT(result, 5, ru->ru_isrss);
6848 SET_INT(result, 6, ru->ru_minflt);
6849 SET_INT(result, 7, ru->ru_majflt);
6850 SET_INT(result, 8, ru->ru_nswap);
6851 SET_INT(result, 9, ru->ru_inblock);
6852 SET_INT(result, 10, ru->ru_oublock);
6853 SET_INT(result, 11, ru->ru_msgsnd);
6854 SET_INT(result, 12, ru->ru_msgrcv);
6855 SET_INT(result, 13, ru->ru_nsignals);
6856 SET_INT(result, 14, ru->ru_nvcsw);
6857 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858#undef SET_INT
6859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 if (PyErr_Occurred()) {
6861 Py_DECREF(result);
6862 return NULL;
6863 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866}
6867#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6868
6869#ifdef HAVE_WAIT3
6870PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006871"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872Wait for completion of a child process.");
6873
6874static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006875posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876{
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 pid_t pid;
6878 int options;
6879 struct rusage ru;
6880 WAIT_TYPE status;
6881 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
Victor Stinner4195b5c2012-02-08 23:03:19 +01006883 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006885
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 Py_BEGIN_ALLOW_THREADS
6887 pid = wait3(&status, options, &ru);
6888 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006889
Victor Stinner4195b5c2012-02-08 23:03:19 +01006890 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891}
6892#endif /* HAVE_WAIT3 */
6893
6894#ifdef HAVE_WAIT4
6895PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006896"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897Wait for completion of a given child process.");
6898
6899static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006900posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006901{
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 pid_t pid;
6903 int options;
6904 struct rusage ru;
6905 WAIT_TYPE status;
6906 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907
Victor Stinner4195b5c2012-02-08 23:03:19 +01006908 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 Py_BEGIN_ALLOW_THREADS
6912 pid = wait4(pid, &status, options, &ru);
6913 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914
Victor Stinner4195b5c2012-02-08 23:03:19 +01006915 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916}
6917#endif /* HAVE_WAIT4 */
6918
Ross Lagerwall7807c352011-03-17 20:20:30 +02006919#if defined(HAVE_WAITID) && !defined(__APPLE__)
6920PyDoc_STRVAR(posix_waitid__doc__,
6921"waitid(idtype, id, options) -> waitid_result\n\n\
6922Wait for the completion of one or more child processes.\n\n\
6923idtype can be P_PID, P_PGID or P_ALL.\n\
6924id specifies the pid to wait on.\n\
6925options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6926or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6927Returns either waitid_result or None if WNOHANG is specified and there are\n\
6928no children in a waitable state.");
6929
6930static PyObject *
6931posix_waitid(PyObject *self, PyObject *args)
6932{
6933 PyObject *result;
6934 idtype_t idtype;
6935 id_t id;
6936 int options, res;
6937 siginfo_t si;
6938 si.si_pid = 0;
6939 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6940 return NULL;
6941 Py_BEGIN_ALLOW_THREADS
6942 res = waitid(idtype, id, &si, options);
6943 Py_END_ALLOW_THREADS
6944 if (res == -1)
6945 return posix_error();
6946
6947 if (si.si_pid == 0)
6948 Py_RETURN_NONE;
6949
6950 result = PyStructSequence_New(&WaitidResultType);
6951 if (!result)
6952 return NULL;
6953
6954 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006955 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006956 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6957 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6958 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6959 if (PyErr_Occurred()) {
6960 Py_DECREF(result);
6961 return NULL;
6962 }
6963
6964 return result;
6965}
6966#endif
6967
Guido van Rossumb6775db1994-08-01 11:34:53 +00006968#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006969PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006970"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006971Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006972
Barry Warsaw53699e91996-12-10 23:23:01 +00006973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006974posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006975{
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 pid_t pid;
6977 int options;
6978 WAIT_TYPE status;
6979 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006980
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6982 return NULL;
6983 Py_BEGIN_ALLOW_THREADS
6984 pid = waitpid(pid, &status, options);
6985 Py_END_ALLOW_THREADS
6986 if (pid == -1)
6987 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006988
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006990}
6991
Tim Petersab034fa2002-02-01 11:27:43 +00006992#elif defined(HAVE_CWAIT)
6993
6994/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006995PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006996"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006997"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006998
6999static PyObject *
7000posix_waitpid(PyObject *self, PyObject *args)
7001{
Victor Stinner8c62be82010-05-06 00:08:46 +00007002 Py_intptr_t pid;
7003 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007004
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007005 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 return NULL;
7007 Py_BEGIN_ALLOW_THREADS
7008 pid = _cwait(&status, pid, options);
7009 Py_END_ALLOW_THREADS
7010 if (pid == -1)
7011 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007012
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007014 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007015}
7016#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007017
Guido van Rossumad0ee831995-03-01 10:34:45 +00007018#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007019PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007020"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007022
Barry Warsaw53699e91996-12-10 23:23:01 +00007023static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007024posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007025{
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 pid_t pid;
7027 WAIT_TYPE status;
7028 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007029
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 Py_BEGIN_ALLOW_THREADS
7031 pid = wait(&status);
7032 Py_END_ALLOW_THREADS
7033 if (pid == -1)
7034 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007035
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007037}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007038#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007040
Larry Hastings9cf065c2012-06-22 16:30:09 -07007041#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7042PyDoc_STRVAR(readlink__doc__,
7043"readlink(path, *, dir_fd=None) -> path\n\n\
7044Return a string representing the path to which the symbolic link points.\n\
7045\n\
7046If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7047 and path should be relative; path will then be relative to that directory.\n\
7048dir_fd may not be implemented on your platform.\n\
7049 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007050#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007051
Guido van Rossumb6775db1994-08-01 11:34:53 +00007052#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007053
Barry Warsaw53699e91996-12-10 23:23:01 +00007054static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007055posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007056{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007057 path_t path;
7058 int dir_fd = DEFAULT_DIR_FD;
7059 char buffer[MAXPATHLEN];
7060 ssize_t length;
7061 PyObject *return_value = NULL;
7062 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007063
Larry Hastings9cf065c2012-06-22 16:30:09 -07007064 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007065 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007066 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7067 path_converter, &path,
7068#ifdef HAVE_READLINKAT
7069 dir_fd_converter, &dir_fd
7070#else
7071 dir_fd_unavailable, &dir_fd
7072#endif
7073 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007075
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007077#ifdef HAVE_READLINKAT
7078 if (dir_fd != DEFAULT_DIR_FD)
7079 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007080 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081#endif
7082 length = readlink(path.narrow, buffer, sizeof(buffer));
7083 Py_END_ALLOW_THREADS
7084
7085 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007086 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007087 goto exit;
7088 }
7089
7090 if (PyUnicode_Check(path.object))
7091 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7092 else
7093 return_value = PyBytes_FromStringAndSize(buffer, length);
7094exit:
7095 path_cleanup(&path);
7096 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007097}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007098
7099
Guido van Rossumb6775db1994-08-01 11:34:53 +00007100#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007102
Larry Hastings9cf065c2012-06-22 16:30:09 -07007103#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007104PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7106Create a symbolic link pointing to src named dst.\n\n\
7107target_is_directory is required on Windows if the target is to be\n\
7108 interpreted as a directory. (On Windows, symlink requires\n\
7109 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7110 target_is_directory is ignored on non-Windows platforms.\n\
7111\n\
7112If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7113 and path should be relative; path will then be relative to that directory.\n\
7114dir_fd may not be implemented on your platform.\n\
7115 If it is unavailable, using it will raise a NotImplementedError.");
7116
7117#if defined(MS_WINDOWS)
7118
7119/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7120static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7121static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007122
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007124check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125{
7126 HINSTANCE hKernel32;
7127 /* only recheck */
7128 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7129 return 1;
7130 hKernel32 = GetModuleHandleW(L"KERNEL32");
7131 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7132 "CreateSymbolicLinkW");
7133 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7134 "CreateSymbolicLinkA");
7135 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7136}
7137
Victor Stinner31b3b922013-06-05 01:49:17 +02007138/* Remove the last portion of the path */
7139static void
7140_dirnameW(WCHAR *path)
7141{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007142 WCHAR *ptr;
7143
7144 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007145 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007146 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007147 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007148 }
7149 *ptr = 0;
7150}
7151
Victor Stinner31b3b922013-06-05 01:49:17 +02007152/* Remove the last portion of the path */
7153static void
7154_dirnameA(char *path)
7155{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007156 char *ptr;
7157
7158 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007159 for(ptr = path + strlen(path); ptr != path; ptr--) {
7160 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007161 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007162 }
7163 *ptr = 0;
7164}
7165
Victor Stinner31b3b922013-06-05 01:49:17 +02007166/* Is this path absolute? */
7167static int
7168_is_absW(const WCHAR *path)
7169{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007170 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7171
7172}
7173
Victor Stinner31b3b922013-06-05 01:49:17 +02007174/* Is this path absolute? */
7175static int
7176_is_absA(const char *path)
7177{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007178 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7179
7180}
7181
Victor Stinner31b3b922013-06-05 01:49:17 +02007182/* join root and rest with a backslash */
7183static void
7184_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7185{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007186 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007187
Victor Stinner31b3b922013-06-05 01:49:17 +02007188 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007189 wcscpy(dest_path, rest);
7190 return;
7191 }
7192
7193 root_len = wcslen(root);
7194
7195 wcscpy(dest_path, root);
7196 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007197 dest_path[root_len] = L'\\';
7198 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007199 }
7200 wcscpy(dest_path+root_len, rest);
7201}
7202
Victor Stinner31b3b922013-06-05 01:49:17 +02007203/* join root and rest with a backslash */
7204static void
7205_joinA(char *dest_path, const char *root, const char *rest)
7206{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007207 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007208
Victor Stinner31b3b922013-06-05 01:49:17 +02007209 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007210 strcpy(dest_path, rest);
7211 return;
7212 }
7213
7214 root_len = strlen(root);
7215
7216 strcpy(dest_path, root);
7217 if(root_len) {
7218 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007219 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007220 }
7221 strcpy(dest_path+root_len, rest);
7222}
7223
Victor Stinner31b3b922013-06-05 01:49:17 +02007224/* Return True if the path at src relative to dest is a directory */
7225static int
7226_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007227{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007228 WIN32_FILE_ATTRIBUTE_DATA src_info;
7229 WCHAR dest_parent[MAX_PATH];
7230 WCHAR src_resolved[MAX_PATH] = L"";
7231
7232 /* dest_parent = os.path.dirname(dest) */
7233 wcscpy(dest_parent, dest);
7234 _dirnameW(dest_parent);
7235 /* src_resolved = os.path.join(dest_parent, src) */
7236 _joinW(src_resolved, dest_parent, src);
7237 return (
7238 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7239 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7240 );
7241}
7242
Victor Stinner31b3b922013-06-05 01:49:17 +02007243/* Return True if the path at src relative to dest is a directory */
7244static int
7245_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007246{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007247 WIN32_FILE_ATTRIBUTE_DATA src_info;
7248 char dest_parent[MAX_PATH];
7249 char src_resolved[MAX_PATH] = "";
7250
7251 /* dest_parent = os.path.dirname(dest) */
7252 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007253 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007255 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007256 return (
7257 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7258 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7259 );
7260}
7261
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007263
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007264static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007266{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007267 path_t src;
7268 path_t dst;
7269 int dir_fd = DEFAULT_DIR_FD;
7270 int target_is_directory = 0;
7271 static char *keywords[] = {"src", "dst", "target_is_directory",
7272 "dir_fd", NULL};
7273 PyObject *return_value;
7274#ifdef MS_WINDOWS
7275 DWORD result;
7276#else
7277 int result;
7278#endif
7279
7280 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007281 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007282 src.argument_name = "src";
7283 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007284 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007285 dst.argument_name = "dst";
7286
7287#ifdef MS_WINDOWS
7288 if (!check_CreateSymbolicLink()) {
7289 PyErr_SetString(PyExc_NotImplementedError,
7290 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007291 return NULL;
7292 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007293 if (!win32_can_symlink) {
7294 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007295 return NULL;
7296 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007297#endif
7298
7299 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7300 keywords,
7301 path_converter, &src,
7302 path_converter, &dst,
7303 &target_is_directory,
7304#ifdef HAVE_SYMLINKAT
7305 dir_fd_converter, &dir_fd
7306#else
7307 dir_fd_unavailable, &dir_fd
7308#endif
7309 ))
7310 return NULL;
7311
7312 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7313 PyErr_SetString(PyExc_ValueError,
7314 "symlink: src and dst must be the same type");
7315 return_value = NULL;
7316 goto exit;
7317 }
7318
7319#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320
Larry Hastings9cf065c2012-06-22 16:30:09 -07007321 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007322 if (dst.wide) {
7323 /* if src is a directory, ensure target_is_directory==1 */
7324 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007325 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7326 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007327 }
7328 else {
7329 /* if src is a directory, ensure target_is_directory==1 */
7330 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007331 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7332 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007334 Py_END_ALLOW_THREADS
7335
7336 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007337 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007338 goto exit;
7339 }
7340
7341#else
7342
7343 Py_BEGIN_ALLOW_THREADS
7344#if HAVE_SYMLINKAT
7345 if (dir_fd != DEFAULT_DIR_FD)
7346 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7347 else
7348#endif
7349 result = symlink(src.narrow, dst.narrow);
7350 Py_END_ALLOW_THREADS
7351
7352 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007353 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007354 goto exit;
7355 }
7356#endif
7357
7358 return_value = Py_None;
7359 Py_INCREF(Py_None);
7360 goto exit; /* silence "unused label" warning */
7361exit:
7362 path_cleanup(&src);
7363 path_cleanup(&dst);
7364 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007365}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007367#endif /* HAVE_SYMLINK */
7368
Larry Hastings9cf065c2012-06-22 16:30:09 -07007369
Brian Curtind40e6f72010-07-08 21:39:08 +00007370#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7371
Brian Curtind40e6f72010-07-08 21:39:08 +00007372static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007373win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007374{
7375 wchar_t *path;
7376 DWORD n_bytes_returned;
7377 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007378 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007379 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007380 HANDLE reparse_point_handle;
7381
7382 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7383 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7384 wchar_t *print_name;
7385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 static char *keywords[] = {"path", "dir_fd", NULL};
7387
7388 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7389 &po,
7390 dir_fd_unavailable, &dir_fd
7391 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007392 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393
Victor Stinnereb5657a2011-09-30 01:44:27 +02007394 path = PyUnicode_AsUnicode(po);
7395 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007396 return NULL;
7397
7398 /* First get a handle to the reparse point */
7399 Py_BEGIN_ALLOW_THREADS
7400 reparse_point_handle = CreateFileW(
7401 path,
7402 0,
7403 0,
7404 0,
7405 OPEN_EXISTING,
7406 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7407 0);
7408 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007409
Brian Curtind40e6f72010-07-08 21:39:08 +00007410 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007411 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007412
Brian Curtind40e6f72010-07-08 21:39:08 +00007413 Py_BEGIN_ALLOW_THREADS
7414 /* New call DeviceIoControl to read the reparse point */
7415 io_result = DeviceIoControl(
7416 reparse_point_handle,
7417 FSCTL_GET_REPARSE_POINT,
7418 0, 0, /* in buffer */
7419 target_buffer, sizeof(target_buffer),
7420 &n_bytes_returned,
7421 0 /* we're not using OVERLAPPED_IO */
7422 );
7423 CloseHandle(reparse_point_handle);
7424 Py_END_ALLOW_THREADS
7425
7426 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007427 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007428
7429 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7430 {
7431 PyErr_SetString(PyExc_ValueError,
7432 "not a symbolic link");
7433 return NULL;
7434 }
Brian Curtin74e45612010-07-09 15:58:59 +00007435 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7436 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7437
7438 result = PyUnicode_FromWideChar(print_name,
7439 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007440 return result;
7441}
7442
7443#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7444
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007445
Larry Hastings605a62d2012-06-24 04:33:36 -07007446static PyStructSequence_Field times_result_fields[] = {
7447 {"user", "user time"},
7448 {"system", "system time"},
7449 {"children_user", "user time of children"},
7450 {"children_system", "system time of children"},
7451 {"elapsed", "elapsed time since an arbitrary point in the past"},
7452 {NULL}
7453};
7454
7455PyDoc_STRVAR(times_result__doc__,
7456"times_result: Result from os.times().\n\n\
7457This object may be accessed either as a tuple of\n\
7458 (user, system, children_user, children_system, elapsed),\n\
7459or via the attributes user, system, children_user, children_system,\n\
7460and elapsed.\n\
7461\n\
7462See os.times for more information.");
7463
7464static PyStructSequence_Desc times_result_desc = {
7465 "times_result", /* name */
7466 times_result__doc__, /* doc */
7467 times_result_fields,
7468 5
7469};
7470
7471static PyTypeObject TimesResultType;
7472
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007473#ifdef MS_WINDOWS
7474#define HAVE_TIMES /* mandatory, for the method table */
7475#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007476
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007477#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007478
7479static PyObject *
7480build_times_result(double user, double system,
7481 double children_user, double children_system,
7482 double elapsed)
7483{
7484 PyObject *value = PyStructSequence_New(&TimesResultType);
7485 if (value == NULL)
7486 return NULL;
7487
7488#define SET(i, field) \
7489 { \
7490 PyObject *o = PyFloat_FromDouble(field); \
7491 if (!o) { \
7492 Py_DECREF(value); \
7493 return NULL; \
7494 } \
7495 PyStructSequence_SET_ITEM(value, i, o); \
7496 } \
7497
7498 SET(0, user);
7499 SET(1, system);
7500 SET(2, children_user);
7501 SET(3, children_system);
7502 SET(4, elapsed);
7503
7504#undef SET
7505
7506 return value;
7507}
7508
7509PyDoc_STRVAR(posix_times__doc__,
7510"times() -> times_result\n\n\
7511Return an object containing floating point numbers indicating process\n\
7512times. The object behaves like a named tuple with these fields:\n\
7513 (utime, stime, cutime, cstime, elapsed_time)");
7514
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007515#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007517posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007518{
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 FILETIME create, exit, kernel, user;
7520 HANDLE hProc;
7521 hProc = GetCurrentProcess();
7522 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7523 /* The fields of a FILETIME structure are the hi and lo part
7524 of a 64-bit value expressed in 100 nanosecond units.
7525 1e7 is one second in such units; 1e-7 the inverse.
7526 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7527 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007528 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 (double)(user.dwHighDateTime*429.4967296 +
7530 user.dwLowDateTime*1e-7),
7531 (double)(kernel.dwHighDateTime*429.4967296 +
7532 kernel.dwLowDateTime*1e-7),
7533 (double)0,
7534 (double)0,
7535 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007536}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007537#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007538#define NEED_TICKS_PER_SECOND
7539static long ticks_per_second = -1;
7540static PyObject *
7541posix_times(PyObject *self, PyObject *noargs)
7542{
7543 struct tms t;
7544 clock_t c;
7545 errno = 0;
7546 c = times(&t);
7547 if (c == (clock_t) -1)
7548 return posix_error();
7549 return build_times_result(
7550 (double)t.tms_utime / ticks_per_second,
7551 (double)t.tms_stime / ticks_per_second,
7552 (double)t.tms_cutime / ticks_per_second,
7553 (double)t.tms_cstime / ticks_per_second,
7554 (double)c / ticks_per_second);
7555}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007556#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007557
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007558#endif /* HAVE_TIMES */
7559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007560
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007561#ifdef HAVE_GETSID
7562PyDoc_STRVAR(posix_getsid__doc__,
7563"getsid(pid) -> sid\n\n\
7564Call the system call getsid().");
7565
7566static PyObject *
7567posix_getsid(PyObject *self, PyObject *args)
7568{
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 pid_t pid;
7570 int sid;
7571 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7572 return NULL;
7573 sid = getsid(pid);
7574 if (sid < 0)
7575 return posix_error();
7576 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007577}
7578#endif /* HAVE_GETSID */
7579
7580
Guido van Rossumb6775db1994-08-01 11:34:53 +00007581#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007582PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007583"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007584Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007585
Barry Warsaw53699e91996-12-10 23:23:01 +00007586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007587posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007588{
Victor Stinner8c62be82010-05-06 00:08:46 +00007589 if (setsid() < 0)
7590 return posix_error();
7591 Py_INCREF(Py_None);
7592 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007593}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007594#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007595
Guido van Rossumb6775db1994-08-01 11:34:53 +00007596#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007597PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007598"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007599Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007600
Barry Warsaw53699e91996-12-10 23:23:01 +00007601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007602posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 pid_t pid;
7605 int pgrp;
7606 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7607 return NULL;
7608 if (setpgid(pid, pgrp) < 0)
7609 return posix_error();
7610 Py_INCREF(Py_None);
7611 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007612}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007613#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Guido van Rossumb6775db1994-08-01 11:34:53 +00007616#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007617PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007618"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007619Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007620
Barry Warsaw53699e91996-12-10 23:23:01 +00007621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007622posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007623{
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 int fd;
7625 pid_t pgid;
7626 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7627 return NULL;
7628 pgid = tcgetpgrp(fd);
7629 if (pgid < 0)
7630 return posix_error();
7631 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007632}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007635
Guido van Rossumb6775db1994-08-01 11:34:53 +00007636#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007637PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007638"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007639Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007640
Barry Warsaw53699e91996-12-10 23:23:01 +00007641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007642posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007643{
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 int fd;
7645 pid_t pgid;
7646 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7647 return NULL;
7648 if (tcsetpgrp(fd, pgid) < 0)
7649 return posix_error();
7650 Py_INCREF(Py_None);
7651 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007652}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007653#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007654
Guido van Rossum687dd131993-05-17 08:34:16 +00007655/* Functions acting on file descriptors */
7656
Victor Stinnerdaf45552013-08-28 00:53:59 +02007657#ifdef O_CLOEXEC
7658extern int _Py_open_cloexec_works;
7659#endif
7660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007662"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7663Open a file for low level IO. Returns a file handle (integer).\n\
7664\n\
7665If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7666 and path should be relative; path will then be relative to that directory.\n\
7667dir_fd may not be implemented on your platform.\n\
7668 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Barry Warsaw53699e91996-12-10 23:23:01 +00007670static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007671posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007672{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007673 path_t path;
7674 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007676 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007678 PyObject *return_value = NULL;
7679 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007680#ifdef O_CLOEXEC
7681 int *atomic_flag_works = &_Py_open_cloexec_works;
7682#elif !defined(MS_WINDOWS)
7683 int *atomic_flag_works = NULL;
7684#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007685
Larry Hastings9cf065c2012-06-22 16:30:09 -07007686 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007687 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007688 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7689 path_converter, &path,
7690 &flags, &mode,
7691#ifdef HAVE_OPENAT
7692 dir_fd_converter, &dir_fd
7693#else
7694 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007695#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007696 ))
7697 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007698
Victor Stinnerdaf45552013-08-28 00:53:59 +02007699#ifdef MS_WINDOWS
7700 flags |= O_NOINHERIT;
7701#elif defined(O_CLOEXEC)
7702 flags |= O_CLOEXEC;
7703#endif
7704
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007706#ifdef MS_WINDOWS
7707 if (path.wide)
7708 fd = _wopen(path.wide, flags, mode);
7709 else
7710#endif
7711#ifdef HAVE_OPENAT
7712 if (dir_fd != DEFAULT_DIR_FD)
7713 fd = openat(dir_fd, path.narrow, flags, mode);
7714 else
7715#endif
7716 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007718
Larry Hastings9cf065c2012-06-22 16:30:09 -07007719 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007720 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007721 goto exit;
7722 }
7723
Victor Stinnerdaf45552013-08-28 00:53:59 +02007724#ifndef MS_WINDOWS
7725 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7726 close(fd);
7727 goto exit;
7728 }
7729#endif
7730
Larry Hastings9cf065c2012-06-22 16:30:09 -07007731 return_value = PyLong_FromLong((long)fd);
7732
7733exit:
7734 path_cleanup(&path);
7735 return return_value;
7736}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007738PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007739"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007740Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007741
Barry Warsaw53699e91996-12-10 23:23:01 +00007742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007743posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007744{
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 int fd, res;
7746 if (!PyArg_ParseTuple(args, "i:close", &fd))
7747 return NULL;
7748 if (!_PyVerify_fd(fd))
7749 return posix_error();
7750 Py_BEGIN_ALLOW_THREADS
7751 res = close(fd);
7752 Py_END_ALLOW_THREADS
7753 if (res < 0)
7754 return posix_error();
7755 Py_INCREF(Py_None);
7756 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007757}
7758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007759
Victor Stinner8c62be82010-05-06 00:08:46 +00007760PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007761"closerange(fd_low, fd_high)\n\n\
7762Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7763
7764static PyObject *
7765posix_closerange(PyObject *self, PyObject *args)
7766{
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 int fd_from, fd_to, i;
7768 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7769 return NULL;
7770 Py_BEGIN_ALLOW_THREADS
7771 for (i = fd_from; i < fd_to; i++)
7772 if (_PyVerify_fd(i))
7773 close(i);
7774 Py_END_ALLOW_THREADS
7775 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007776}
7777
7778
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007779PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007780"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007781Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007782
Barry Warsaw53699e91996-12-10 23:23:01 +00007783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007784posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007785{
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007787
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7789 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007790
Victor Stinnerdaf45552013-08-28 00:53:59 +02007791 fd = _Py_dup(fd);
7792 if (fd == -1)
7793 return NULL;
7794
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007796}
7797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007798
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007799PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007800"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007801Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007802
Barry Warsaw53699e91996-12-10 23:23:01 +00007803static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007804posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007805{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007806 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7807 int fd, fd2;
7808 int inheritable = 1;
7809 int res;
7810#if defined(HAVE_DUP3) && \
7811 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7812 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7813 int dup3_works = -1;
7814#endif
7815
7816 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7817 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007819
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 if (!_PyVerify_fd_dup2(fd, fd2))
7821 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007822
7823#ifdef MS_WINDOWS
7824 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007826 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 if (res < 0)
7828 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007829
7830 /* Character files like console cannot be make non-inheritable */
7831 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7832 close(fd2);
7833 return NULL;
7834 }
7835
7836#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7837 Py_BEGIN_ALLOW_THREADS
7838 if (!inheritable)
7839 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7840 else
7841 res = dup2(fd, fd2);
7842 Py_END_ALLOW_THREADS
7843 if (res < 0)
7844 return posix_error();
7845
7846#else
7847
7848#ifdef HAVE_DUP3
7849 if (!inheritable && dup3_works != 0) {
7850 Py_BEGIN_ALLOW_THREADS
7851 res = dup3(fd, fd2, O_CLOEXEC);
7852 Py_END_ALLOW_THREADS
7853 if (res < 0) {
7854 if (dup3_works == -1)
7855 dup3_works = (errno != ENOSYS);
7856 if (dup3_works)
7857 return posix_error();
7858 }
7859 }
7860
7861 if (inheritable || dup3_works == 0)
7862 {
7863#endif
7864 Py_BEGIN_ALLOW_THREADS
7865 res = dup2(fd, fd2);
7866 Py_END_ALLOW_THREADS
7867 if (res < 0)
7868 return posix_error();
7869
7870 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7871 close(fd2);
7872 return NULL;
7873 }
7874#ifdef HAVE_DUP3
7875 }
7876#endif
7877
7878#endif
7879
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 Py_INCREF(Py_None);
7881 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007882}
7883
Ross Lagerwall7807c352011-03-17 20:20:30 +02007884#ifdef HAVE_LOCKF
7885PyDoc_STRVAR(posix_lockf__doc__,
7886"lockf(fd, cmd, len)\n\n\
7887Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7888fd is an open file descriptor.\n\
7889cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7890F_TEST.\n\
7891len specifies the section of the file to lock.");
7892
7893static PyObject *
7894posix_lockf(PyObject *self, PyObject *args)
7895{
7896 int fd, cmd, res;
7897 off_t len;
7898 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7899 &fd, &cmd, _parse_off_t, &len))
7900 return NULL;
7901
7902 Py_BEGIN_ALLOW_THREADS
7903 res = lockf(fd, cmd, len);
7904 Py_END_ALLOW_THREADS
7905
7906 if (res < 0)
7907 return posix_error();
7908
7909 Py_RETURN_NONE;
7910}
7911#endif
7912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007914PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007915"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007916Set the current position of a file descriptor.\n\
7917Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007918
Barry Warsaw53699e91996-12-10 23:23:01 +00007919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007920posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007921{
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007923#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007925#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007926 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007927#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007928 PyObject *posobj;
7929 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007931#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7933 switch (how) {
7934 case 0: how = SEEK_SET; break;
7935 case 1: how = SEEK_CUR; break;
7936 case 2: how = SEEK_END; break;
7937 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007938#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007939
Ross Lagerwall8e749672011-03-17 21:54:07 +02007940#if !defined(HAVE_LARGEFILE_SUPPORT)
7941 pos = PyLong_AsLong(posobj);
7942#else
7943 pos = PyLong_AsLongLong(posobj);
7944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 if (PyErr_Occurred())
7946 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007947
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (!_PyVerify_fd(fd))
7949 return posix_error();
7950 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007955#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 Py_END_ALLOW_THREADS
7957 if (res < 0)
7958 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007959
7960#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007962#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007964#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007965}
7966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007968PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007969"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007970Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007971
Barry Warsaw53699e91996-12-10 23:23:01 +00007972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007973posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007974{
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 int fd, size;
7976 Py_ssize_t n;
7977 PyObject *buffer;
7978 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7979 return NULL;
7980 if (size < 0) {
7981 errno = EINVAL;
7982 return posix_error();
7983 }
7984 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7985 if (buffer == NULL)
7986 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007987 if (!_PyVerify_fd(fd)) {
7988 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007990 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 Py_BEGIN_ALLOW_THREADS
7992 n = read(fd, PyBytes_AS_STRING(buffer), size);
7993 Py_END_ALLOW_THREADS
7994 if (n < 0) {
7995 Py_DECREF(buffer);
7996 return posix_error();
7997 }
7998 if (n != size)
7999 _PyBytes_Resize(&buffer, n);
8000 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008001}
8002
Ross Lagerwall7807c352011-03-17 20:20:30 +02008003#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8004 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008005static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008006iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8007{
8008 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008009 Py_ssize_t blen, total = 0;
8010
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008011 *iov = PyMem_New(struct iovec, cnt);
8012 if (*iov == NULL) {
8013 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008014 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008016
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008017 *buf = PyMem_New(Py_buffer, cnt);
8018 if (*buf == NULL) {
8019 PyMem_Del(*iov);
8020 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008021 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008022 }
8023
8024 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008025 PyObject *item = PySequence_GetItem(seq, i);
8026 if (item == NULL)
8027 goto fail;
8028 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8029 Py_DECREF(item);
8030 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008031 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008032 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008033 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008034 blen = (*buf)[i].len;
8035 (*iov)[i].iov_len = blen;
8036 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008037 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008038 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008039
8040fail:
8041 PyMem_Del(*iov);
8042 for (j = 0; j < i; j++) {
8043 PyBuffer_Release(&(*buf)[j]);
8044 }
8045 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008046 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047}
8048
8049static void
8050iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8051{
8052 int i;
8053 PyMem_Del(iov);
8054 for (i = 0; i < cnt; i++) {
8055 PyBuffer_Release(&buf[i]);
8056 }
8057 PyMem_Del(buf);
8058}
8059#endif
8060
Ross Lagerwall7807c352011-03-17 20:20:30 +02008061#ifdef HAVE_READV
8062PyDoc_STRVAR(posix_readv__doc__,
8063"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008064Read from a file descriptor fd into a number of mutable, bytes-like\n\
8065objects (\"buffers\"). readv will transfer data into each buffer\n\
8066until it is full and then move on to the next buffer in the sequence\n\
8067to hold the rest of the data.\n\n\
8068readv returns the total number of bytes read (which may be less than\n\
8069the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008070
8071static PyObject *
8072posix_readv(PyObject *self, PyObject *args)
8073{
8074 int fd, cnt;
8075 Py_ssize_t n;
8076 PyObject *seq;
8077 struct iovec *iov;
8078 Py_buffer *buf;
8079
8080 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8081 return NULL;
8082 if (!PySequence_Check(seq)) {
8083 PyErr_SetString(PyExc_TypeError,
8084 "readv() arg 2 must be a sequence");
8085 return NULL;
8086 }
8087 cnt = PySequence_Size(seq);
8088
Victor Stinner57ddf782014-01-08 15:21:28 +01008089 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008090 return NULL;
8091
8092 Py_BEGIN_ALLOW_THREADS
8093 n = readv(fd, iov, cnt);
8094 Py_END_ALLOW_THREADS
8095
8096 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008097 if (n < 0)
8098 return posix_error();
8099
Ross Lagerwall7807c352011-03-17 20:20:30 +02008100 return PyLong_FromSsize_t(n);
8101}
8102#endif
8103
8104#ifdef HAVE_PREAD
8105PyDoc_STRVAR(posix_pread__doc__,
8106"pread(fd, buffersize, offset) -> string\n\n\
8107Read from a file descriptor, fd, at a position of offset. It will read up\n\
8108to buffersize number of bytes. The file offset remains unchanged.");
8109
8110static PyObject *
8111posix_pread(PyObject *self, PyObject *args)
8112{
8113 int fd, size;
8114 off_t offset;
8115 Py_ssize_t n;
8116 PyObject *buffer;
8117 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8118 return NULL;
8119
8120 if (size < 0) {
8121 errno = EINVAL;
8122 return posix_error();
8123 }
8124 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8125 if (buffer == NULL)
8126 return NULL;
8127 if (!_PyVerify_fd(fd)) {
8128 Py_DECREF(buffer);
8129 return posix_error();
8130 }
8131 Py_BEGIN_ALLOW_THREADS
8132 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8133 Py_END_ALLOW_THREADS
8134 if (n < 0) {
8135 Py_DECREF(buffer);
8136 return posix_error();
8137 }
8138 if (n != size)
8139 _PyBytes_Resize(&buffer, n);
8140 return buffer;
8141}
8142#endif
8143
8144PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008145"write(fd, data) -> byteswritten\n\n\
8146Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008147
8148static PyObject *
8149posix_write(PyObject *self, PyObject *args)
8150{
8151 Py_buffer pbuf;
8152 int fd;
8153 Py_ssize_t size, len;
8154
8155 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8156 return NULL;
8157 if (!_PyVerify_fd(fd)) {
8158 PyBuffer_Release(&pbuf);
8159 return posix_error();
8160 }
8161 len = pbuf.len;
8162 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008163#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008164 if (len > INT_MAX)
8165 len = INT_MAX;
8166 size = write(fd, pbuf.buf, (int)len);
8167#else
8168 size = write(fd, pbuf.buf, len);
8169#endif
8170 Py_END_ALLOW_THREADS
8171 PyBuffer_Release(&pbuf);
8172 if (size < 0)
8173 return posix_error();
8174 return PyLong_FromSsize_t(size);
8175}
8176
8177#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008178PyDoc_STRVAR(posix_sendfile__doc__,
8179"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8180sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8181 -> byteswritten\n\
8182Copy nbytes bytes from file descriptor in to file descriptor out.");
8183
8184static PyObject *
8185posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8186{
8187 int in, out;
8188 Py_ssize_t ret;
8189 off_t offset;
8190
8191#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8192#ifndef __APPLE__
8193 Py_ssize_t len;
8194#endif
8195 PyObject *headers = NULL, *trailers = NULL;
8196 Py_buffer *hbuf, *tbuf;
8197 off_t sbytes;
8198 struct sf_hdtr sf;
8199 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008200 static char *keywords[] = {"out", "in",
8201 "offset", "count",
8202 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008203
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008204 sf.headers = NULL;
8205 sf.trailers = NULL;
8206
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207#ifdef __APPLE__
8208 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008209 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008210#else
8211 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008212 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008213#endif
8214 &headers, &trailers, &flags))
8215 return NULL;
8216 if (headers != NULL) {
8217 if (!PySequence_Check(headers)) {
8218 PyErr_SetString(PyExc_TypeError,
8219 "sendfile() headers must be a sequence or None");
8220 return NULL;
8221 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008222 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008223 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008224 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008225 (i = iov_setup(&(sf.headers), &hbuf,
8226 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008227 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008228#ifdef __APPLE__
8229 sbytes += i;
8230#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231 }
8232 }
8233 if (trailers != NULL) {
8234 if (!PySequence_Check(trailers)) {
8235 PyErr_SetString(PyExc_TypeError,
8236 "sendfile() trailers must be a sequence or None");
8237 return NULL;
8238 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008239 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008240 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008241 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008242 (i = iov_setup(&(sf.trailers), &tbuf,
8243 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008244 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008245#ifdef __APPLE__
8246 sbytes += i;
8247#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248 }
8249 }
8250
8251 Py_BEGIN_ALLOW_THREADS
8252#ifdef __APPLE__
8253 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8254#else
8255 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8256#endif
8257 Py_END_ALLOW_THREADS
8258
8259 if (sf.headers != NULL)
8260 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8261 if (sf.trailers != NULL)
8262 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8263
8264 if (ret < 0) {
8265 if ((errno == EAGAIN) || (errno == EBUSY)) {
8266 if (sbytes != 0) {
8267 // some data has been sent
8268 goto done;
8269 }
8270 else {
8271 // no data has been sent; upper application is supposed
8272 // to retry on EAGAIN or EBUSY
8273 return posix_error();
8274 }
8275 }
8276 return posix_error();
8277 }
8278 goto done;
8279
8280done:
8281 #if !defined(HAVE_LARGEFILE_SUPPORT)
8282 return Py_BuildValue("l", sbytes);
8283 #else
8284 return Py_BuildValue("L", sbytes);
8285 #endif
8286
8287#else
8288 Py_ssize_t count;
8289 PyObject *offobj;
8290 static char *keywords[] = {"out", "in",
8291 "offset", "count", NULL};
8292 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8293 keywords, &out, &in, &offobj, &count))
8294 return NULL;
8295#ifdef linux
8296 if (offobj == Py_None) {
8297 Py_BEGIN_ALLOW_THREADS
8298 ret = sendfile(out, in, NULL, count);
8299 Py_END_ALLOW_THREADS
8300 if (ret < 0)
8301 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008302 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008303 }
8304#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008305 if (!_parse_off_t(offobj, &offset))
8306 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 Py_BEGIN_ALLOW_THREADS
8308 ret = sendfile(out, in, &offset, count);
8309 Py_END_ALLOW_THREADS
8310 if (ret < 0)
8311 return posix_error();
8312 return Py_BuildValue("n", ret);
8313#endif
8314}
8315#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008316
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008317PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008318"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008319Like stat(), but for an open file descriptor.\n\
8320Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008321
Barry Warsaw53699e91996-12-10 23:23:01 +00008322static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008323posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008324{
Victor Stinner8c62be82010-05-06 00:08:46 +00008325 int fd;
8326 STRUCT_STAT st;
8327 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008328 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 Py_BEGIN_ALLOW_THREADS
8331 res = FSTAT(fd, &st);
8332 Py_END_ALLOW_THREADS
8333 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008334#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008335 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008336#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008338#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 }
Tim Peters5aa91602002-01-30 05:46:57 +00008340
Victor Stinner4195b5c2012-02-08 23:03:19 +01008341 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008342}
8343
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008344PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008345"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008346Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008347connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008348
8349static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008350posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008351{
Victor Stinner8c62be82010-05-06 00:08:46 +00008352 int fd;
8353 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8354 return NULL;
8355 if (!_PyVerify_fd(fd))
8356 return PyBool_FromLong(0);
8357 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008358}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008359
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008360#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008361PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008362"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008363Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008364
Barry Warsaw53699e91996-12-10 23:23:01 +00008365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008366posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008367{
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008369#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008371 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008373#else
8374 int res;
8375#endif
8376
8377#ifdef MS_WINDOWS
8378 attr.nLength = sizeof(attr);
8379 attr.lpSecurityDescriptor = NULL;
8380 attr.bInheritHandle = FALSE;
8381
8382 Py_BEGIN_ALLOW_THREADS
8383 ok = CreatePipe(&read, &write, &attr, 0);
8384 if (ok) {
8385 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8386 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8387 if (fds[0] == -1 || fds[1] == -1) {
8388 CloseHandle(read);
8389 CloseHandle(write);
8390 ok = 0;
8391 }
8392 }
8393 Py_END_ALLOW_THREADS
8394
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008396 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008397#else
8398
8399#ifdef HAVE_PIPE2
8400 Py_BEGIN_ALLOW_THREADS
8401 res = pipe2(fds, O_CLOEXEC);
8402 Py_END_ALLOW_THREADS
8403
8404 if (res != 0 && errno == ENOSYS)
8405 {
8406#endif
8407 Py_BEGIN_ALLOW_THREADS
8408 res = pipe(fds);
8409 Py_END_ALLOW_THREADS
8410
8411 if (res == 0) {
8412 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8413 close(fds[0]);
8414 close(fds[1]);
8415 return NULL;
8416 }
8417 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8418 close(fds[0]);
8419 close(fds[1]);
8420 return NULL;
8421 }
8422 }
8423#ifdef HAVE_PIPE2
8424 }
8425#endif
8426
8427 if (res != 0)
8428 return PyErr_SetFromErrno(PyExc_OSError);
8429#endif /* !MS_WINDOWS */
8430 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008431}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008432#endif /* HAVE_PIPE */
8433
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008434#ifdef HAVE_PIPE2
8435PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008436"pipe2(flags) -> (read_end, write_end)\n\n\
8437Create a pipe with flags set atomically.\n\
8438flags can be constructed by ORing together one or more of these values:\n\
8439O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008440");
8441
8442static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008443posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008444{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008445 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008446 int fds[2];
8447 int res;
8448
Serhiy Storchaka78980432013-01-15 01:12:17 +02008449 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008450 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008451 return NULL;
8452
8453 res = pipe2(fds, flags);
8454 if (res != 0)
8455 return posix_error();
8456 return Py_BuildValue("(ii)", fds[0], fds[1]);
8457}
8458#endif /* HAVE_PIPE2 */
8459
Ross Lagerwall7807c352011-03-17 20:20:30 +02008460#ifdef HAVE_WRITEV
8461PyDoc_STRVAR(posix_writev__doc__,
8462"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008463Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8464must be a sequence of bytes-like objects.\n\n\
8465writev writes the contents of each object to the file descriptor\n\
8466and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008467
8468static PyObject *
8469posix_writev(PyObject *self, PyObject *args)
8470{
8471 int fd, cnt;
8472 Py_ssize_t res;
8473 PyObject *seq;
8474 struct iovec *iov;
8475 Py_buffer *buf;
8476 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8477 return NULL;
8478 if (!PySequence_Check(seq)) {
8479 PyErr_SetString(PyExc_TypeError,
8480 "writev() arg 2 must be a sequence");
8481 return NULL;
8482 }
8483 cnt = PySequence_Size(seq);
8484
Victor Stinner57ddf782014-01-08 15:21:28 +01008485 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008486 return NULL;
8487 }
8488
8489 Py_BEGIN_ALLOW_THREADS
8490 res = writev(fd, iov, cnt);
8491 Py_END_ALLOW_THREADS
8492
8493 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008494 if (res < 0)
8495 return posix_error();
8496
Ross Lagerwall7807c352011-03-17 20:20:30 +02008497 return PyLong_FromSsize_t(res);
8498}
8499#endif
8500
8501#ifdef HAVE_PWRITE
8502PyDoc_STRVAR(posix_pwrite__doc__,
8503"pwrite(fd, string, offset) -> byteswritten\n\n\
8504Write string to a file descriptor, fd, from offset, leaving the file\n\
8505offset unchanged.");
8506
8507static PyObject *
8508posix_pwrite(PyObject *self, PyObject *args)
8509{
8510 Py_buffer pbuf;
8511 int fd;
8512 off_t offset;
8513 Py_ssize_t size;
8514
8515 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8516 return NULL;
8517
8518 if (!_PyVerify_fd(fd)) {
8519 PyBuffer_Release(&pbuf);
8520 return posix_error();
8521 }
8522 Py_BEGIN_ALLOW_THREADS
8523 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8524 Py_END_ALLOW_THREADS
8525 PyBuffer_Release(&pbuf);
8526 if (size < 0)
8527 return posix_error();
8528 return PyLong_FromSsize_t(size);
8529}
8530#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008531
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008532#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008533PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008534"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8535Create a FIFO (a POSIX named pipe).\n\
8536\n\
8537If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8538 and path should be relative; path will then be relative to that directory.\n\
8539dir_fd may not be implemented on your platform.\n\
8540 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008541
Barry Warsaw53699e91996-12-10 23:23:01 +00008542static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008543posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008544{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008545 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008546 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008547 int dir_fd = DEFAULT_DIR_FD;
8548 int result;
8549 PyObject *return_value = NULL;
8550 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8551
8552 memset(&path, 0, sizeof(path));
8553 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8554 path_converter, &path,
8555 &mode,
8556#ifdef HAVE_MKFIFOAT
8557 dir_fd_converter, &dir_fd
8558#else
8559 dir_fd_unavailable, &dir_fd
8560#endif
8561 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008563
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008565#ifdef HAVE_MKFIFOAT
8566 if (dir_fd != DEFAULT_DIR_FD)
8567 result = mkfifoat(dir_fd, path.narrow, mode);
8568 else
8569#endif
8570 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008572
8573 if (result < 0) {
8574 return_value = posix_error();
8575 goto exit;
8576 }
8577
8578 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008580
8581exit:
8582 path_cleanup(&path);
8583 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008584}
8585#endif
8586
Neal Norwitz11690112002-07-30 01:08:28 +00008587#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008588PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008589"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008590Create a filesystem node (file, device special file or named pipe)\n\
8591named filename. mode specifies both the permissions to use and the\n\
8592type of node to be created, being combined (bitwise OR) with one of\n\
8593S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008594device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008595os.makedev()), otherwise it is ignored.\n\
8596\n\
8597If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8598 and path should be relative; path will then be relative to that directory.\n\
8599dir_fd may not be implemented on your platform.\n\
8600 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008601
8602
8603static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008604posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008605{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008606 path_t path;
8607 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008609 int dir_fd = DEFAULT_DIR_FD;
8610 int result;
8611 PyObject *return_value = NULL;
8612 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8613
8614 memset(&path, 0, sizeof(path));
8615 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8616 path_converter, &path,
8617 &mode, &device,
8618#ifdef HAVE_MKNODAT
8619 dir_fd_converter, &dir_fd
8620#else
8621 dir_fd_unavailable, &dir_fd
8622#endif
8623 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008624 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008625
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008627#ifdef HAVE_MKNODAT
8628 if (dir_fd != DEFAULT_DIR_FD)
8629 result = mknodat(dir_fd, path.narrow, mode, device);
8630 else
8631#endif
8632 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008634
8635 if (result < 0) {
8636 return_value = posix_error();
8637 goto exit;
8638 }
8639
8640 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008642
Larry Hastings9cf065c2012-06-22 16:30:09 -07008643exit:
8644 path_cleanup(&path);
8645 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008646}
8647#endif
8648
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008649#ifdef HAVE_DEVICE_MACROS
8650PyDoc_STRVAR(posix_major__doc__,
8651"major(device) -> major number\n\
8652Extracts a device major number from a raw device number.");
8653
8654static PyObject *
8655posix_major(PyObject *self, PyObject *args)
8656{
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 int device;
8658 if (!PyArg_ParseTuple(args, "i:major", &device))
8659 return NULL;
8660 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008661}
8662
8663PyDoc_STRVAR(posix_minor__doc__,
8664"minor(device) -> minor number\n\
8665Extracts a device minor number from a raw device number.");
8666
8667static PyObject *
8668posix_minor(PyObject *self, PyObject *args)
8669{
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 int device;
8671 if (!PyArg_ParseTuple(args, "i:minor", &device))
8672 return NULL;
8673 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008674}
8675
8676PyDoc_STRVAR(posix_makedev__doc__,
8677"makedev(major, minor) -> device number\n\
8678Composes a raw device number from the major and minor device numbers.");
8679
8680static PyObject *
8681posix_makedev(PyObject *self, PyObject *args)
8682{
Victor Stinner8c62be82010-05-06 00:08:46 +00008683 int major, minor;
8684 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8685 return NULL;
8686 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008687}
8688#endif /* device macros */
8689
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008690
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008691#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008692PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008693"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008694Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008695
Barry Warsaw53699e91996-12-10 23:23:01 +00008696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008697posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008698{
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 int fd;
8700 off_t length;
8701 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008702
Ross Lagerwall7807c352011-03-17 20:20:30 +02008703 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008705
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 Py_BEGIN_ALLOW_THREADS
8707 res = ftruncate(fd, length);
8708 Py_END_ALLOW_THREADS
8709 if (res < 0)
8710 return posix_error();
8711 Py_INCREF(Py_None);
8712 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008713}
8714#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008715
Ross Lagerwall7807c352011-03-17 20:20:30 +02008716#ifdef HAVE_TRUNCATE
8717PyDoc_STRVAR(posix_truncate__doc__,
8718"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008719Truncate the file given by path to length bytes.\n\
8720On some platforms, path may also be specified as an open file descriptor.\n\
8721 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008722
8723static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008724posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008725{
Georg Brandl306336b2012-06-24 12:55:33 +02008726 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008727 off_t length;
8728 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008729 PyObject *result = NULL;
8730 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731
Georg Brandl306336b2012-06-24 12:55:33 +02008732 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008733 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008734#ifdef HAVE_FTRUNCATE
8735 path.allow_fd = 1;
8736#endif
8737 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8738 path_converter, &path,
8739 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008740 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008741
8742 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008743#ifdef HAVE_FTRUNCATE
8744 if (path.fd != -1)
8745 res = ftruncate(path.fd, length);
8746 else
8747#endif
8748 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008749 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008750 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008751 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008752 else {
8753 Py_INCREF(Py_None);
8754 result = Py_None;
8755 }
8756 path_cleanup(&path);
8757 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008758}
8759#endif
8760
8761#ifdef HAVE_POSIX_FALLOCATE
8762PyDoc_STRVAR(posix_posix_fallocate__doc__,
8763"posix_fallocate(fd, offset, len)\n\n\
8764Ensures that enough disk space is allocated for the file specified by fd\n\
8765starting from offset and continuing for len bytes.");
8766
8767static PyObject *
8768posix_posix_fallocate(PyObject *self, PyObject *args)
8769{
8770 off_t len, offset;
8771 int res, fd;
8772
8773 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8774 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8775 return NULL;
8776
8777 Py_BEGIN_ALLOW_THREADS
8778 res = posix_fallocate(fd, offset, len);
8779 Py_END_ALLOW_THREADS
8780 if (res != 0) {
8781 errno = res;
8782 return posix_error();
8783 }
8784 Py_RETURN_NONE;
8785}
8786#endif
8787
8788#ifdef HAVE_POSIX_FADVISE
8789PyDoc_STRVAR(posix_posix_fadvise__doc__,
8790"posix_fadvise(fd, offset, len, advice)\n\n\
8791Announces an intention to access data in a specific pattern thus allowing\n\
8792the kernel to make optimizations.\n\
8793The advice applies to the region of the file specified by fd starting at\n\
8794offset and continuing for len bytes.\n\
8795advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8796POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8797POSIX_FADV_DONTNEED.");
8798
8799static PyObject *
8800posix_posix_fadvise(PyObject *self, PyObject *args)
8801{
8802 off_t len, offset;
8803 int res, fd, advice;
8804
8805 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8806 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8807 return NULL;
8808
8809 Py_BEGIN_ALLOW_THREADS
8810 res = posix_fadvise(fd, offset, len, advice);
8811 Py_END_ALLOW_THREADS
8812 if (res != 0) {
8813 errno = res;
8814 return posix_error();
8815 }
8816 Py_RETURN_NONE;
8817}
8818#endif
8819
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008820#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008821PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008822"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008823Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008824
Fred Drake762e2061999-08-26 17:23:54 +00008825/* Save putenv() parameters as values here, so we can collect them when they
8826 * get re-set with another call for the same key. */
8827static PyObject *posix_putenv_garbage;
8828
Tim Peters5aa91602002-01-30 05:46:57 +00008829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008830posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008831{
Victor Stinner84ae1182010-05-06 22:05:07 +00008832 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008833#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008834 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008835 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008836
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008838 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008839 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008841
Victor Stinner65170952011-11-22 22:16:17 +01008842 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008843 if (newstr == NULL) {
8844 PyErr_NoMemory();
8845 goto error;
8846 }
Victor Stinner65170952011-11-22 22:16:17 +01008847 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8848 PyErr_Format(PyExc_ValueError,
8849 "the environment variable is longer than %u characters",
8850 _MAX_ENV);
8851 goto error;
8852 }
8853
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008855 if (newenv == NULL)
8856 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008859 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008861#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008862 PyObject *os1, *os2;
8863 char *s1, *s2;
8864 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008865
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008866 if (!PyArg_ParseTuple(args,
8867 "O&O&:putenv",
8868 PyUnicode_FSConverter, &os1,
8869 PyUnicode_FSConverter, &os2))
8870 return NULL;
8871 s1 = PyBytes_AsString(os1);
8872 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008873
Victor Stinner65170952011-11-22 22:16:17 +01008874 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008875 if (newstr == NULL) {
8876 PyErr_NoMemory();
8877 goto error;
8878 }
8879
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008883 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008885#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008886
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 /* Install the first arg and newstr in posix_putenv_garbage;
8888 * this will cause previous value to be collected. This has to
8889 * happen after the real putenv() call because the old value
8890 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008891 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 /* really not much we can do; just leak */
8893 PyErr_Clear();
8894 }
8895 else {
8896 Py_DECREF(newstr);
8897 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008898
Martin v. Löwis011e8422009-05-05 04:43:17 +00008899#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 Py_DECREF(os1);
8901 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008902#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008903 Py_RETURN_NONE;
8904
8905error:
8906#ifndef MS_WINDOWS
8907 Py_DECREF(os1);
8908 Py_DECREF(os2);
8909#endif
8910 Py_XDECREF(newstr);
8911 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008912}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008913#endif /* putenv */
8914
Guido van Rossumc524d952001-10-19 01:31:59 +00008915#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008916PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008917"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008918Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008919
8920static PyObject *
8921posix_unsetenv(PyObject *self, PyObject *args)
8922{
Victor Stinner65170952011-11-22 22:16:17 +01008923 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008924#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008925 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008926#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008927
8928 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008929
Victor Stinner65170952011-11-22 22:16:17 +01008930 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008931 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008932
Victor Stinner984890f2011-11-24 13:53:38 +01008933#ifdef HAVE_BROKEN_UNSETENV
8934 unsetenv(PyBytes_AS_STRING(name));
8935#else
Victor Stinner65170952011-11-22 22:16:17 +01008936 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008937 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008938 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008939 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008940 }
Victor Stinner984890f2011-11-24 13:53:38 +01008941#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008942
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 /* Remove the key from posix_putenv_garbage;
8944 * this will cause it to be collected. This has to
8945 * happen after the real unsetenv() call because the
8946 * old value was still accessible until then.
8947 */
Victor Stinner65170952011-11-22 22:16:17 +01008948 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 /* really not much we can do; just leak */
8950 PyErr_Clear();
8951 }
Victor Stinner65170952011-11-22 22:16:17 +01008952 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008953 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008954}
8955#endif /* unsetenv */
8956
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008957PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008958"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008959Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008960
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008962posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008963{
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 int code;
8965 char *message;
8966 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8967 return NULL;
8968 message = strerror(code);
8969 if (message == NULL) {
8970 PyErr_SetString(PyExc_ValueError,
8971 "strerror() argument out of range");
8972 return NULL;
8973 }
Victor Stinner1b579672011-12-17 05:47:23 +01008974 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008975}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008976
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008977
Guido van Rossumc9641791998-08-04 15:26:23 +00008978#ifdef HAVE_SYS_WAIT_H
8979
Fred Drake106c1a02002-04-23 15:58:02 +00008980#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008981PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008982"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008983Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008984
8985static PyObject *
8986posix_WCOREDUMP(PyObject *self, PyObject *args)
8987{
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 WAIT_TYPE status;
8989 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008990
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8992 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008993
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008995}
8996#endif /* WCOREDUMP */
8997
8998#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008999PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009000"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009001Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009002job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009003
9004static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009005posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009006{
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 WAIT_TYPE status;
9008 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009009
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9011 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009012
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009014}
9015#endif /* WIFCONTINUED */
9016
Guido van Rossumc9641791998-08-04 15:26:23 +00009017#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009018PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009019"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009020Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009021
9022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009023posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009024{
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 WAIT_TYPE status;
9026 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009027
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9029 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009030
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009032}
9033#endif /* WIFSTOPPED */
9034
9035#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009036PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009037"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009038Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009039
9040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009041posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009042{
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 WAIT_TYPE status;
9044 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009045
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9047 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009048
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009050}
9051#endif /* WIFSIGNALED */
9052
9053#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009054PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009055"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009056Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009057system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009058
9059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009060posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009061{
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 WAIT_TYPE status;
9063 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009064
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9066 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009067
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009069}
9070#endif /* WIFEXITED */
9071
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009072#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009073PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009074"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009075Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009076
9077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009078posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009079{
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 WAIT_TYPE status;
9081 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009082
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9084 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009085
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009087}
9088#endif /* WEXITSTATUS */
9089
9090#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009091PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009092"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009093Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009094value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009095
9096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009097posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009098{
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 WAIT_TYPE status;
9100 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009101
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9103 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009104
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009106}
9107#endif /* WTERMSIG */
9108
9109#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009110PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009111"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009112Return the signal that stopped the process that provided\n\
9113the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009114
9115static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009116posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009117{
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 WAIT_TYPE status;
9119 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009120
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009123
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009125}
9126#endif /* WSTOPSIG */
9127
9128#endif /* HAVE_SYS_WAIT_H */
9129
9130
Thomas Wouters477c8d52006-05-27 19:21:47 +00009131#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009132#ifdef _SCO_DS
9133/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9134 needed definitions in sys/statvfs.h */
9135#define _SVID3
9136#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009137#include <sys/statvfs.h>
9138
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009139static PyObject*
9140_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9142 if (v == NULL)
9143 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009144
9145#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9147 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9148 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9149 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9150 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9151 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9152 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9153 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9154 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9155 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009156#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9158 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9159 PyStructSequence_SET_ITEM(v, 2,
9160 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9161 PyStructSequence_SET_ITEM(v, 3,
9162 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9163 PyStructSequence_SET_ITEM(v, 4,
9164 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9165 PyStructSequence_SET_ITEM(v, 5,
9166 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9167 PyStructSequence_SET_ITEM(v, 6,
9168 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9169 PyStructSequence_SET_ITEM(v, 7,
9170 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9171 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9172 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009173#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009174 if (PyErr_Occurred()) {
9175 Py_DECREF(v);
9176 return NULL;
9177 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009178
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009180}
9181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009182PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009183"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009184Perform an fstatvfs system call on the given fd.\n\
9185Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009186
9187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009188posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009189{
Victor Stinner8c62be82010-05-06 00:08:46 +00009190 int fd, res;
9191 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009192
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9194 return NULL;
9195 Py_BEGIN_ALLOW_THREADS
9196 res = fstatvfs(fd, &st);
9197 Py_END_ALLOW_THREADS
9198 if (res != 0)
9199 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009200
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009202}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009203#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009204
9205
Thomas Wouters477c8d52006-05-27 19:21:47 +00009206#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009207#include <sys/statvfs.h>
9208
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009209PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009210"statvfs(path)\n\n\
9211Perform a statvfs system call on the given path.\n\
9212\n\
9213path may always be specified as a string.\n\
9214On some platforms, path may also be specified as an open file descriptor.\n\
9215 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009216
9217static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009218posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009220 static char *keywords[] = {"path", NULL};
9221 path_t path;
9222 int result;
9223 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009225
Larry Hastings9cf065c2012-06-22 16:30:09 -07009226 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009227 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009228#ifdef HAVE_FSTATVFS
9229 path.allow_fd = 1;
9230#endif
9231 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9232 path_converter, &path
9233 ))
9234 return NULL;
9235
9236 Py_BEGIN_ALLOW_THREADS
9237#ifdef HAVE_FSTATVFS
9238 if (path.fd != -1) {
9239#ifdef __APPLE__
9240 /* handle weak-linking on Mac OS X 10.3 */
9241 if (fstatvfs == NULL) {
9242 fd_specified("statvfs", path.fd);
9243 goto exit;
9244 }
9245#endif
9246 result = fstatvfs(path.fd, &st);
9247 }
9248 else
9249#endif
9250 result = statvfs(path.narrow, &st);
9251 Py_END_ALLOW_THREADS
9252
9253 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009254 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009255 goto exit;
9256 }
9257
9258 return_value = _pystatvfs_fromstructstatvfs(st);
9259
9260exit:
9261 path_cleanup(&path);
9262 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009263}
9264#endif /* HAVE_STATVFS */
9265
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009266#ifdef MS_WINDOWS
9267PyDoc_STRVAR(win32__getdiskusage__doc__,
9268"_getdiskusage(path) -> (total, free)\n\n\
9269Return disk usage statistics about the given path as (total, free) tuple.");
9270
9271static PyObject *
9272win32__getdiskusage(PyObject *self, PyObject *args)
9273{
9274 BOOL retval;
9275 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009276 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009277
Victor Stinner6139c1b2011-11-09 22:14:14 +01009278 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009279 return NULL;
9280
9281 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009282 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009283 Py_END_ALLOW_THREADS
9284 if (retval == 0)
9285 return PyErr_SetFromWindowsErr(0);
9286
9287 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9288}
9289#endif
9290
9291
Fred Drakec9680921999-12-13 16:37:25 +00009292/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9293 * It maps strings representing configuration variable names to
9294 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009295 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009296 * rarely-used constants. There are three separate tables that use
9297 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009298 *
9299 * This code is always included, even if none of the interfaces that
9300 * need it are included. The #if hackery needed to avoid it would be
9301 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009302 */
9303struct constdef {
9304 char *name;
9305 long value;
9306};
9307
Fred Drake12c6e2d1999-12-14 21:25:03 +00009308static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009309conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009310 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009311{
Christian Heimes217cfd12007-12-02 14:31:20 +00009312 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009313 *valuep = PyLong_AS_LONG(arg);
9314 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009315 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009316 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009317 /* look up the value in the table using a binary search */
9318 size_t lo = 0;
9319 size_t mid;
9320 size_t hi = tablesize;
9321 int cmp;
9322 const char *confname;
9323 if (!PyUnicode_Check(arg)) {
9324 PyErr_SetString(PyExc_TypeError,
9325 "configuration names must be strings or integers");
9326 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009328 confname = _PyUnicode_AsString(arg);
9329 if (confname == NULL)
9330 return 0;
9331 while (lo < hi) {
9332 mid = (lo + hi) / 2;
9333 cmp = strcmp(confname, table[mid].name);
9334 if (cmp < 0)
9335 hi = mid;
9336 else if (cmp > 0)
9337 lo = mid + 1;
9338 else {
9339 *valuep = table[mid].value;
9340 return 1;
9341 }
9342 }
9343 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9344 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009346}
9347
9348
9349#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9350static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009351#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
Fred Drakec9680921999-12-13 16:37:25 +00009357#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009402#ifdef _PC_ACL_ENABLED
9403 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9404#endif
9405#ifdef _PC_MIN_HOLE_SIZE
9406 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9407#endif
9408#ifdef _PC_ALLOC_SIZE_MIN
9409 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9410#endif
9411#ifdef _PC_REC_INCR_XFER_SIZE
9412 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9413#endif
9414#ifdef _PC_REC_MAX_XFER_SIZE
9415 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9416#endif
9417#ifdef _PC_REC_MIN_XFER_SIZE
9418 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9419#endif
9420#ifdef _PC_REC_XFER_ALIGN
9421 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9422#endif
9423#ifdef _PC_SYMLINK_MAX
9424 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9425#endif
9426#ifdef _PC_XATTR_ENABLED
9427 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9428#endif
9429#ifdef _PC_XATTR_EXISTS
9430 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9431#endif
9432#ifdef _PC_TIMESTAMP_RESOLUTION
9433 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9434#endif
Fred Drakec9680921999-12-13 16:37:25 +00009435};
9436
Fred Drakec9680921999-12-13 16:37:25 +00009437static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009438conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009439{
9440 return conv_confname(arg, valuep, posix_constants_pathconf,
9441 sizeof(posix_constants_pathconf)
9442 / sizeof(struct constdef));
9443}
9444#endif
9445
9446#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009447PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009448"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009449Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009450If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009451
9452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009453posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009454{
9455 PyObject *result = NULL;
9456 int name, fd;
9457
Fred Drake12c6e2d1999-12-14 21:25:03 +00009458 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9459 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009460 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009461
Stefan Krah0e803b32010-11-26 16:16:47 +00009462 errno = 0;
9463 limit = fpathconf(fd, name);
9464 if (limit == -1 && errno != 0)
9465 posix_error();
9466 else
9467 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009468 }
9469 return result;
9470}
9471#endif
9472
9473
9474#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009475PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009476"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009477Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009478If there is no limit, return -1.\n\
9479On some platforms, path may also be specified as an open file descriptor.\n\
9480 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009481
9482static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009483posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009484{
Georg Brandl306336b2012-06-24 12:55:33 +02009485 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009486 PyObject *result = NULL;
9487 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009488 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009489
Georg Brandl306336b2012-06-24 12:55:33 +02009490 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009491 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009492#ifdef HAVE_FPATHCONF
9493 path.allow_fd = 1;
9494#endif
9495 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9496 path_converter, &path,
9497 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009499
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009501#ifdef HAVE_FPATHCONF
9502 if (path.fd != -1)
9503 limit = fpathconf(path.fd, name);
9504 else
9505#endif
9506 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 if (limit == -1 && errno != 0) {
9508 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009509 /* could be a path or name problem */
9510 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009511 else
Victor Stinner292c8352012-10-30 02:17:38 +01009512 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 }
9514 else
9515 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009516 }
Georg Brandl306336b2012-06-24 12:55:33 +02009517 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009518 return result;
9519}
9520#endif
9521
9522#ifdef HAVE_CONFSTR
9523static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009524#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009527#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009529#endif
9530#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009532#endif
Fred Draked86ed291999-12-15 15:34:33 +00009533#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
9536#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
9539#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
9542#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009544#endif
Fred Drakec9680921999-12-13 16:37:25 +00009545#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
Fred Draked86ed291999-12-15 15:34:33 +00009569#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009571#endif
Fred Drakec9680921999-12-13 16:37:25 +00009572#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
Fred Draked86ed291999-12-15 15:34:33 +00009575#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009577#endif
9578#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009580#endif
9581#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009583#endif
9584#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009586#endif
Fred Drakec9680921999-12-13 16:37:25 +00009587#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
Fred Draked86ed291999-12-15 15:34:33 +00009635#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009637#endif
9638#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009640#endif
9641#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009643#endif
9644#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009646#endif
9647#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009649#endif
9650#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
9653#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009655#endif
9656#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
9665#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
9668#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009670#endif
9671#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009673#endif
Fred Drakec9680921999-12-13 16:37:25 +00009674};
9675
9676static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009677conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009678{
9679 return conv_confname(arg, valuep, posix_constants_confstr,
9680 sizeof(posix_constants_confstr)
9681 / sizeof(struct constdef));
9682}
9683
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009684PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009685"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009686Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009687
9688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009689posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009690{
9691 PyObject *result = NULL;
9692 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009693 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009694 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009695
Victor Stinnercb043522010-09-10 23:49:04 +00009696 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9697 return NULL;
9698
9699 errno = 0;
9700 len = confstr(name, buffer, sizeof(buffer));
9701 if (len == 0) {
9702 if (errno) {
9703 posix_error();
9704 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009705 }
9706 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009707 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009708 }
9709 }
Victor Stinnercb043522010-09-10 23:49:04 +00009710
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009711 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009712 char *buf = PyMem_Malloc(len);
9713 if (buf == NULL)
9714 return PyErr_NoMemory();
9715 confstr(name, buf, len);
9716 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9717 PyMem_Free(buf);
9718 }
9719 else
9720 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009721 return result;
9722}
9723#endif
9724
9725
9726#ifdef HAVE_SYSCONF
9727static struct constdef posix_constants_sysconf[] = {
9728#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
Fred Draked86ed291999-12-15 15:34:33 +00009758#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
9761#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
Fred Draked86ed291999-12-15 15:34:33 +00009782#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
Fred Drakec9680921999-12-13 16:37:25 +00009785#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
Fred Draked86ed291999-12-15 15:34:33 +00009800#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
Fred Drakec9680921999-12-13 16:37:25 +00009803#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
Fred Draked86ed291999-12-15 15:34:33 +00009872#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009874#endif
Fred Drakec9680921999-12-13 16:37:25 +00009875#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
Fred Draked86ed291999-12-15 15:34:33 +00009884#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009886#endif
Fred Drakec9680921999-12-13 16:37:25 +00009887#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
Fred Draked86ed291999-12-15 15:34:33 +00009890#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
9893#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009895#endif
Fred Drakec9680921999-12-13 16:37:25 +00009896#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
Fred Draked86ed291999-12-15 15:34:33 +00009908#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
Fred Drakec9680921999-12-13 16:37:25 +00009911#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
Fred Draked86ed291999-12-15 15:34:33 +00009932#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009934#endif
Fred Drakec9680921999-12-13 16:37:25 +00009935#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
Fred Draked86ed291999-12-15 15:34:33 +00009941#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009943#endif
Fred Drakec9680921999-12-13 16:37:25 +00009944#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
Fred Draked86ed291999-12-15 15:34:33 +00009971#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
9974#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
Fred Drakec9680921999-12-13 16:37:25 +00009977#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
Fred Draked86ed291999-12-15 15:34:33 +000010082#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010084#endif
Fred Drakec9680921999-12-13 16:37:25 +000010085#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220};
10221
10222static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010223conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010224{
10225 return conv_confname(arg, valuep, posix_constants_sysconf,
10226 sizeof(posix_constants_sysconf)
10227 / sizeof(struct constdef));
10228}
10229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010230PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010231"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010232Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010233
10234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010235posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010236{
10237 PyObject *result = NULL;
10238 int name;
10239
10240 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010241 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010242
10243 errno = 0;
10244 value = sysconf(name);
10245 if (value == -1 && errno != 0)
10246 posix_error();
10247 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010248 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010249 }
10250 return result;
10251}
10252#endif
10253
10254
Fred Drakebec628d1999-12-15 18:31:10 +000010255/* This code is used to ensure that the tables of configuration value names
10256 * are in sorted order as required by conv_confname(), and also to build the
10257 * the exported dictionaries that are used to publish information about the
10258 * names available on the host platform.
10259 *
10260 * Sorting the table at runtime ensures that the table is properly ordered
10261 * when used, even for platforms we're not able to test on. It also makes
10262 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010263 */
Fred Drakebec628d1999-12-15 18:31:10 +000010264
10265static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010266cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010267{
10268 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010270 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010272
10273 return strcmp(c1->name, c2->name);
10274}
10275
10276static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010277setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010279{
Fred Drakebec628d1999-12-15 18:31:10 +000010280 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010281 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010282
10283 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10284 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010285 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010287
Barry Warsaw3155db32000-04-13 15:20:40 +000010288 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 PyObject *o = PyLong_FromLong(table[i].value);
10290 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10291 Py_XDECREF(o);
10292 Py_DECREF(d);
10293 return -1;
10294 }
10295 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010296 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010297 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010298}
10299
Fred Drakebec628d1999-12-15 18:31:10 +000010300/* Return -1 on failure, 0 on success. */
10301static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010302setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010303{
10304#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010305 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010306 sizeof(posix_constants_pathconf)
10307 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010308 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010309 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010310#endif
10311#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010312 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010313 sizeof(posix_constants_confstr)
10314 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010315 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010316 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010317#endif
10318#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010319 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010320 sizeof(posix_constants_sysconf)
10321 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010322 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010323 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010324#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010325 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010326}
Fred Draked86ed291999-12-15 15:34:33 +000010327
10328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010329PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010330"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010331Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010332in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010333
10334static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010335posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010336{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010337 abort();
10338 /*NOTREACHED*/
10339 Py_FatalError("abort() called from Python code didn't abort!");
10340 return NULL;
10341}
Fred Drakebec628d1999-12-15 18:31:10 +000010342
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010343#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010344PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010345"startfile(filepath [, operation]) - Start a file with its associated\n\
10346application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010347\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010348When \"operation\" is not specified or \"open\", this acts like\n\
10349double-clicking the file in Explorer, or giving the file name as an\n\
10350argument to the DOS \"start\" command: the file is opened with whatever\n\
10351application (if any) its extension is associated.\n\
10352When another \"operation\" is given, it specifies what should be done with\n\
10353the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010354\n\
10355startfile returns as soon as the associated application is launched.\n\
10356There is no option to wait for the application to close, and no way\n\
10357to retrieve the application's exit status.\n\
10358\n\
10359The filepath is relative to the current directory. If you want to use\n\
10360an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010361the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010362
10363static PyObject *
10364win32_startfile(PyObject *self, PyObject *args)
10365{
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 PyObject *ofilepath;
10367 char *filepath;
10368 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010369 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010371
Victor Stinnereb5657a2011-09-30 01:44:27 +020010372 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 if (!PyArg_ParseTuple(args, "U|s:startfile",
10374 &unipath, &operation)) {
10375 PyErr_Clear();
10376 goto normal;
10377 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010378
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010380 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010382 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 PyErr_Clear();
10384 operation = NULL;
10385 goto normal;
10386 }
10387 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010388
Victor Stinnereb5657a2011-09-30 01:44:27 +020010389 wpath = PyUnicode_AsUnicode(unipath);
10390 if (wpath == NULL)
10391 goto normal;
10392 if (uoperation) {
10393 woperation = PyUnicode_AsUnicode(uoperation);
10394 if (woperation == NULL)
10395 goto normal;
10396 }
10397 else
10398 woperation = NULL;
10399
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010401 rc = ShellExecuteW((HWND)0, woperation, wpath,
10402 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 Py_END_ALLOW_THREADS
10404
Victor Stinnereb5657a2011-09-30 01:44:27 +020010405 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010407 win32_error_object("startfile", unipath);
10408 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 }
10410 Py_INCREF(Py_None);
10411 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010412
10413normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10415 PyUnicode_FSConverter, &ofilepath,
10416 &operation))
10417 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010418 if (win32_warn_bytes_api()) {
10419 Py_DECREF(ofilepath);
10420 return NULL;
10421 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 filepath = PyBytes_AsString(ofilepath);
10423 Py_BEGIN_ALLOW_THREADS
10424 rc = ShellExecute((HWND)0, operation, filepath,
10425 NULL, NULL, SW_SHOWNORMAL);
10426 Py_END_ALLOW_THREADS
10427 if (rc <= (HINSTANCE)32) {
10428 PyObject *errval = win32_error("startfile", filepath);
10429 Py_DECREF(ofilepath);
10430 return errval;
10431 }
10432 Py_DECREF(ofilepath);
10433 Py_INCREF(Py_None);
10434 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010435}
10436#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010437
Martin v. Löwis438b5342002-12-27 10:16:42 +000010438#ifdef HAVE_GETLOADAVG
10439PyDoc_STRVAR(posix_getloadavg__doc__,
10440"getloadavg() -> (float, float, float)\n\n\
10441Return the number of processes in the system run queue averaged over\n\
10442the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10443was unobtainable");
10444
10445static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010446posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010447{
10448 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010449 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010450 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10451 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010452 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010453 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010454}
10455#endif
10456
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010457PyDoc_STRVAR(device_encoding__doc__,
10458"device_encoding(fd) -> str\n\n\
10459Return a string describing the encoding of the device\n\
10460if the output is a terminal; else return None.");
10461
10462static PyObject *
10463device_encoding(PyObject *self, PyObject *args)
10464{
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010466
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10468 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010469
10470 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010471}
10472
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010473#ifdef HAVE_SETRESUID
10474PyDoc_STRVAR(posix_setresuid__doc__,
10475"setresuid(ruid, euid, suid)\n\n\
10476Set the current process's real, effective, and saved user ids.");
10477
10478static PyObject*
10479posix_setresuid (PyObject *self, PyObject *args)
10480{
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010482 uid_t ruid, euid, suid;
10483 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10484 _Py_Uid_Converter, &ruid,
10485 _Py_Uid_Converter, &euid,
10486 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 return NULL;
10488 if (setresuid(ruid, euid, suid) < 0)
10489 return posix_error();
10490 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010491}
10492#endif
10493
10494#ifdef HAVE_SETRESGID
10495PyDoc_STRVAR(posix_setresgid__doc__,
10496"setresgid(rgid, egid, sgid)\n\n\
10497Set the current process's real, effective, and saved group ids.");
10498
10499static PyObject*
10500posix_setresgid (PyObject *self, PyObject *args)
10501{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010502 gid_t rgid, egid, sgid;
10503 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10504 _Py_Gid_Converter, &rgid,
10505 _Py_Gid_Converter, &egid,
10506 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 return NULL;
10508 if (setresgid(rgid, egid, sgid) < 0)
10509 return posix_error();
10510 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010511}
10512#endif
10513
10514#ifdef HAVE_GETRESUID
10515PyDoc_STRVAR(posix_getresuid__doc__,
10516"getresuid() -> (ruid, euid, suid)\n\n\
10517Get tuple of the current process's real, effective, and saved user ids.");
10518
10519static PyObject*
10520posix_getresuid (PyObject *self, PyObject *noargs)
10521{
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 if (getresuid(&ruid, &euid, &suid) < 0)
10524 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010525 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10526 _PyLong_FromUid(euid),
10527 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010528}
10529#endif
10530
10531#ifdef HAVE_GETRESGID
10532PyDoc_STRVAR(posix_getresgid__doc__,
10533"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010534Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010535
10536static PyObject*
10537posix_getresgid (PyObject *self, PyObject *noargs)
10538{
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 if (getresgid(&rgid, &egid, &sgid) < 0)
10541 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010542 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10543 _PyLong_FromGid(egid),
10544 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010545}
10546#endif
10547
Benjamin Peterson9428d532011-09-14 11:45:52 -040010548#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010549
Benjamin Peterson799bd802011-08-31 22:15:17 -040010550PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010551"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10552Return the value of extended attribute attribute on path.\n\
10553\n\
10554path may be either a string or an open file descriptor.\n\
10555If follow_symlinks is False, and the last element of the path is a symbolic\n\
10556 link, getxattr will examine the symbolic link itself instead of the file\n\
10557 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010558
10559static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010560posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562 path_t path;
10563 path_t attribute;
10564 int follow_symlinks = 1;
10565 PyObject *buffer = NULL;
10566 int i;
10567 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568
Larry Hastings9cf065c2012-06-22 16:30:09 -070010569 memset(&path, 0, sizeof(path));
10570 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010571 path.function_name = "getxattr";
10572 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 path.allow_fd = 1;
10574 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10575 path_converter, &path,
10576 path_converter, &attribute,
10577 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010578 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010579
Larry Hastings9cf065c2012-06-22 16:30:09 -070010580 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10581 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings9cf065c2012-06-22 16:30:09 -070010583 for (i = 0; ; i++) {
10584 void *ptr;
10585 ssize_t result;
10586 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10587 Py_ssize_t buffer_size = buffer_sizes[i];
10588 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010589 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010590 goto exit;
10591 }
10592 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10593 if (!buffer)
10594 goto exit;
10595 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010596
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 Py_BEGIN_ALLOW_THREADS;
10598 if (path.fd >= 0)
10599 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10600 else if (follow_symlinks)
10601 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10602 else
10603 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10604 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010605
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 if (result < 0) {
10607 Py_DECREF(buffer);
10608 buffer = NULL;
10609 if (errno == ERANGE)
10610 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010611 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 goto exit;
10613 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010614
Larry Hastings9cf065c2012-06-22 16:30:09 -070010615 if (result != buffer_size) {
10616 /* Can only shrink. */
10617 _PyBytes_Resize(&buffer, result);
10618 }
10619 break;
10620 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010621
Larry Hastings9cf065c2012-06-22 16:30:09 -070010622exit:
10623 path_cleanup(&path);
10624 path_cleanup(&attribute);
10625 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626}
10627
10628PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10630Set extended attribute attribute on path to value.\n\
10631path may be either a string or an open file descriptor.\n\
10632If follow_symlinks is False, and the last element of the path is a symbolic\n\
10633 link, setxattr will modify the symbolic link itself instead of the file\n\
10634 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635
10636static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010637posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010638{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010639 path_t path;
10640 path_t attribute;
10641 Py_buffer value;
10642 int flags = 0;
10643 int follow_symlinks = 1;
10644 int result;
10645 PyObject *return_value = NULL;
10646 static char *keywords[] = {"path", "attribute", "value",
10647 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648
Larry Hastings9cf065c2012-06-22 16:30:09 -070010649 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010650 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 path.allow_fd = 1;
10652 memset(&attribute, 0, sizeof(attribute));
10653 memset(&value, 0, sizeof(value));
10654 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10655 keywords,
10656 path_converter, &path,
10657 path_converter, &attribute,
10658 &value, &flags,
10659 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010660 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661
10662 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10663 goto exit;
10664
Benjamin Peterson799bd802011-08-31 22:15:17 -040010665 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 if (path.fd > -1)
10667 result = fsetxattr(path.fd, attribute.narrow,
10668 value.buf, value.len, flags);
10669 else if (follow_symlinks)
10670 result = setxattr(path.narrow, attribute.narrow,
10671 value.buf, value.len, flags);
10672 else
10673 result = lsetxattr(path.narrow, attribute.narrow,
10674 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010676
Larry Hastings9cf065c2012-06-22 16:30:09 -070010677 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010678 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679 goto exit;
10680 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010681
Larry Hastings9cf065c2012-06-22 16:30:09 -070010682 return_value = Py_None;
10683 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010684
Larry Hastings9cf065c2012-06-22 16:30:09 -070010685exit:
10686 path_cleanup(&path);
10687 path_cleanup(&attribute);
10688 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010689
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691}
10692
10693PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010694"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10695Remove extended attribute attribute on path.\n\
10696path may be either a string or an open file descriptor.\n\
10697If follow_symlinks is False, and the last element of the path is a symbolic\n\
10698 link, removexattr will modify the symbolic link itself instead of the file\n\
10699 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010700
10701static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010702posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010703{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010704 path_t path;
10705 path_t attribute;
10706 int follow_symlinks = 1;
10707 int result;
10708 PyObject *return_value = NULL;
10709 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010710
Larry Hastings9cf065c2012-06-22 16:30:09 -070010711 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010712 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010713 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010714 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 path.allow_fd = 1;
10716 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10717 keywords,
10718 path_converter, &path,
10719 path_converter, &attribute,
10720 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010722
10723 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10724 goto exit;
10725
Benjamin Peterson799bd802011-08-31 22:15:17 -040010726 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727 if (path.fd > -1)
10728 result = fremovexattr(path.fd, attribute.narrow);
10729 else if (follow_symlinks)
10730 result = removexattr(path.narrow, attribute.narrow);
10731 else
10732 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010733 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010734
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010736 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010737 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010738 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010739
Larry Hastings9cf065c2012-06-22 16:30:09 -070010740 return_value = Py_None;
10741 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743exit:
10744 path_cleanup(&path);
10745 path_cleanup(&attribute);
10746
10747 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010748}
10749
10750PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751"listxattr(path='.', *, follow_symlinks=True)\n\n\
10752Return a list of extended attributes on path.\n\
10753\n\
10754path may be either None, a string, or an open file descriptor.\n\
10755if path is None, listxattr will examine the current directory.\n\
10756If follow_symlinks is False, and the last element of the path is a symbolic\n\
10757 link, listxattr will examine the symbolic link itself instead of the file\n\
10758 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010759
10760static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 path_t path;
10764 int follow_symlinks = 1;
10765 Py_ssize_t i;
10766 PyObject *result = NULL;
10767 char *buffer = NULL;
10768 char *name;
10769 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010770
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010772 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 path.allow_fd = 1;
10774 path.fd = -1;
10775 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10776 path_converter, &path,
10777 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010778 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010779
Larry Hastings9cf065c2012-06-22 16:30:09 -070010780 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10781 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 name = path.narrow ? path.narrow : ".";
10784 for (i = 0; ; i++) {
10785 char *start, *trace, *end;
10786 ssize_t length;
10787 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10788 Py_ssize_t buffer_size = buffer_sizes[i];
10789 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010790 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010791 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 break;
10793 }
10794 buffer = PyMem_MALLOC(buffer_size);
10795 if (!buffer) {
10796 PyErr_NoMemory();
10797 break;
10798 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 Py_BEGIN_ALLOW_THREADS;
10801 if (path.fd > -1)
10802 length = flistxattr(path.fd, buffer, buffer_size);
10803 else if (follow_symlinks)
10804 length = listxattr(name, buffer, buffer_size);
10805 else
10806 length = llistxattr(name, buffer, buffer_size);
10807 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010808
Larry Hastings9cf065c2012-06-22 16:30:09 -070010809 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010810 if (errno == ERANGE) {
10811 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010812 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010814 }
Victor Stinner292c8352012-10-30 02:17:38 +010010815 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010816 break;
10817 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 result = PyList_New(0);
10820 if (!result) {
10821 goto exit;
10822 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 end = buffer + length;
10825 for (trace = start = buffer; trace != end; trace++) {
10826 if (!*trace) {
10827 int error;
10828 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10829 trace - start);
10830 if (!attribute) {
10831 Py_DECREF(result);
10832 result = NULL;
10833 goto exit;
10834 }
10835 error = PyList_Append(result, attribute);
10836 Py_DECREF(attribute);
10837 if (error) {
10838 Py_DECREF(result);
10839 result = NULL;
10840 goto exit;
10841 }
10842 start = trace + 1;
10843 }
10844 }
10845 break;
10846 }
10847exit:
10848 path_cleanup(&path);
10849 if (buffer)
10850 PyMem_FREE(buffer);
10851 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010852}
10853
Benjamin Peterson9428d532011-09-14 11:45:52 -040010854#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010856
Georg Brandl2fb477c2012-02-21 00:33:36 +010010857PyDoc_STRVAR(posix_urandom__doc__,
10858"urandom(n) -> str\n\n\
10859Return n random bytes suitable for cryptographic use.");
10860
10861static PyObject *
10862posix_urandom(PyObject *self, PyObject *args)
10863{
10864 Py_ssize_t size;
10865 PyObject *result;
10866 int ret;
10867
10868 /* Read arguments */
10869 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10870 return NULL;
10871 if (size < 0)
10872 return PyErr_Format(PyExc_ValueError,
10873 "negative argument not allowed");
10874 result = PyBytes_FromStringAndSize(NULL, size);
10875 if (result == NULL)
10876 return NULL;
10877
10878 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10879 PyBytes_GET_SIZE(result));
10880 if (ret == -1) {
10881 Py_DECREF(result);
10882 return NULL;
10883 }
10884 return result;
10885}
10886
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010887/* Terminal size querying */
10888
10889static PyTypeObject TerminalSizeType;
10890
10891PyDoc_STRVAR(TerminalSize_docstring,
10892 "A tuple of (columns, lines) for holding terminal window size");
10893
10894static PyStructSequence_Field TerminalSize_fields[] = {
10895 {"columns", "width of the terminal window in characters"},
10896 {"lines", "height of the terminal window in characters"},
10897 {NULL, NULL}
10898};
10899
10900static PyStructSequence_Desc TerminalSize_desc = {
10901 "os.terminal_size",
10902 TerminalSize_docstring,
10903 TerminalSize_fields,
10904 2,
10905};
10906
10907#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10908PyDoc_STRVAR(termsize__doc__,
10909 "Return the size of the terminal window as (columns, lines).\n" \
10910 "\n" \
10911 "The optional argument fd (default standard output) specifies\n" \
10912 "which file descriptor should be queried.\n" \
10913 "\n" \
10914 "If the file descriptor is not connected to a terminal, an OSError\n" \
10915 "is thrown.\n" \
10916 "\n" \
10917 "This function will only be defined if an implementation is\n" \
10918 "available for this system.\n" \
10919 "\n" \
10920 "shutil.get_terminal_size is the high-level function which should \n" \
10921 "normally be used, os.get_terminal_size is the low-level implementation.");
10922
10923static PyObject*
10924get_terminal_size(PyObject *self, PyObject *args)
10925{
10926 int columns, lines;
10927 PyObject *termsize;
10928
10929 int fd = fileno(stdout);
10930 /* Under some conditions stdout may not be connected and
10931 * fileno(stdout) may point to an invalid file descriptor. For example
10932 * GUI apps don't have valid standard streams by default.
10933 *
10934 * If this happens, and the optional fd argument is not present,
10935 * the ioctl below will fail returning EBADF. This is what we want.
10936 */
10937
10938 if (!PyArg_ParseTuple(args, "|i", &fd))
10939 return NULL;
10940
10941#ifdef TERMSIZE_USE_IOCTL
10942 {
10943 struct winsize w;
10944 if (ioctl(fd, TIOCGWINSZ, &w))
10945 return PyErr_SetFromErrno(PyExc_OSError);
10946 columns = w.ws_col;
10947 lines = w.ws_row;
10948 }
10949#endif /* TERMSIZE_USE_IOCTL */
10950
10951#ifdef TERMSIZE_USE_CONIO
10952 {
10953 DWORD nhandle;
10954 HANDLE handle;
10955 CONSOLE_SCREEN_BUFFER_INFO csbi;
10956 switch (fd) {
10957 case 0: nhandle = STD_INPUT_HANDLE;
10958 break;
10959 case 1: nhandle = STD_OUTPUT_HANDLE;
10960 break;
10961 case 2: nhandle = STD_ERROR_HANDLE;
10962 break;
10963 default:
10964 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10965 }
10966 handle = GetStdHandle(nhandle);
10967 if (handle == NULL)
10968 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10969 if (handle == INVALID_HANDLE_VALUE)
10970 return PyErr_SetFromWindowsErr(0);
10971
10972 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10973 return PyErr_SetFromWindowsErr(0);
10974
10975 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10976 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10977 }
10978#endif /* TERMSIZE_USE_CONIO */
10979
10980 termsize = PyStructSequence_New(&TerminalSizeType);
10981 if (termsize == NULL)
10982 return NULL;
10983 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10984 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10985 if (PyErr_Occurred()) {
10986 Py_DECREF(termsize);
10987 return NULL;
10988 }
10989 return termsize;
10990}
10991#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10992
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010993PyDoc_STRVAR(posix_cpu_count__doc__,
10994"cpu_count() -> integer\n\n\
10995Return the number of CPUs in the system, or None if this value cannot be\n\
10996established.");
10997
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010998static PyObject *
10999posix_cpu_count(PyObject *self)
11000{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011001 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011002#ifdef MS_WINDOWS
11003 SYSTEM_INFO sysinfo;
11004 GetSystemInfo(&sysinfo);
11005 ncpu = sysinfo.dwNumberOfProcessors;
11006#elif defined(__hpux)
11007 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11008#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11009 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011010#elif defined(__DragonFly__) || \
11011 defined(__OpenBSD__) || \
11012 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011013 defined(__NetBSD__) || \
11014 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011015 int mib[2];
11016 size_t len = sizeof(ncpu);
11017 mib[0] = CTL_HW;
11018 mib[1] = HW_NCPU;
11019 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11020 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011021#endif
11022 if (ncpu >= 1)
11023 return PyLong_FromLong(ncpu);
11024 else
11025 Py_RETURN_NONE;
11026}
11027
Victor Stinnerdaf45552013-08-28 00:53:59 +020011028PyDoc_STRVAR(get_inheritable__doc__,
11029 "get_inheritable(fd) -> bool\n" \
11030 "\n" \
11031 "Get the close-on-exe flag of the specified file descriptor.");
11032
11033static PyObject*
11034posix_get_inheritable(PyObject *self, PyObject *args)
11035{
11036 int fd;
11037 int inheritable;
11038
11039 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11040 return NULL;
11041
11042 if (!_PyVerify_fd(fd))
11043 return posix_error();
11044
11045 inheritable = _Py_get_inheritable(fd);
11046 if (inheritable < 0)
11047 return NULL;
11048 return PyBool_FromLong(inheritable);
11049}
11050
11051PyDoc_STRVAR(set_inheritable__doc__,
11052 "set_inheritable(fd, inheritable)\n" \
11053 "\n" \
11054 "Set the inheritable flag of the specified file descriptor.");
11055
11056static PyObject*
11057posix_set_inheritable(PyObject *self, PyObject *args)
11058{
11059 int fd, inheritable;
11060
11061 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11062 return NULL;
11063
11064 if (!_PyVerify_fd(fd))
11065 return posix_error();
11066
11067 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11068 return NULL;
11069 Py_RETURN_NONE;
11070}
11071
11072
11073#ifdef MS_WINDOWS
11074PyDoc_STRVAR(get_handle_inheritable__doc__,
11075 "get_handle_inheritable(fd) -> bool\n" \
11076 "\n" \
11077 "Get the close-on-exe flag of the specified file descriptor.");
11078
11079static PyObject*
11080posix_get_handle_inheritable(PyObject *self, PyObject *args)
11081{
11082 Py_intptr_t handle;
11083 DWORD flags;
11084
11085 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11086 return NULL;
11087
11088 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11089 PyErr_SetFromWindowsErr(0);
11090 return NULL;
11091 }
11092
11093 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11094}
11095
11096PyDoc_STRVAR(set_handle_inheritable__doc__,
11097 "set_handle_inheritable(fd, inheritable)\n" \
11098 "\n" \
11099 "Set the inheritable flag of the specified handle.");
11100
11101static PyObject*
11102posix_set_handle_inheritable(PyObject *self, PyObject *args)
11103{
11104 int inheritable = 1;
11105 Py_intptr_t handle;
11106 DWORD flags;
11107
11108 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11109 &handle, &inheritable))
11110 return NULL;
11111
11112 if (inheritable)
11113 flags = HANDLE_FLAG_INHERIT;
11114 else
11115 flags = 0;
11116 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11117 PyErr_SetFromWindowsErr(0);
11118 return NULL;
11119 }
11120 Py_RETURN_NONE;
11121}
11122#endif /* MS_WINDOWS */
11123
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011124
Larry Hastings31826802013-10-19 00:09:25 -070011125
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011126static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011127
11128 OS_STAT_METHODDEF
11129 OS_ACCESS_METHODDEF
11130 OS_TTYNAME_METHODDEF
11131
Larry Hastings9cf065c2012-06-22 16:30:09 -070011132 {"chdir", (PyCFunction)posix_chdir,
11133 METH_VARARGS | METH_KEYWORDS,
11134 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011135#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011136 {"chflags", (PyCFunction)posix_chflags,
11137 METH_VARARGS | METH_KEYWORDS,
11138 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011139#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011140 {"chmod", (PyCFunction)posix_chmod,
11141 METH_VARARGS | METH_KEYWORDS,
11142 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011143#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011145#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011146#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011147 {"chown", (PyCFunction)posix_chown,
11148 METH_VARARGS | METH_KEYWORDS,
11149 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011150#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011151#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011153#endif /* HAVE_LCHMOD */
11154#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011156#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011157#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011159#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011160#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011162#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011163#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011165#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011166#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011168#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11170 METH_NOARGS, posix_getcwd__doc__},
11171 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11172 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011173#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11174 {"link", (PyCFunction)posix_link,
11175 METH_VARARGS | METH_KEYWORDS,
11176 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011177#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011178 {"listdir", (PyCFunction)posix_listdir,
11179 METH_VARARGS | METH_KEYWORDS,
11180 posix_listdir__doc__},
11181 {"lstat", (PyCFunction)posix_lstat,
11182 METH_VARARGS | METH_KEYWORDS,
11183 posix_lstat__doc__},
11184 {"mkdir", (PyCFunction)posix_mkdir,
11185 METH_VARARGS | METH_KEYWORDS,
11186 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011187#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011189#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011190#ifdef HAVE_GETPRIORITY
11191 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11192#endif /* HAVE_GETPRIORITY */
11193#ifdef HAVE_SETPRIORITY
11194 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11195#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011196#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011197 {"readlink", (PyCFunction)posix_readlink,
11198 METH_VARARGS | METH_KEYWORDS,
11199 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011200#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011201#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011202 {"readlink", (PyCFunction)win_readlink,
11203 METH_VARARGS | METH_KEYWORDS,
11204 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011205#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011206 {"rename", (PyCFunction)posix_rename,
11207 METH_VARARGS | METH_KEYWORDS,
11208 posix_rename__doc__},
11209 {"replace", (PyCFunction)posix_replace,
11210 METH_VARARGS | METH_KEYWORDS,
11211 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011212 {"rmdir", (PyCFunction)posix_rmdir,
11213 METH_VARARGS | METH_KEYWORDS,
11214 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011216#if defined(HAVE_SYMLINK)
11217 {"symlink", (PyCFunction)posix_symlink,
11218 METH_VARARGS | METH_KEYWORDS,
11219 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011220#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011221#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011223#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011225#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011227#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011228 {"unlink", (PyCFunction)posix_unlink,
11229 METH_VARARGS | METH_KEYWORDS,
11230 posix_unlink__doc__},
11231 {"remove", (PyCFunction)posix_unlink,
11232 METH_VARARGS | METH_KEYWORDS,
11233 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011234 {"utime", (PyCFunction)posix_utime,
11235 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011236#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011238#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011240#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011242 {"execve", (PyCFunction)posix_execve,
11243 METH_VARARGS | METH_KEYWORDS,
11244 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011245#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011246#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11248 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011249#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011250#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011252#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011253#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011255#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011256#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011257#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011258 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11259 {"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 +020011260#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011261#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011262 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011263#endif
11264#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011265 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011266#endif
11267#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011268 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011269#endif
11270#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011271 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011272#endif
11273#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011274 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011275#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011276 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011277#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011278 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11279 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11280#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011281#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011282#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011284#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011285#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011287#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011288#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011290#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011291#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011293#endif /* HAVE_GETEUID */
11294#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011296#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011297#ifdef HAVE_GETGROUPLIST
11298 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11299#endif
Fred Drakec9680921999-12-13 16:37:25 +000011300#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011304#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011306#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011307#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011309#endif /* HAVE_GETPPID */
11310#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011312#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011313#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011315#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011316#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011318#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011319#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011321#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011322#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011324#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011325#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11327 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011328#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011329#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011331#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011332#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011334#endif /* HAVE_SETEUID */
11335#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011337#endif /* HAVE_SETEGID */
11338#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011340#endif /* HAVE_SETREUID */
11341#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011343#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011344#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011346#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011347#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011349#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011350#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011352#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011353#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011355#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011356#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011358#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011359#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011361#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011362#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011363 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011364#endif /* HAVE_WAIT3 */
11365#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011366 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011367#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011368#if defined(HAVE_WAITID) && !defined(__APPLE__)
11369 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11370#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011371#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011373#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011374#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011376#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011377#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011379#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011380#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011382#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011383#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011385#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011386#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011388#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011389 {"open", (PyCFunction)posix_open,\
11390 METH_VARARGS | METH_KEYWORDS,
11391 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11393 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11394 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11395 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011396 {"dup2", (PyCFunction)posix_dup2,
11397 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011398#ifdef HAVE_LOCKF
11399 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11400#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11402 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011403#ifdef HAVE_READV
11404 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11405#endif
11406#ifdef HAVE_PREAD
11407 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11408#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011410#ifdef HAVE_WRITEV
11411 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11412#endif
11413#ifdef HAVE_PWRITE
11414 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11415#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011416#ifdef HAVE_SENDFILE
11417 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11418 posix_sendfile__doc__},
11419#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011420 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011422#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011424#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011425#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011426 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011427#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011428#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011429 {"mkfifo", (PyCFunction)posix_mkfifo,
11430 METH_VARARGS | METH_KEYWORDS,
11431 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011432#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011433#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011434 {"mknod", (PyCFunction)posix_mknod,
11435 METH_VARARGS | METH_KEYWORDS,
11436 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011437#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011438#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11440 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11441 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011442#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011443#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011445#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011446#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011447 {"truncate", (PyCFunction)posix_truncate,
11448 METH_VARARGS | METH_KEYWORDS,
11449 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011450#endif
11451#ifdef HAVE_POSIX_FALLOCATE
11452 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11453#endif
11454#ifdef HAVE_POSIX_FADVISE
11455 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11456#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011457#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011459#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011460#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011462#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011464#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011466#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011467#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011469#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011470#ifdef HAVE_SYNC
11471 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11472#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011473#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011475#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011476#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011477#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011479#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011480#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011482#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011483#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011485#endif /* WIFSTOPPED */
11486#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011488#endif /* WIFSIGNALED */
11489#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011491#endif /* WIFEXITED */
11492#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011494#endif /* WEXITSTATUS */
11495#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011497#endif /* WTERMSIG */
11498#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011500#endif /* WSTOPSIG */
11501#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011502#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011504#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011505#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011506 {"statvfs", (PyCFunction)posix_statvfs,
11507 METH_VARARGS | METH_KEYWORDS,
11508 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011509#endif
Fred Drakec9680921999-12-13 16:37:25 +000011510#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011512#endif
11513#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011515#endif
11516#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011517 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011518#endif
11519#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011520 {"pathconf", (PyCFunction)posix_pathconf,
11521 METH_VARARGS | METH_KEYWORDS,
11522 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011525#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011527 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011528 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011529 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011530 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011531#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011532#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011534#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011535 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011536#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011538#endif
11539#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011541#endif
11542#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011544#endif
11545#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011547#endif
11548
Benjamin Peterson9428d532011-09-14 11:45:52 -040011549#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011550 {"setxattr", (PyCFunction)posix_setxattr,
11551 METH_VARARGS | METH_KEYWORDS,
11552 posix_setxattr__doc__},
11553 {"getxattr", (PyCFunction)posix_getxattr,
11554 METH_VARARGS | METH_KEYWORDS,
11555 posix_getxattr__doc__},
11556 {"removexattr", (PyCFunction)posix_removexattr,
11557 METH_VARARGS | METH_KEYWORDS,
11558 posix_removexattr__doc__},
11559 {"listxattr", (PyCFunction)posix_listxattr,
11560 METH_VARARGS | METH_KEYWORDS,
11561 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011562#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011563#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11564 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11565#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011566 {"cpu_count", (PyCFunction)posix_cpu_count,
11567 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011568 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11569 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11570#ifdef MS_WINDOWS
11571 {"get_handle_inheritable", posix_get_handle_inheritable,
11572 METH_VARARGS, get_handle_inheritable__doc__},
11573 {"set_handle_inheritable", posix_set_handle_inheritable,
11574 METH_VARARGS, set_handle_inheritable__doc__},
11575#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011577};
11578
11579
Brian Curtin52173d42010-12-02 18:29:18 +000011580#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011581static int
Brian Curtin52173d42010-12-02 18:29:18 +000011582enable_symlink()
11583{
11584 HANDLE tok;
11585 TOKEN_PRIVILEGES tok_priv;
11586 LUID luid;
11587 int meth_idx = 0;
11588
11589 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011590 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011591
11592 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011593 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011594
11595 tok_priv.PrivilegeCount = 1;
11596 tok_priv.Privileges[0].Luid = luid;
11597 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11598
11599 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11600 sizeof(TOKEN_PRIVILEGES),
11601 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011602 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011603
Brian Curtin3b4499c2010-12-28 14:31:47 +000011604 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11605 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011606}
11607#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11608
Barry Warsaw4a342091996-12-19 23:50:02 +000011609static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011610all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011611{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011612#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011613 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011614#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011615#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011616 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011617#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011618#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011619 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011620#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011621#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011622 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011623#endif
Fred Drakec9680921999-12-13 16:37:25 +000011624#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011625 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011626#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011627#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011628 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011629#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011630#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011631 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011632#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011633#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011634 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011635#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011636#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011637 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011638#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011639#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011640 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011641#endif
11642#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011643 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011644#endif
11645#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011646 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011647#endif
11648#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011649 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011650#endif
11651#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011652 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011653#endif
11654#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011655 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011656#endif
11657#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011658 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011659#endif
11660#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011661 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011662#endif
11663#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011664 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011665#endif
11666#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011667 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011668#endif
11669#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011670 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011671#endif
11672#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011673 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011674#endif
11675#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011676 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011677#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011678#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011679 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011680#endif
11681#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011682 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011683#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011684#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011685 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011686#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011687#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011688 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011689#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011690#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011691 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011692#endif
11693#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011694 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011695#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011696#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011697 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011698#endif
11699#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011701#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011702#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011704#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011705#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011707#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011708#ifdef O_TMPFILE
11709 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11710#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011711#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011712 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011713#endif
11714#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011715 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011716#endif
11717#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011718 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011719#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011720#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011722#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011723#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011724 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011725#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011726
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011727
Jesus Cea94363612012-06-22 18:32:07 +020011728#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011729 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011730#endif
11731#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011732 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011733#endif
11734
Tim Peters5aa91602002-01-30 05:46:57 +000011735/* MS Windows */
11736#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011738 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011739#endif
11740#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011741 /* Optimize for short life (keep in memory). */
11742 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011743 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011744#endif
11745#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011747 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011748#endif
11749#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011750 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011752#endif
11753#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011754 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011755 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011756#endif
11757
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011758/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011759#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011760 /* Send a SIGIO signal whenever input or output
11761 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011762 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011763#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011764#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011767#endif
11768#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011769 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011770 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011771#endif
11772#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011773 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011774 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011775#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011776#ifdef O_NOLINKS
11777 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011778 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011779#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011780#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011781 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011782 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011783#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011784
Victor Stinner8c62be82010-05-06 00:08:46 +000011785 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011786#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011787 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011788#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011789#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011790 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011791#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011792#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011793 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011794#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011795#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011796 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011797#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011798#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011799 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011800#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011801#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011802 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011803#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011804#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011805 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011806#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011807#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011809#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011810#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011811 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011812#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011813#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011814 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011815#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011816#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011817 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011818#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011819#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011820 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011821#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011822#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011823 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011824#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011825#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011826 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011827#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011828#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011829 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011830#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011831#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011832 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011833#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011834#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011835 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011836#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011837
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011838 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011839#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011840 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011841#endif /* ST_RDONLY */
11842#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011843 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011844#endif /* ST_NOSUID */
11845
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011846 /* GNU extensions */
11847#ifdef ST_NODEV
11848 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11849#endif /* ST_NODEV */
11850#ifdef ST_NOEXEC
11851 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11852#endif /* ST_NOEXEC */
11853#ifdef ST_SYNCHRONOUS
11854 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11855#endif /* ST_SYNCHRONOUS */
11856#ifdef ST_MANDLOCK
11857 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11858#endif /* ST_MANDLOCK */
11859#ifdef ST_WRITE
11860 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11861#endif /* ST_WRITE */
11862#ifdef ST_APPEND
11863 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11864#endif /* ST_APPEND */
11865#ifdef ST_NOATIME
11866 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11867#endif /* ST_NOATIME */
11868#ifdef ST_NODIRATIME
11869 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11870#endif /* ST_NODIRATIME */
11871#ifdef ST_RELATIME
11872 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11873#endif /* ST_RELATIME */
11874
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011875 /* FreeBSD sendfile() constants */
11876#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011877 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011878#endif
11879#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011880 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011881#endif
11882#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011883 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011884#endif
11885
Ross Lagerwall7807c352011-03-17 20:20:30 +020011886 /* constants for posix_fadvise */
11887#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011888 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011889#endif
11890#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011891 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011892#endif
11893#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011894 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011895#endif
11896#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011897 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011898#endif
11899#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011900 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011901#endif
11902#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011903 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011904#endif
11905
11906 /* constants for waitid */
11907#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011908 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11909 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11910 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011911#endif
11912#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011913 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011914#endif
11915#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011916 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011917#endif
11918#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011919 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011920#endif
11921#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011923#endif
11924#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011925 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011926#endif
11927#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011928 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011929#endif
11930#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011931 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011932#endif
11933
11934 /* constants for lockf */
11935#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011936 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011937#endif
11938#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011939 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011940#endif
11941#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011942 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011943#endif
11944#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011945 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011946#endif
11947
Guido van Rossum246bc171999-02-01 23:54:31 +000011948#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011949 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11950 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11951 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11952 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11953 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011954#endif
11955
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011956#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011957 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11958 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11959 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011960#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011961 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011962#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011963#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011964 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011965#endif
11966#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011968#endif
11969#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011970 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011971#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011972#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011974#endif
11975#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011976 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011977#endif
11978#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011979 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011980#endif
11981#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011982 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011983#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011984#endif
11985
Benjamin Peterson9428d532011-09-14 11:45:52 -040011986#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11988 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11989 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011990#endif
11991
Victor Stinner8b905bd2011-10-25 13:34:04 +020011992#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011993 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011994#endif
11995#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011996 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011997#endif
11998#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011999 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012000#endif
12001#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012002 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012003#endif
12004#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012005 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012006#endif
12007#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012008 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012009#endif
12010#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012011 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012012#endif
12013
Victor Stinner8c62be82010-05-06 00:08:46 +000012014 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012015}
12016
12017
Tim Peters5aa91602002-01-30 05:46:57 +000012018#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012019#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012020#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012021
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012022#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012023#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012024#define MODNAME "posix"
12025#endif
12026
Martin v. Löwis1a214512008-06-11 05:26:20 +000012027static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012028 PyModuleDef_HEAD_INIT,
12029 MODNAME,
12030 posix__doc__,
12031 -1,
12032 posix_methods,
12033 NULL,
12034 NULL,
12035 NULL,
12036 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012037};
12038
12039
Larry Hastings9cf065c2012-06-22 16:30:09 -070012040static char *have_functions[] = {
12041
12042#ifdef HAVE_FACCESSAT
12043 "HAVE_FACCESSAT",
12044#endif
12045
12046#ifdef HAVE_FCHDIR
12047 "HAVE_FCHDIR",
12048#endif
12049
12050#ifdef HAVE_FCHMOD
12051 "HAVE_FCHMOD",
12052#endif
12053
12054#ifdef HAVE_FCHMODAT
12055 "HAVE_FCHMODAT",
12056#endif
12057
12058#ifdef HAVE_FCHOWN
12059 "HAVE_FCHOWN",
12060#endif
12061
Larry Hastings00964ed2013-08-12 13:49:30 -040012062#ifdef HAVE_FCHOWNAT
12063 "HAVE_FCHOWNAT",
12064#endif
12065
Larry Hastings9cf065c2012-06-22 16:30:09 -070012066#ifdef HAVE_FEXECVE
12067 "HAVE_FEXECVE",
12068#endif
12069
12070#ifdef HAVE_FDOPENDIR
12071 "HAVE_FDOPENDIR",
12072#endif
12073
Georg Brandl306336b2012-06-24 12:55:33 +020012074#ifdef HAVE_FPATHCONF
12075 "HAVE_FPATHCONF",
12076#endif
12077
Larry Hastings9cf065c2012-06-22 16:30:09 -070012078#ifdef HAVE_FSTATAT
12079 "HAVE_FSTATAT",
12080#endif
12081
12082#ifdef HAVE_FSTATVFS
12083 "HAVE_FSTATVFS",
12084#endif
12085
Georg Brandl306336b2012-06-24 12:55:33 +020012086#ifdef HAVE_FTRUNCATE
12087 "HAVE_FTRUNCATE",
12088#endif
12089
Larry Hastings9cf065c2012-06-22 16:30:09 -070012090#ifdef HAVE_FUTIMENS
12091 "HAVE_FUTIMENS",
12092#endif
12093
12094#ifdef HAVE_FUTIMES
12095 "HAVE_FUTIMES",
12096#endif
12097
12098#ifdef HAVE_FUTIMESAT
12099 "HAVE_FUTIMESAT",
12100#endif
12101
12102#ifdef HAVE_LINKAT
12103 "HAVE_LINKAT",
12104#endif
12105
12106#ifdef HAVE_LCHFLAGS
12107 "HAVE_LCHFLAGS",
12108#endif
12109
12110#ifdef HAVE_LCHMOD
12111 "HAVE_LCHMOD",
12112#endif
12113
12114#ifdef HAVE_LCHOWN
12115 "HAVE_LCHOWN",
12116#endif
12117
12118#ifdef HAVE_LSTAT
12119 "HAVE_LSTAT",
12120#endif
12121
12122#ifdef HAVE_LUTIMES
12123 "HAVE_LUTIMES",
12124#endif
12125
12126#ifdef HAVE_MKDIRAT
12127 "HAVE_MKDIRAT",
12128#endif
12129
12130#ifdef HAVE_MKFIFOAT
12131 "HAVE_MKFIFOAT",
12132#endif
12133
12134#ifdef HAVE_MKNODAT
12135 "HAVE_MKNODAT",
12136#endif
12137
12138#ifdef HAVE_OPENAT
12139 "HAVE_OPENAT",
12140#endif
12141
12142#ifdef HAVE_READLINKAT
12143 "HAVE_READLINKAT",
12144#endif
12145
12146#ifdef HAVE_RENAMEAT
12147 "HAVE_RENAMEAT",
12148#endif
12149
12150#ifdef HAVE_SYMLINKAT
12151 "HAVE_SYMLINKAT",
12152#endif
12153
12154#ifdef HAVE_UNLINKAT
12155 "HAVE_UNLINKAT",
12156#endif
12157
12158#ifdef HAVE_UTIMENSAT
12159 "HAVE_UTIMENSAT",
12160#endif
12161
12162#ifdef MS_WINDOWS
12163 "MS_WINDOWS",
12164#endif
12165
12166 NULL
12167};
12168
12169
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012170PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012171INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012172{
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012174 PyObject *list;
12175 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012176
Brian Curtin52173d42010-12-02 18:29:18 +000012177#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012178 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012179#endif
12180
Victor Stinner8c62be82010-05-06 00:08:46 +000012181 m = PyModule_Create(&posixmodule);
12182 if (m == NULL)
12183 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012184
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 /* Initialize environ dictionary */
12186 v = convertenviron();
12187 Py_XINCREF(v);
12188 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12189 return NULL;
12190 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012191
Victor Stinner8c62be82010-05-06 00:08:46 +000012192 if (all_ins(m))
12193 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012194
Victor Stinner8c62be82010-05-06 00:08:46 +000012195 if (setup_confname_tables(m))
12196 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012197
Victor Stinner8c62be82010-05-06 00:08:46 +000012198 Py_INCREF(PyExc_OSError);
12199 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012200
Guido van Rossumb3d39562000-01-31 18:41:26 +000012201#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012202 if (posix_putenv_garbage == NULL)
12203 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012204#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012205
Victor Stinner8c62be82010-05-06 00:08:46 +000012206 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012207#if defined(HAVE_WAITID) && !defined(__APPLE__)
12208 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012209 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12210 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012211#endif
12212
Christian Heimes25827622013-10-12 01:27:08 +020012213 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012214 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12215 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12216 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012217 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12218 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012219 structseq_new = StatResultType.tp_new;
12220 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012221
Christian Heimes25827622013-10-12 01:27:08 +020012222 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012223 if (PyStructSequence_InitType2(&StatVFSResultType,
12224 &statvfs_result_desc) < 0)
12225 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012226#ifdef NEED_TICKS_PER_SECOND
12227# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012228 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012229# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012230 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012231# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012232 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012233# endif
12234#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012235
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012236#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012237 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012238 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12239 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012240 SchedParamType.tp_new = sched_param_new;
12241#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012242
12243 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012244 if (PyStructSequence_InitType2(&TerminalSizeType,
12245 &TerminalSize_desc) < 0)
12246 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012247 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012248#if defined(HAVE_WAITID) && !defined(__APPLE__)
12249 Py_INCREF((PyObject*) &WaitidResultType);
12250 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012252 Py_INCREF((PyObject*) &StatResultType);
12253 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12254 Py_INCREF((PyObject*) &StatVFSResultType);
12255 PyModule_AddObject(m, "statvfs_result",
12256 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012257
12258#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012259 Py_INCREF(&SchedParamType);
12260 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012261#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012262
Larry Hastings605a62d2012-06-24 04:33:36 -070012263 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012264 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12265 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012266 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12267
12268 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012269 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12270 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012271 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12272
Thomas Wouters477c8d52006-05-27 19:21:47 +000012273#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012274 /*
12275 * Step 2 of weak-linking support on Mac OS X.
12276 *
12277 * The code below removes functions that are not available on the
12278 * currently active platform.
12279 *
12280 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012281 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012282 * OSX 10.4.
12283 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012284#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012285 if (fstatvfs == NULL) {
12286 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12287 return NULL;
12288 }
12289 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012290#endif /* HAVE_FSTATVFS */
12291
12292#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012293 if (statvfs == NULL) {
12294 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12295 return NULL;
12296 }
12297 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012298#endif /* HAVE_STATVFS */
12299
12300# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012301 if (lchown == NULL) {
12302 if (PyObject_DelAttrString(m, "lchown") == -1) {
12303 return NULL;
12304 }
12305 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012306#endif /* HAVE_LCHOWN */
12307
12308
12309#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012310
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012311 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012312 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12313
Larry Hastings6fe20b32012-04-19 15:07:49 -070012314 billion = PyLong_FromLong(1000000000);
12315 if (!billion)
12316 return NULL;
12317
Larry Hastings9cf065c2012-06-22 16:30:09 -070012318 /* suppress "function not used" warnings */
12319 {
12320 int ignored;
12321 fd_specified("", -1);
12322 follow_symlinks_specified("", 1);
12323 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12324 dir_fd_converter(Py_None, &ignored);
12325 dir_fd_unavailable(Py_None, &ignored);
12326 }
12327
12328 /*
12329 * provide list of locally available functions
12330 * so os.py can populate support_* lists
12331 */
12332 list = PyList_New(0);
12333 if (!list)
12334 return NULL;
12335 for (trace = have_functions; *trace; trace++) {
12336 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12337 if (!unicode)
12338 return NULL;
12339 if (PyList_Append(list, unicode))
12340 return NULL;
12341 Py_DECREF(unicode);
12342 }
12343 PyModule_AddObject(m, "_have_functions", list);
12344
12345 initialized = 1;
12346
Victor Stinner8c62be82010-05-06 00:08:46 +000012347 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012348}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012349
12350#ifdef __cplusplus
12351}
12352#endif