blob: 2f21ceb6f7ca8e8f050be2d8a9a3815c47203b81 [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
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020033# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Ross Lagerwall4d076da2011-03-18 06:56:53 +020048#ifdef HAVE_SYS_UIO_H
49#include <sys/uio.h>
50#endif
51
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054#endif /* HAVE_SYS_TYPES_H */
55
56#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000057#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000059
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000061#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000062#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000065#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000067
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#ifdef HAVE_FCNTL_H
69#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000070#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000071
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072#ifdef HAVE_GRP_H
73#include <grp.h>
74#endif
75
Barry Warsaw5676bd12003-01-07 20:57:09 +000076#ifdef HAVE_SYSEXITS_H
77#include <sysexits.h>
78#endif /* HAVE_SYSEXITS_H */
79
Anthony Baxter8a560de2004-10-13 15:30:56 +000080#ifdef HAVE_SYS_LOADAVG_H
81#include <sys/loadavg.h>
82#endif
83
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000084#ifdef HAVE_LANGINFO_H
85#include <langinfo.h>
86#endif
87
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000088#ifdef HAVE_SYS_SENDFILE_H
89#include <sys/sendfile.h>
90#endif
91
Benjamin Peterson94b580d2011-08-02 17:30:04 -050092#ifdef HAVE_SCHED_H
93#include <sched.h>
94#endif
95
Benjamin Peterson2dbda072012-03-16 10:12:55 -050096#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050097#undef HAVE_SCHED_SETAFFINITY
98#endif
99
Benjamin Peterson9428d532011-09-14 11:45:52 -0400100#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
101#define USE_XATTRS
102#endif
103
104#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400105#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
109#ifdef HAVE_SYS_SOCKET_H
110#include <sys/socket.h>
111#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#endif
113
Victor Stinner8b905bd2011-10-25 13:34:04 +0200114#ifdef HAVE_DLFCN_H
115#include <dlfcn.h>
116#endif
117
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200118#ifdef __hpux
119#include <sys/mpctl.h>
120#endif
121
122#if defined(__DragonFly__) || \
123 defined(__OpenBSD__) || \
124 defined(__FreeBSD__) || \
125 defined(__NetBSD__) || \
126 defined(__APPLE__)
127#include <sys/sysctl.h>
128#endif
129
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100130#if defined(MS_WINDOWS)
131# define TERMSIZE_USE_CONIO
132#elif defined(HAVE_SYS_IOCTL_H)
133# include <sys/ioctl.h>
134# if defined(HAVE_TERMIOS_H)
135# include <termios.h>
136# endif
137# if defined(TIOCGWINSZ)
138# define TERMSIZE_USE_IOCTL
139# endif
140#endif /* MS_WINDOWS */
141
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000143/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000146#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_OPENDIR 1
152#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_WAIT 1
155#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000156#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000157#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000158#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#define HAVE_SYSTEM 1
163#define HAVE_CWAIT 1
164#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000165#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000166#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200167#if defined(__VMS)
168/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170/* Unix functions that the configure script doesn't check for */
171#define HAVE_EXECV 1
172#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000173#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000174#define HAVE_FORK1 1
175#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#define HAVE_GETEGID 1
177#define HAVE_GETEUID 1
178#define HAVE_GETGID 1
179#define HAVE_GETPPID 1
180#define HAVE_GETUID 1
181#define HAVE_KILL 1
182#define HAVE_OPENDIR 1
183#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000186#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200187#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#endif /* _MSC_VER */
189#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000190#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000191
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800193/*[clinic]
194module os
195[clinic]*/
196/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000200#if defined(__sgi)&&_COMPILER_VERSION>=700
201/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
202 (default) */
203extern char *ctermid_r(char *);
204#endif
205
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000206#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000210#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000215#endif
216#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chdir(char *);
218extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000220extern int chdir(const char *);
221extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000222#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000223#ifdef __BORLANDC__
224extern int chmod(const char *, int);
225#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000227#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000313#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000314#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000316#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000317#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000318#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
319#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000320static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000321#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000322#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#if defined(PATH_MAX) && PATH_MAX > 1024
326#define MAXPATHLEN PATH_MAX
327#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000328#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000330#endif /* MAXPATHLEN */
331
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000332#ifdef UNION_WAIT
333/* Emulate some macros on systems that have a union instead of macros */
334
335#ifndef WIFEXITED
336#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
337#endif
338
339#ifndef WEXITSTATUS
340#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
341#endif
342
343#ifndef WTERMSIG
344#define WTERMSIG(u_wait) ((u_wait).w_termsig)
345#endif
346
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347#define WAIT_TYPE union wait
348#define WAIT_STATUS_INT(s) (s.w_status)
349
350#else /* !UNION_WAIT */
351#define WAIT_TYPE int
352#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000353#endif /* UNION_WAIT */
354
Greg Wardb48bc172000-03-01 21:51:56 +0000355/* Don't use the "_r" form if we don't need it (also, won't have a
356 prototype for it, at least on Solaris -- maybe others as well?). */
357#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
358#define USE_CTERMID_R
359#endif
360
Fred Drake699f3522000-06-29 21:12:41 +0000361/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000362#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000363#undef FSTAT
364#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200365#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT win32_fstat
369# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000371# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000373# define FSTAT fstat
374# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000375#endif
376
Tim Peters11b23062003-04-23 02:39:17 +0000377#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000378#include <sys/mkdev.h>
379#else
380#if defined(MAJOR_IN_SYSMACROS)
381#include <sys/sysmacros.h>
382#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000383#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
384#include <sys/mkdev.h>
385#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000386#endif
Fred Drake699f3522000-06-29 21:12:41 +0000387
Victor Stinner6edddfa2013-11-24 19:22:57 +0100388#define DWORD_MAX 4294967295U
389
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390
391#ifdef MS_WINDOWS
392static int
393win32_warn_bytes_api()
394{
395 return PyErr_WarnEx(PyExc_DeprecationWarning,
396 "The Windows bytes API has been deprecated, "
397 "use Unicode filenames instead",
398 1);
399}
400#endif
401
402
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200403#ifndef MS_WINDOWS
404PyObject *
405_PyLong_FromUid(uid_t uid)
406{
407 if (uid == (uid_t)-1)
408 return PyLong_FromLong(-1);
409 return PyLong_FromUnsignedLong(uid);
410}
411
412PyObject *
413_PyLong_FromGid(gid_t gid)
414{
415 if (gid == (gid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(gid);
418}
419
420int
421_Py_Uid_Converter(PyObject *obj, void *p)
422{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700423 uid_t uid;
424 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200425 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200426 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427 unsigned long uresult;
428
429 index = PyNumber_Index(obj);
430 if (index == NULL) {
431 PyErr_Format(PyExc_TypeError,
432 "uid should be integer, not %.200s",
433 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 return 0;
435 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700436
437 /*
438 * Handling uid_t is complicated for two reasons:
439 * * Although uid_t is (always?) unsigned, it still
440 * accepts -1.
441 * * We don't know its size in advance--it may be
442 * bigger than an int, or it may be smaller than
443 * a long.
444 *
445 * So a bit of defensive programming is in order.
446 * Start with interpreting the value passed
447 * in as a signed long and see if it works.
448 */
449
450 result = PyLong_AsLongAndOverflow(index, &overflow);
451
452 if (!overflow) {
453 uid = (uid_t)result;
454
455 if (result == -1) {
456 if (PyErr_Occurred())
457 goto fail;
458 /* It's a legitimate -1, we're done. */
459 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200460 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700461
462 /* Any other negative number is disallowed. */
463 if (result < 0)
464 goto underflow;
465
466 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200467 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700468 (long)uid != result)
469 goto underflow;
470 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200471 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700472
473 if (overflow < 0)
474 goto underflow;
475
476 /*
477 * Okay, the value overflowed a signed long. If it
478 * fits in an *unsigned* long, it may still be okay,
479 * as uid_t may be unsigned long on this platform.
480 */
481 uresult = PyLong_AsUnsignedLong(index);
482 if (PyErr_Occurred()) {
483 if (PyErr_ExceptionMatches(PyExc_OverflowError))
484 goto overflow;
485 goto fail;
486 }
487
488 uid = (uid_t)uresult;
489
490 /*
491 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
492 * but this value would get interpreted as (uid_t)-1 by chown
493 * and its siblings. That's not what the user meant! So we
494 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100495 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700496 */
497 if (uid == (uid_t)-1)
498 goto overflow;
499
500 /* Ensure the value wasn't truncated. */
501 if (sizeof(uid_t) < sizeof(long) &&
502 (unsigned long)uid != uresult)
503 goto overflow;
504 /* fallthrough */
505
506success:
507 Py_DECREF(index);
508 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200509 return 1;
510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is less than minimum");
514 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200515
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700516overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518 "uid is greater than maximum");
519 /* fallthrough */
520
521fail:
522 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523 return 0;
524}
525
526int
527_Py_Gid_Converter(PyObject *obj, void *p)
528{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529 gid_t gid;
530 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200532 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533 unsigned long uresult;
534
535 index = PyNumber_Index(obj);
536 if (index == NULL) {
537 PyErr_Format(PyExc_TypeError,
538 "gid should be integer, not %.200s",
539 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 return 0;
541 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542
543 /*
544 * Handling gid_t is complicated for two reasons:
545 * * Although gid_t is (always?) unsigned, it still
546 * accepts -1.
547 * * We don't know its size in advance--it may be
548 * bigger than an int, or it may be smaller than
549 * a long.
550 *
551 * So a bit of defensive programming is in order.
552 * Start with interpreting the value passed
553 * in as a signed long and see if it works.
554 */
555
556 result = PyLong_AsLongAndOverflow(index, &overflow);
557
558 if (!overflow) {
559 gid = (gid_t)result;
560
561 if (result == -1) {
562 if (PyErr_Occurred())
563 goto fail;
564 /* It's a legitimate -1, we're done. */
565 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567
568 /* Any other negative number is disallowed. */
569 if (result < 0) {
570 goto underflow;
571 }
572
573 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575 (long)gid != result)
576 goto underflow;
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 if (overflow < 0)
581 goto underflow;
582
583 /*
584 * Okay, the value overflowed a signed long. If it
585 * fits in an *unsigned* long, it may still be okay,
586 * as gid_t may be unsigned long on this platform.
587 */
588 uresult = PyLong_AsUnsignedLong(index);
589 if (PyErr_Occurred()) {
590 if (PyErr_ExceptionMatches(PyExc_OverflowError))
591 goto overflow;
592 goto fail;
593 }
594
595 gid = (gid_t)uresult;
596
597 /*
598 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
599 * but this value would get interpreted as (gid_t)-1 by chown
600 * and its siblings. That's not what the user meant! So we
601 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100602 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 */
604 if (gid == (gid_t)-1)
605 goto overflow;
606
607 /* Ensure the value wasn't truncated. */
608 if (sizeof(gid_t) < sizeof(long) &&
609 (unsigned long)gid != uresult)
610 goto overflow;
611 /* fallthrough */
612
613success:
614 Py_DECREF(index);
615 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 return 1;
617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is less than minimum");
621 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625 "gid is greater than maximum");
626 /* fallthrough */
627
628fail:
629 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 return 0;
631}
632#endif /* MS_WINDOWS */
633
634
Larry Hastings9cf065c2012-06-22 16:30:09 -0700635#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400636/*
637 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
638 * without the int cast, the value gets interpreted as uint (4291925331),
639 * which doesn't play nicely with all the initializer lines in this file that
640 * look like this:
641 * int dir_fd = DEFAULT_DIR_FD;
642 */
643#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700644#else
645#define DEFAULT_DIR_FD (-100)
646#endif
647
648static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200649_fd_converter(PyObject *o, int *p, const char *allowed)
650{
651 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652 long long_value;
653
654 PyObject *index = PyNumber_Index(o);
655 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200656 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700657 "argument should be %s, not %.200s",
658 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700659 return 0;
660 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700661
662 long_value = PyLong_AsLongAndOverflow(index, &overflow);
663 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200664 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700665 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667 return 0;
668 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200669 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700670 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700671 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700672 return 0;
673 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700674
Larry Hastings9cf065c2012-06-22 16:30:09 -0700675 *p = (int)long_value;
676 return 1;
677}
678
679static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200680dir_fd_converter(PyObject *o, void *p)
681{
682 if (o == Py_None) {
683 *(int *)p = DEFAULT_DIR_FD;
684 return 1;
685 }
686 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700687}
688
689
690
691/*
692 * A PyArg_ParseTuple "converter" function
693 * that handles filesystem paths in the manner
694 * preferred by the os module.
695 *
696 * path_converter accepts (Unicode) strings and their
697 * subclasses, and bytes and their subclasses. What
698 * it does with the argument depends on the platform:
699 *
700 * * On Windows, if we get a (Unicode) string we
701 * extract the wchar_t * and return it; if we get
702 * bytes we extract the char * and return that.
703 *
704 * * On all other platforms, strings are encoded
705 * to bytes using PyUnicode_FSConverter, then we
706 * extract the char * from the bytes object and
707 * return that.
708 *
709 * path_converter also optionally accepts signed
710 * integers (representing open file descriptors) instead
711 * of path strings.
712 *
713 * Input fields:
714 * path.nullable
715 * If nonzero, the path is permitted to be None.
716 * path.allow_fd
717 * If nonzero, the path is permitted to be a file handle
718 * (a signed int) instead of a string.
719 * path.function_name
720 * If non-NULL, path_converter will use that as the name
721 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700722 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700723 * path.argument_name
724 * If non-NULL, path_converter will use that as the name
725 * of the parameter in error messages.
726 * (If path.argument_name is NULL it uses "path".)
727 *
728 * Output fields:
729 * path.wide
730 * Points to the path if it was expressed as Unicode
731 * and was not encoded. (Only used on Windows.)
732 * path.narrow
733 * Points to the path if it was expressed as bytes,
734 * or it was Unicode and was encoded to bytes.
735 * path.fd
736 * Contains a file descriptor if path.accept_fd was true
737 * and the caller provided a signed integer instead of any
738 * sort of string.
739 *
740 * WARNING: if your "path" parameter is optional, and is
741 * unspecified, path_converter will never get called.
742 * So if you set allow_fd, you *MUST* initialize path.fd = -1
743 * yourself!
744 * path.length
745 * The length of the path in characters, if specified as
746 * a string.
747 * path.object
748 * The original object passed in.
749 * path.cleanup
750 * For internal use only. May point to a temporary object.
751 * (Pay no attention to the man behind the curtain.)
752 *
753 * At most one of path.wide or path.narrow will be non-NULL.
754 * If path was None and path.nullable was set,
755 * or if path was an integer and path.allow_fd was set,
756 * both path.wide and path.narrow will be NULL
757 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200758 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700759 * path_converter takes care to not write to the path_t
760 * unless it's successful. However it must reset the
761 * "cleanup" field each time it's called.
762 *
763 * Use as follows:
764 * path_t path;
765 * memset(&path, 0, sizeof(path));
766 * PyArg_ParseTuple(args, "O&", path_converter, &path);
767 * // ... use values from path ...
768 * path_cleanup(&path);
769 *
770 * (Note that if PyArg_Parse fails you don't need to call
771 * path_cleanup(). However it is safe to do so.)
772 */
773typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100774 const char *function_name;
775 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 int nullable;
777 int allow_fd;
778 wchar_t *wide;
779 char *narrow;
780 int fd;
781 Py_ssize_t length;
782 PyObject *object;
783 PyObject *cleanup;
784} path_t;
785
Larry Hastings31826802013-10-19 00:09:25 -0700786#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
787 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
788
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789static void
790path_cleanup(path_t *path) {
791 if (path->cleanup) {
792 Py_DECREF(path->cleanup);
793 path->cleanup = NULL;
794 }
795}
796
797static int
798path_converter(PyObject *o, void *p) {
799 path_t *path = (path_t *)p;
800 PyObject *unicode, *bytes;
801 Py_ssize_t length;
802 char *narrow;
803
804#define FORMAT_EXCEPTION(exc, fmt) \
805 PyErr_Format(exc, "%s%s" fmt, \
806 path->function_name ? path->function_name : "", \
807 path->function_name ? ": " : "", \
808 path->argument_name ? path->argument_name : "path")
809
810 /* Py_CLEANUP_SUPPORTED support */
811 if (o == NULL) {
812 path_cleanup(path);
813 return 1;
814 }
815
816 /* ensure it's always safe to call path_cleanup() */
817 path->cleanup = NULL;
818
819 if (o == Py_None) {
820 if (!path->nullable) {
821 FORMAT_EXCEPTION(PyExc_TypeError,
822 "can't specify None for %s argument");
823 return 0;
824 }
825 path->wide = NULL;
826 path->narrow = NULL;
827 path->length = 0;
828 path->object = o;
829 path->fd = -1;
830 return 1;
831 }
832
833 unicode = PyUnicode_FromObject(o);
834 if (unicode) {
835#ifdef MS_WINDOWS
836 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100837
838 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
839 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840 Py_DECREF(unicode);
841 return 0;
842 }
Victor Stinner59799a82013-11-13 14:17:30 +0100843 if (length > 32767) {
844 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845 Py_DECREF(unicode);
846 return 0;
847 }
848
849 path->wide = wide;
850 path->narrow = NULL;
851 path->length = length;
852 path->object = o;
853 path->fd = -1;
854 path->cleanup = unicode;
855 return Py_CLEANUP_SUPPORTED;
856#else
857 int converted = PyUnicode_FSConverter(unicode, &bytes);
858 Py_DECREF(unicode);
859 if (!converted)
860 bytes = NULL;
861#endif
862 }
863 else {
864 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200865 if (PyObject_CheckBuffer(o))
866 bytes = PyBytes_FromObject(o);
867 else
868 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700869 if (!bytes) {
870 PyErr_Clear();
871 if (path->allow_fd) {
872 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200873 int result = _fd_converter(o, &fd,
874 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 if (result) {
876 path->wide = NULL;
877 path->narrow = NULL;
878 path->length = 0;
879 path->object = o;
880 path->fd = fd;
881 return result;
882 }
883 }
884 }
885 }
886
887 if (!bytes) {
888 if (!PyErr_Occurred())
889 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
890 return 0;
891 }
892
893#ifdef MS_WINDOWS
894 if (win32_warn_bytes_api()) {
895 Py_DECREF(bytes);
896 return 0;
897 }
898#endif
899
900 length = PyBytes_GET_SIZE(bytes);
901#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100902 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
904 Py_DECREF(bytes);
905 return 0;
906 }
907#endif
908
909 narrow = PyBytes_AS_STRING(bytes);
910 if (length != strlen(narrow)) {
911 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
912 Py_DECREF(bytes);
913 return 0;
914 }
915
916 path->wide = NULL;
917 path->narrow = narrow;
918 path->length = length;
919 path->object = o;
920 path->fd = -1;
921 path->cleanup = bytes;
922 return Py_CLEANUP_SUPPORTED;
923}
924
925static void
926argument_unavailable_error(char *function_name, char *argument_name) {
927 PyErr_Format(PyExc_NotImplementedError,
928 "%s%s%s unavailable on this platform",
929 (function_name != NULL) ? function_name : "",
930 (function_name != NULL) ? ": ": "",
931 argument_name);
932}
933
934static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200935dir_fd_unavailable(PyObject *o, void *p)
936{
937 int dir_fd;
938 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200940 if (dir_fd != DEFAULT_DIR_FD) {
941 argument_unavailable_error(NULL, "dir_fd");
942 return 0;
943 }
944 *(int *)p = dir_fd;
945 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946}
947
948static int
949fd_specified(char *function_name, int fd) {
950 if (fd == -1)
951 return 0;
952
953 argument_unavailable_error(function_name, "fd");
954 return 1;
955}
956
957static int
958follow_symlinks_specified(char *function_name, int follow_symlinks) {
959 if (follow_symlinks)
960 return 0;
961
962 argument_unavailable_error(function_name, "follow_symlinks");
963 return 1;
964}
965
966static int
967path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
968 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
969 PyErr_Format(PyExc_ValueError,
970 "%s: can't specify dir_fd without matching path",
971 function_name);
972 return 1;
973 }
974 return 0;
975}
976
977static int
978dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
979 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
980 PyErr_Format(PyExc_ValueError,
981 "%s: can't specify both dir_fd and fd",
982 function_name);
983 return 1;
984 }
985 return 0;
986}
987
988static int
989fd_and_follow_symlinks_invalid(char *function_name, int fd,
990 int follow_symlinks) {
991 if ((fd > 0) && (!follow_symlinks)) {
992 PyErr_Format(PyExc_ValueError,
993 "%s: cannot use fd and follow_symlinks together",
994 function_name);
995 return 1;
996 }
997 return 0;
998}
999
1000static int
1001dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1002 int follow_symlinks) {
1003 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1004 PyErr_Format(PyExc_ValueError,
1005 "%s: cannot use dir_fd and follow_symlinks together",
1006 function_name);
1007 return 1;
1008 }
1009 return 0;
1010}
1011
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001012/* A helper used by a number of POSIX-only functions */
1013#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001014static int
1015_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001016{
1017#if !defined(HAVE_LARGEFILE_SUPPORT)
1018 *((off_t*)addr) = PyLong_AsLong(arg);
1019#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001020 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001021#endif
1022 if (PyErr_Occurred())
1023 return 0;
1024 return 1;
1025}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001026#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001027
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001028#if defined _MSC_VER && _MSC_VER >= 1400
1029/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001030 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001031 * Normally, an invalid fd is likely to be a C program error and therefore
1032 * an assertion can be useful, but it does contradict the POSIX standard
1033 * which for write(2) states:
1034 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1035 * "[EBADF] The fildes argument is not a valid file descriptor open for
1036 * writing."
1037 * Furthermore, python allows the user to enter any old integer
1038 * as a fd and should merely raise a python exception on error.
1039 * The Microsoft CRT doesn't provide an official way to check for the
1040 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001041 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001042 * internal structures involved.
1043 * The structures below must be updated for each version of visual studio
1044 * according to the file internal.h in the CRT source, until MS comes
1045 * up with a less hacky way to do this.
1046 * (all of this is to avoid globally modifying the CRT behaviour using
1047 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1048 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001049/* The actual size of the structure is determined at runtime.
1050 * Only the first items must be present.
1051 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001052typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001053 intptr_t osfhnd;
1054 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001055} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001056
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001057extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001058#define IOINFO_L2E 5
1059#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1060#define IOINFO_ARRAYS 64
1061#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1062#define FOPEN 0x01
1063#define _NO_CONSOLE_FILENO (intptr_t)-2
1064
1065/* This function emulates what the windows CRT does to validate file handles */
1066int
1067_PyVerify_fd(int fd)
1068{
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 const int i1 = fd >> IOINFO_L2E;
1070 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001071
Antoine Pitrou22e41552010-08-15 18:07:50 +00001072 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073
Victor Stinner8c62be82010-05-06 00:08:46 +00001074 /* Determine the actual size of the ioinfo structure,
1075 * as used by the CRT loaded in memory
1076 */
1077 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1078 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1079 }
1080 if (sizeof_ioinfo == 0) {
1081 /* This should not happen... */
1082 goto fail;
1083 }
1084
1085 /* See that it isn't a special CLEAR fileno */
1086 if (fd != _NO_CONSOLE_FILENO) {
1087 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1088 * we check pointer validity and other info
1089 */
1090 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1091 /* finally, check that the file is open */
1092 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1093 if (info->osfile & FOPEN) {
1094 return 1;
1095 }
1096 }
1097 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001098 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001099 errno = EBADF;
1100 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001101}
1102
1103/* the special case of checking dup2. The target fd must be in a sensible range */
1104static int
1105_PyVerify_fd_dup2(int fd1, int fd2)
1106{
Victor Stinner8c62be82010-05-06 00:08:46 +00001107 if (!_PyVerify_fd(fd1))
1108 return 0;
1109 if (fd2 == _NO_CONSOLE_FILENO)
1110 return 0;
1111 if ((unsigned)fd2 < _NHANDLE_)
1112 return 1;
1113 else
1114 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001115}
1116#else
1117/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1118#define _PyVerify_fd_dup2(A, B) (1)
1119#endif
1120
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001121#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001122/* The following structure was copied from
1123 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1124 include doesn't seem to be present in the Windows SDK (at least as included
1125 with Visual Studio Express). */
1126typedef struct _REPARSE_DATA_BUFFER {
1127 ULONG ReparseTag;
1128 USHORT ReparseDataLength;
1129 USHORT Reserved;
1130 union {
1131 struct {
1132 USHORT SubstituteNameOffset;
1133 USHORT SubstituteNameLength;
1134 USHORT PrintNameOffset;
1135 USHORT PrintNameLength;
1136 ULONG Flags;
1137 WCHAR PathBuffer[1];
1138 } SymbolicLinkReparseBuffer;
1139
1140 struct {
1141 USHORT SubstituteNameOffset;
1142 USHORT SubstituteNameLength;
1143 USHORT PrintNameOffset;
1144 USHORT PrintNameLength;
1145 WCHAR PathBuffer[1];
1146 } MountPointReparseBuffer;
1147
1148 struct {
1149 UCHAR DataBuffer[1];
1150 } GenericReparseBuffer;
1151 };
1152} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1153
1154#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1155 GenericReparseBuffer)
1156#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1157
1158static int
Brian Curtind25aef52011-06-13 15:16:04 -05001159win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001160{
1161 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1162 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1163 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001164
1165 if (0 == DeviceIoControl(
1166 reparse_point_handle,
1167 FSCTL_GET_REPARSE_POINT,
1168 NULL, 0, /* in buffer */
1169 target_buffer, sizeof(target_buffer),
1170 &n_bytes_returned,
1171 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001172 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001173
1174 if (reparse_tag)
1175 *reparse_tag = rdb->ReparseTag;
1176
Brian Curtind25aef52011-06-13 15:16:04 -05001177 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001178}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001179
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001180#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001181
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001183#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001184/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001185** environ directly, we must obtain it with _NSGetEnviron(). See also
1186** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001187*/
1188#include <crt_externs.h>
1189static char **environ;
1190#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001192#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193
Barry Warsaw53699e91996-12-10 23:23:01 +00001194static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001195convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001196{
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001198#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001200#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001202#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001203
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 d = PyDict_New();
1205 if (d == NULL)
1206 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001207#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001208 if (environ == NULL)
1209 environ = *_NSGetEnviron();
1210#endif
1211#ifdef MS_WINDOWS
1212 /* _wenviron must be initialized in this way if the program is started
1213 through main() instead of wmain(). */
1214 _wgetenv(L"");
1215 if (_wenviron == NULL)
1216 return d;
1217 /* This part ignores errors */
1218 for (e = _wenviron; *e != NULL; e++) {
1219 PyObject *k;
1220 PyObject *v;
1221 wchar_t *p = wcschr(*e, L'=');
1222 if (p == NULL)
1223 continue;
1224 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1225 if (k == NULL) {
1226 PyErr_Clear();
1227 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001228 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1230 if (v == NULL) {
1231 PyErr_Clear();
1232 Py_DECREF(k);
1233 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001234 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001235 if (PyDict_GetItem(d, k) == NULL) {
1236 if (PyDict_SetItem(d, k, v) != 0)
1237 PyErr_Clear();
1238 }
1239 Py_DECREF(k);
1240 Py_DECREF(v);
1241 }
1242#else
1243 if (environ == NULL)
1244 return d;
1245 /* This part ignores errors */
1246 for (e = environ; *e != NULL; e++) {
1247 PyObject *k;
1248 PyObject *v;
1249 char *p = strchr(*e, '=');
1250 if (p == NULL)
1251 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001252 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (k == NULL) {
1254 PyErr_Clear();
1255 continue;
1256 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001257 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001258 if (v == NULL) {
1259 PyErr_Clear();
1260 Py_DECREF(k);
1261 continue;
1262 }
1263 if (PyDict_GetItem(d, k) == NULL) {
1264 if (PyDict_SetItem(d, k, v) != 0)
1265 PyErr_Clear();
1266 }
1267 Py_DECREF(k);
1268 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001269 }
1270#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001272}
1273
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001274/* Set a POSIX-specific error from errno, and return NULL */
1275
Barry Warsawd58d7641998-07-23 16:14:40 +00001276static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001277posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001278{
Victor Stinner8c62be82010-05-06 00:08:46 +00001279 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280}
Mark Hammondef8b6542001-05-13 08:04:26 +00001281
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001282#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001283static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001284win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001285{
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 /* XXX We should pass the function name along in the future.
1287 (winreg.c also wants to pass the function name.)
1288 This would however require an additional param to the
1289 Windows error object, which is non-trivial.
1290 */
1291 errno = GetLastError();
1292 if (filename)
1293 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1294 else
1295 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001296}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001297
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001298static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001299win32_error_object(char* function, PyObject* filename)
1300{
1301 /* XXX - see win32_error for comments on 'function' */
1302 errno = GetLastError();
1303 if (filename)
1304 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001305 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001306 errno,
1307 filename);
1308 else
1309 return PyErr_SetFromWindowsErr(errno);
1310}
1311
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001312#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313
Larry Hastings9cf065c2012-06-22 16:30:09 -07001314static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001315path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001316{
1317#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001318 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1319 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001320#else
Victor Stinner292c8352012-10-30 02:17:38 +01001321 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001322#endif
1323}
1324
Larry Hastings31826802013-10-19 00:09:25 -07001325
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326/* POSIX generic methods */
1327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001329posix_fildes(PyObject *fdobj, int (*func)(int))
1330{
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 int fd;
1332 int res;
1333 fd = PyObject_AsFileDescriptor(fdobj);
1334 if (fd < 0)
1335 return NULL;
1336 if (!_PyVerify_fd(fd))
1337 return posix_error();
1338 Py_BEGIN_ALLOW_THREADS
1339 res = (*func)(fd);
1340 Py_END_ALLOW_THREADS
1341 if (res < 0)
1342 return posix_error();
1343 Py_INCREF(Py_None);
1344 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001345}
Guido van Rossum21142a01999-01-08 21:05:37 +00001346
1347static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001348posix_1str(const char *func_name, PyObject *args, char *format,
1349 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350{
Victor Stinner292c8352012-10-30 02:17:38 +01001351 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001353 memset(&path, 0, sizeof(path));
1354 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001356 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001359 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001361 if (res < 0) {
1362 path_error(&path);
1363 path_cleanup(&path);
1364 return NULL;
1365 }
1366 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 Py_INCREF(Py_None);
1368 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369}
1370
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001371
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001372#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373/* This is a reimplementation of the C library's chdir function,
1374 but one that produces Win32 errors instead of DOS error codes.
1375 chdir is essentially a wrapper around SetCurrentDirectory; however,
1376 it also needs to set "magic" environment variables indicating
1377 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001378static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001379win32_chdir(LPCSTR path)
1380{
Victor Stinner75875072013-11-24 19:23:25 +01001381 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 int result;
1383 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 if(!SetCurrentDirectoryA(path))
1386 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001387 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 if (!result)
1389 return FALSE;
1390 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001391 than MAX_PATH-1 (not including the final null character). */
1392 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 if (strncmp(new_path, "\\\\", 2) == 0 ||
1394 strncmp(new_path, "//", 2) == 0)
1395 /* UNC path, nothing to do. */
1396 return TRUE;
1397 env[1] = new_path[0];
1398 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399}
1400
1401/* The Unicode version differs from the ANSI version
1402 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001403static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404win32_wchdir(LPCWSTR path)
1405{
Victor Stinner75875072013-11-24 19:23:25 +01001406 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 int result;
1408 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 if(!SetCurrentDirectoryW(path))
1411 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001412 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if (!result)
1414 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001415 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001416 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 if (!new_path) {
1418 SetLastError(ERROR_OUTOFMEMORY);
1419 return FALSE;
1420 }
1421 result = GetCurrentDirectoryW(result, new_path);
1422 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001423 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return FALSE;
1425 }
1426 }
1427 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1428 wcsncmp(new_path, L"//", 2) == 0)
1429 /* UNC path, nothing to do. */
1430 return TRUE;
1431 env[1] = new_path[0];
1432 result = SetEnvironmentVariableW(env, new_path);
1433 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001434 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436}
1437#endif
1438
Martin v. Löwis14694662006-02-03 12:54:16 +00001439#ifdef MS_WINDOWS
1440/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1441 - time stamps are restricted to second resolution
1442 - file modification times suffer from forth-and-back conversions between
1443 UTC and local time
1444 Therefore, we implement our own stat, based on the Win32 API directly.
1445*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001446#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001447
1448struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001449 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 __int64 st_ino;
1451 unsigned short st_mode;
1452 int st_nlink;
1453 int st_uid;
1454 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001455 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001456 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001457 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001458 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001459 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001460 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001461 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001462 int st_ctime_nsec;
1463};
1464
1465static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1466
1467static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001468FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001469{
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1471 /* Cannot simply cast and dereference in_ptr,
1472 since it might not be aligned properly */
1473 __int64 in;
1474 memcpy(&in, in_ptr, sizeof(in));
1475 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001476 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001477}
1478
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001480time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001481{
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 /* XXX endianness */
1483 __int64 out;
1484 out = time_in + secs_between_epochs;
1485 out = out * 10000000 + nsec_in / 100;
1486 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487}
1488
Martin v. Löwis14694662006-02-03 12:54:16 +00001489/* Below, we *know* that ugo+r is 0444 */
1490#if _S_IREAD != 0400
1491#error Unsupported C library
1492#endif
1493static int
1494attributes_to_mode(DWORD attr)
1495{
Victor Stinner8c62be82010-05-06 00:08:46 +00001496 int m = 0;
1497 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1498 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1499 else
1500 m |= _S_IFREG;
1501 if (attr & FILE_ATTRIBUTE_READONLY)
1502 m |= 0444;
1503 else
1504 m |= 0666;
1505 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001506}
1507
1508static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001509attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001510{
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 memset(result, 0, sizeof(*result));
1512 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1513 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001514 result->st_dev = info->dwVolumeSerialNumber;
1515 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1517 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1518 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001519 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001520 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1522 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001523 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001524 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001525 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001527
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001529}
1530
Guido van Rossumd8faa362007-04-27 19:54:29 +00001531static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001532attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001533{
Victor Stinner8c62be82010-05-06 00:08:46 +00001534 HANDLE hFindFile;
1535 WIN32_FIND_DATAA FileData;
1536 hFindFile = FindFirstFileA(pszFile, &FileData);
1537 if (hFindFile == INVALID_HANDLE_VALUE)
1538 return FALSE;
1539 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001540 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001541 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542 info->dwFileAttributes = FileData.dwFileAttributes;
1543 info->ftCreationTime = FileData.ftCreationTime;
1544 info->ftLastAccessTime = FileData.ftLastAccessTime;
1545 info->ftLastWriteTime = FileData.ftLastWriteTime;
1546 info->nFileSizeHigh = FileData.nFileSizeHigh;
1547 info->nFileSizeLow = FileData.nFileSizeLow;
1548/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001549 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1550 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552}
1553
1554static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001556{
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 HANDLE hFindFile;
1558 WIN32_FIND_DATAW FileData;
1559 hFindFile = FindFirstFileW(pszFile, &FileData);
1560 if (hFindFile == INVALID_HANDLE_VALUE)
1561 return FALSE;
1562 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001564 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565 info->dwFileAttributes = FileData.dwFileAttributes;
1566 info->ftCreationTime = FileData.ftCreationTime;
1567 info->ftLastAccessTime = FileData.ftLastAccessTime;
1568 info->ftLastWriteTime = FileData.ftLastWriteTime;
1569 info->nFileSizeHigh = FileData.nFileSizeHigh;
1570 info->nFileSizeLow = FileData.nFileSizeLow;
1571/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001572 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1573 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575}
1576
Brian Curtind25aef52011-06-13 15:16:04 -05001577/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001578static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001579static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1580 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001581static int
Brian Curtind25aef52011-06-13 15:16:04 -05001582check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583{
Brian Curtind25aef52011-06-13 15:16:04 -05001584 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001585 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1586 DWORD);
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001589 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001590 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001591 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001592 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1593 "GetFinalPathNameByHandleA");
1594 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1595 "GetFinalPathNameByHandleW");
1596 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1597 Py_GetFinalPathNameByHandleW;
1598 }
1599 return has_GetFinalPathNameByHandle;
1600}
1601
1602static BOOL
1603get_target_path(HANDLE hdl, wchar_t **target_path)
1604{
1605 int buf_size, result_length;
1606 wchar_t *buf;
1607
1608 /* We have a good handle to the target, use it to determine
1609 the target path name (then we'll call lstat on it). */
1610 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1611 VOLUME_NAME_DOS);
1612 if(!buf_size)
1613 return FALSE;
1614
Victor Stinnerb6404912013-07-07 16:21:41 +02001615 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001616 if (!buf) {
1617 SetLastError(ERROR_OUTOFMEMORY);
1618 return FALSE;
1619 }
1620
Brian Curtind25aef52011-06-13 15:16:04 -05001621 result_length = Py_GetFinalPathNameByHandleW(hdl,
1622 buf, buf_size, VOLUME_NAME_DOS);
1623
1624 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001625 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001626 return FALSE;
1627 }
1628
1629 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001630 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001631 return FALSE;
1632 }
1633
1634 buf[result_length] = 0;
1635
1636 *target_path = buf;
1637 return TRUE;
1638}
1639
1640static int
1641win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1642 BOOL traverse);
1643static int
1644win32_xstat_impl(const char *path, struct win32_stat *result,
1645 BOOL traverse)
1646{
Victor Stinner26de69d2011-06-17 15:15:38 +02001647 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001648 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001649 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001651 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 const char *dot;
1653
Brian Curtind25aef52011-06-13 15:16:04 -05001654 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001655 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1656 traverse reparse point. */
1657 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 }
1659
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 hFile = CreateFileA(
1661 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001662 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 0, /* share mode */
1664 NULL, /* security attributes */
1665 OPEN_EXISTING,
1666 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001667 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1668 Because of this, calls like GetFinalPathNameByHandle will return
1669 the symlink path agin and not the actual final path. */
1670 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1671 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672 NULL);
1673
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675 /* Either the target doesn't exist, or we don't have access to
1676 get a handle to it. If the former, we need to return an error.
1677 If the latter, we can use attributes_from_dir. */
1678 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 return -1;
1680 /* Could not get attributes on open file. Fall back to
1681 reading the directory. */
1682 if (!attributes_from_dir(path, &info, &reparse_tag))
1683 /* Very strange. This should not fail now */
1684 return -1;
1685 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1686 if (traverse) {
1687 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001688 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 } else {
1693 if (!GetFileInformationByHandle(hFile, &info)) {
1694 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001695 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 }
1697 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001698 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1699 return -1;
1700
1701 /* Close the outer open file handle now that we're about to
1702 reopen it with different flags. */
1703 if (!CloseHandle(hFile))
1704 return -1;
1705
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001707 /* In order to call GetFinalPathNameByHandle we need to open
1708 the file without the reparse handling flag set. */
1709 hFile2 = CreateFileA(
1710 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1711 NULL, OPEN_EXISTING,
1712 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1713 NULL);
1714 if (hFile2 == INVALID_HANDLE_VALUE)
1715 return -1;
1716
1717 if (!get_target_path(hFile2, &target_path))
1718 return -1;
1719
1720 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001721 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 return code;
1723 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001724 } else
1725 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001726 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728
1729 /* Set S_IEXEC if it is an .exe, .bat, ... */
1730 dot = strrchr(path, '.');
1731 if (dot) {
1732 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1733 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1734 result->st_mode |= 0111;
1735 }
1736 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001737}
1738
1739static int
Brian Curtind25aef52011-06-13 15:16:04 -05001740win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1741 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001742{
1743 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001744 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001745 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001746 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001747 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 const wchar_t *dot;
1749
Brian Curtind25aef52011-06-13 15:16:04 -05001750 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001751 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1752 traverse reparse point. */
1753 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001754 }
1755
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 hFile = CreateFileW(
1757 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001758 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759 0, /* share mode */
1760 NULL, /* security attributes */
1761 OPEN_EXISTING,
1762 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001763 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1764 Because of this, calls like GetFinalPathNameByHandle will return
1765 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001766 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001767 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768 NULL);
1769
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771 /* Either the target doesn't exist, or we don't have access to
1772 get a handle to it. If the former, we need to return an error.
1773 If the latter, we can use attributes_from_dir. */
1774 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 return -1;
1776 /* Could not get attributes on open file. Fall back to
1777 reading the directory. */
1778 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1779 /* Very strange. This should not fail now */
1780 return -1;
1781 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1782 if (traverse) {
1783 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001784 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001786 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 } else {
1789 if (!GetFileInformationByHandle(hFile, &info)) {
1790 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001791 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001792 }
1793 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001794 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1795 return -1;
1796
1797 /* Close the outer open file handle now that we're about to
1798 reopen it with different flags. */
1799 if (!CloseHandle(hFile))
1800 return -1;
1801
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001802 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001803 /* In order to call GetFinalPathNameByHandle we need to open
1804 the file without the reparse handling flag set. */
1805 hFile2 = CreateFileW(
1806 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1807 NULL, OPEN_EXISTING,
1808 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1809 NULL);
1810 if (hFile2 == INVALID_HANDLE_VALUE)
1811 return -1;
1812
1813 if (!get_target_path(hFile2, &target_path))
1814 return -1;
1815
1816 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001817 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818 return code;
1819 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001820 } else
1821 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001822 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001823 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001824
1825 /* Set S_IEXEC if it is an .exe, .bat, ... */
1826 dot = wcsrchr(path, '.');
1827 if (dot) {
1828 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1829 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1830 result->st_mode |= 0111;
1831 }
1832 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001833}
1834
1835static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001836win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001837{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001838 /* Protocol violation: we explicitly clear errno, instead of
1839 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001840 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001841 errno = 0;
1842 return code;
1843}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001844
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001845static int
1846win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1847{
1848 /* Protocol violation: we explicitly clear errno, instead of
1849 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001850 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001851 errno = 0;
1852 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001853}
Brian Curtind25aef52011-06-13 15:16:04 -05001854/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001855
1856 In Posix, stat automatically traverses symlinks and returns the stat
1857 structure for the target. In Windows, the equivalent GetFileAttributes by
1858 default does not traverse symlinks and instead returns attributes for
1859 the symlink.
1860
1861 Therefore, win32_lstat will get the attributes traditionally, and
1862 win32_stat will first explicitly resolve the symlink target and then will
1863 call win32_lstat on that result.
1864
Ezio Melotti4969f702011-03-15 05:59:46 +02001865 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001866
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001867static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001868win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001869{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001870 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
Victor Stinner8c62be82010-05-06 00:08:46 +00001873static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001874win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001875{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001876 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001877}
1878
1879static int
1880win32_stat(const char* path, struct win32_stat *result)
1881{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001883}
1884
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001885static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001886win32_stat_w(const wchar_t* path, struct win32_stat *result)
1887{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001888 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001889}
1890
1891static int
1892win32_fstat(int file_number, struct win32_stat *result)
1893{
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 BY_HANDLE_FILE_INFORMATION info;
1895 HANDLE h;
1896 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001897
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001898 if (!_PyVerify_fd(file_number))
1899 h = INVALID_HANDLE_VALUE;
1900 else
1901 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001902
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 /* Protocol violation: we explicitly clear errno, instead of
1904 setting it to a POSIX error. Callers should use GetLastError. */
1905 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001906
Victor Stinner8c62be82010-05-06 00:08:46 +00001907 if (h == INVALID_HANDLE_VALUE) {
1908 /* This is really a C library error (invalid file handle).
1909 We set the Win32 error to the closes one matching. */
1910 SetLastError(ERROR_INVALID_HANDLE);
1911 return -1;
1912 }
1913 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001914
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 type = GetFileType(h);
1916 if (type == FILE_TYPE_UNKNOWN) {
1917 DWORD error = GetLastError();
1918 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001919 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 }
1921 /* else: valid but unknown file */
1922 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001923
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 if (type != FILE_TYPE_DISK) {
1925 if (type == FILE_TYPE_CHAR)
1926 result->st_mode = _S_IFCHR;
1927 else if (type == FILE_TYPE_PIPE)
1928 result->st_mode = _S_IFIFO;
1929 return 0;
1930 }
1931
1932 if (!GetFileInformationByHandle(h, &info)) {
1933 return -1;
1934 }
1935
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001936 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1939 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001940}
1941
1942#endif /* MS_WINDOWS */
1943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001944PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001945"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001946This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001947 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1949\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001950Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1951or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001952\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001954
1955static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 {"st_mode", "protection bits"},
1957 {"st_ino", "inode"},
1958 {"st_dev", "device"},
1959 {"st_nlink", "number of hard links"},
1960 {"st_uid", "user ID of owner"},
1961 {"st_gid", "group ID of owner"},
1962 {"st_size", "total size, in bytes"},
1963 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1964 {NULL, "integer time of last access"},
1965 {NULL, "integer time of last modification"},
1966 {NULL, "integer time of last change"},
1967 {"st_atime", "time of last access"},
1968 {"st_mtime", "time of last modification"},
1969 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001970 {"st_atime_ns", "time of last access in nanoseconds"},
1971 {"st_mtime_ns", "time of last modification in nanoseconds"},
1972 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001976#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001981#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001982#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001984#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001985#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001987#endif
1988#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001990#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992};
1993
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001994#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001995#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001996#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001997#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001998#endif
1999
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002000#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002001#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2002#else
2003#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2004#endif
2005
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002006#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002007#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2008#else
2009#define ST_RDEV_IDX ST_BLOCKS_IDX
2010#endif
2011
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002012#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2013#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2014#else
2015#define ST_FLAGS_IDX ST_RDEV_IDX
2016#endif
2017
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002019#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002020#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002021#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002022#endif
2023
2024#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2025#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2026#else
2027#define ST_BIRTHTIME_IDX ST_GEN_IDX
2028#endif
2029
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 "stat_result", /* name */
2032 stat_result__doc__, /* doc */
2033 stat_result_fields,
2034 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035};
2036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2039This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002041or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002044
2045static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 {"f_bsize", },
2047 {"f_frsize", },
2048 {"f_blocks", },
2049 {"f_bfree", },
2050 {"f_bavail", },
2051 {"f_files", },
2052 {"f_ffree", },
2053 {"f_favail", },
2054 {"f_flag", },
2055 {"f_namemax",},
2056 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002057};
2058
2059static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 "statvfs_result", /* name */
2061 statvfs_result__doc__, /* doc */
2062 statvfs_result_fields,
2063 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002064};
2065
Ross Lagerwall7807c352011-03-17 20:20:30 +02002066#if defined(HAVE_WAITID) && !defined(__APPLE__)
2067PyDoc_STRVAR(waitid_result__doc__,
2068"waitid_result: Result from waitid.\n\n\
2069This object may be accessed either as a tuple of\n\
2070 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2071or via the attributes si_pid, si_uid, and so on.\n\
2072\n\
2073See os.waitid for more information.");
2074
2075static PyStructSequence_Field waitid_result_fields[] = {
2076 {"si_pid", },
2077 {"si_uid", },
2078 {"si_signo", },
2079 {"si_status", },
2080 {"si_code", },
2081 {0}
2082};
2083
2084static PyStructSequence_Desc waitid_result_desc = {
2085 "waitid_result", /* name */
2086 waitid_result__doc__, /* doc */
2087 waitid_result_fields,
2088 5
2089};
2090static PyTypeObject WaitidResultType;
2091#endif
2092
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002093static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002094static PyTypeObject StatResultType;
2095static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002096#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002097static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002098#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002099static newfunc structseq_new;
2100
2101static PyObject *
2102statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2103{
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 PyStructSequence *result;
2105 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002106
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 result = (PyStructSequence*)structseq_new(type, args, kwds);
2108 if (!result)
2109 return NULL;
2110 /* If we have been initialized from a tuple,
2111 st_?time might be set to None. Initialize it
2112 from the int slots. */
2113 for (i = 7; i <= 9; i++) {
2114 if (result->ob_item[i+3] == Py_None) {
2115 Py_DECREF(Py_None);
2116 Py_INCREF(result->ob_item[i]);
2117 result->ob_item[i+3] = result->ob_item[i];
2118 }
2119 }
2120 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002121}
2122
2123
2124
2125/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002126static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002127
2128PyDoc_STRVAR(stat_float_times__doc__,
2129"stat_float_times([newval]) -> oldval\n\n\
2130Determine whether os.[lf]stat represents time stamps as float objects.\n\
2131If newval is True, future calls to stat() return floats, if it is False,\n\
2132future calls return ints. \n\
2133If newval is omitted, return the current setting.\n");
2134
2135static PyObject*
2136stat_float_times(PyObject* self, PyObject *args)
2137{
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 int newval = -1;
2139 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2140 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002141 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2142 "stat_float_times() is deprecated",
2143 1))
2144 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 if (newval == -1)
2146 /* Return old value */
2147 return PyBool_FromLong(_stat_float_times);
2148 _stat_float_times = newval;
2149 Py_INCREF(Py_None);
2150 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002151}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002152
Larry Hastings6fe20b32012-04-19 15:07:49 -07002153static PyObject *billion = NULL;
2154
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002155static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002156fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002157{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002158 PyObject *s = _PyLong_FromTime_t(sec);
2159 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2160 PyObject *s_in_ns = NULL;
2161 PyObject *ns_total = NULL;
2162 PyObject *float_s = NULL;
2163
2164 if (!(s && ns_fractional))
2165 goto exit;
2166
2167 s_in_ns = PyNumber_Multiply(s, billion);
2168 if (!s_in_ns)
2169 goto exit;
2170
2171 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2172 if (!ns_total)
2173 goto exit;
2174
Victor Stinner4195b5c2012-02-08 23:03:19 +01002175 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002176 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2177 if (!float_s)
2178 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002179 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002180 else {
2181 float_s = s;
2182 Py_INCREF(float_s);
2183 }
2184
2185 PyStructSequence_SET_ITEM(v, index, s);
2186 PyStructSequence_SET_ITEM(v, index+3, float_s);
2187 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2188 s = NULL;
2189 float_s = NULL;
2190 ns_total = NULL;
2191exit:
2192 Py_XDECREF(s);
2193 Py_XDECREF(ns_fractional);
2194 Py_XDECREF(s_in_ns);
2195 Py_XDECREF(ns_total);
2196 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002197}
2198
Tim Peters5aa91602002-01-30 05:46:57 +00002199/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002200 (used by posix_stat() and posix_fstat()) */
2201static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002202_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002203{
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 unsigned long ansec, mnsec, cnsec;
2205 PyObject *v = PyStructSequence_New(&StatResultType);
2206 if (v == NULL)
2207 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002208
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002210#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002211 PyStructSequence_SET_ITEM(v, 1,
2212 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002215#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002216#ifdef MS_WINDOWS
2217 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2218#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002219 PyStructSequence_SET_ITEM(v, 2,
2220 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002221#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002222 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002223#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002224 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002225#if defined(MS_WINDOWS)
2226 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2227 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2228#else
2229 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2230 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2231#endif
Fred Drake699f3522000-06-29 21:12:41 +00002232#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002233 PyStructSequence_SET_ITEM(v, 6,
2234 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002235#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002237#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002238
Martin v. Löwis14694662006-02-03 12:54:16 +00002239#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 ansec = st->st_atim.tv_nsec;
2241 mnsec = st->st_mtim.tv_nsec;
2242 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002243#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 ansec = st->st_atimespec.tv_nsec;
2245 mnsec = st->st_mtimespec.tv_nsec;
2246 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002247#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 ansec = st->st_atime_nsec;
2249 mnsec = st->st_mtime_nsec;
2250 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002251#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002253#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002254 fill_time(v, 7, st->st_atime, ansec);
2255 fill_time(v, 8, st->st_mtime, mnsec);
2256 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002257
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002258#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2260 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002261#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002262#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002263 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2264 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002265#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002266#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2268 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002269#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002270#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002271 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2272 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002273#endif
2274#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002276 PyObject *val;
2277 unsigned long bsec,bnsec;
2278 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002280 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002281#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002282 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002283#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002284 if (_stat_float_times) {
2285 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2286 } else {
2287 val = PyLong_FromLong((long)bsec);
2288 }
2289 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2290 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002291 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002292#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002293#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2295 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002296#endif
Fred Drake699f3522000-06-29 21:12:41 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 if (PyErr_Occurred()) {
2299 Py_DECREF(v);
2300 return NULL;
2301 }
Fred Drake699f3522000-06-29 21:12:41 +00002302
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002304}
2305
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002306/* POSIX methods */
2307
Guido van Rossum94f6f721999-01-06 18:42:14 +00002308
2309static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002310posix_do_stat(char *function_name, path_t *path,
2311 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002312{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002313 STRUCT_STAT st;
2314 int result;
2315
2316#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2317 if (follow_symlinks_specified(function_name, follow_symlinks))
2318 return NULL;
2319#endif
2320
2321 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2322 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2323 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2324 return NULL;
2325
2326 Py_BEGIN_ALLOW_THREADS
2327 if (path->fd != -1)
2328 result = FSTAT(path->fd, &st);
2329 else
2330#ifdef MS_WINDOWS
2331 if (path->wide) {
2332 if (follow_symlinks)
2333 result = win32_stat_w(path->wide, &st);
2334 else
2335 result = win32_lstat_w(path->wide, &st);
2336 }
2337 else
2338#endif
2339#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2340 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2341 result = LSTAT(path->narrow, &st);
2342 else
2343#endif
2344#ifdef HAVE_FSTATAT
2345 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2346 result = fstatat(dir_fd, path->narrow, &st,
2347 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2348 else
2349#endif
2350 result = STAT(path->narrow, &st);
2351 Py_END_ALLOW_THREADS
2352
Victor Stinner292c8352012-10-30 02:17:38 +01002353 if (result != 0) {
2354 return path_error(path);
2355 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002356
2357 return _pystat_fromstructstat(&st);
2358}
2359
Larry Hastings31826802013-10-19 00:09:25 -07002360#ifdef HAVE_FSTATAT
2361 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2362#else
2363 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2364#endif
2365
2366
2367/*[python]
2368
2369class path_t_converter(CConverter):
2370
2371 type = "path_t"
2372 impl_by_reference = True
2373 parse_by_reference = True
2374
2375 converter = 'path_converter'
2376
2377 def converter_init(self, *, allow_fd=False, nullable=False):
2378 def strify(value):
2379 return str(int(bool(value)))
2380
2381 # right now path_t doesn't support default values.
2382 # to support a default value, you'll need to override initialize().
2383
2384 assert self.default is unspecified
2385
2386 self.nullable = nullable
2387 self.allow_fd = allow_fd
2388
2389 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2390 self.function.name,
2391 strify(nullable),
2392 strify(allow_fd),
2393 )
2394
2395 def cleanup(self):
2396 return "path_cleanup(&" + self.name + ");\n"
2397
2398
2399class dir_fd_converter(CConverter):
2400 type = 'int'
2401 converter = 'OS_STAT_DIR_FD_CONVERTER'
2402
2403 def converter_init(self):
2404 if self.default in (unspecified, None):
2405 self.c_default = 'DEFAULT_DIR_FD'
2406
2407
2408[python]*/
2409/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
2410
2411/*[clinic]
Larry Hastings31826802013-10-19 00:09:25 -07002412
2413os.stat -> object(doc_default='stat_result')
2414
2415 path : path_t(allow_fd=True)
2416 Path to be examined; can be string, bytes, or open-file-descriptor int.
2417
2418 *
2419
2420 dir_fd : dir_fd = None
2421 If not None, it should be a file descriptor open to a directory,
2422 and path should be a relative string; path will then be relative to
2423 that directory.
2424
2425 follow_symlinks: bool = True
2426 If False, and the last element of the path is a symbolic link,
2427 stat will examine the symbolic link itself instead of the file
2428 the link points to.
2429
2430Perform a stat system call on the given path.
2431
2432dir_fd and follow_symlinks may not be implemented
2433 on your platform. If they are unavailable, using them will raise a
2434 NotImplementedError.
2435
2436It's an error to use dir_fd or follow_symlinks when specifying path as
2437 an open file descriptor.
2438
2439[clinic]*/
2440
2441PyDoc_STRVAR(os_stat__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002442"stat(path, *, dir_fd=None, follow_symlinks=True)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002443"Perform a stat system call on the given path.\n"
2444"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002445" path\n"
2446" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2447" dir_fd\n"
2448" If not None, it should be a file descriptor open to a directory,\n"
2449" and path should be a relative string; path will then be relative to\n"
2450" that directory.\n"
2451" follow_symlinks\n"
2452" If False, and the last element of the path is a symbolic link,\n"
2453" stat will examine the symbolic link itself instead of the file\n"
2454" the link points to.\n"
2455"\n"
2456"dir_fd and follow_symlinks may not be implemented\n"
2457" on your platform. If they are unavailable, using them will raise a\n"
2458" NotImplementedError.\n"
2459"\n"
2460"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2461" an open file descriptor.");
2462
2463#define OS_STAT_METHODDEF \
2464 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002465
2466static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002467os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002468
2469static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002470os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002471{
Larry Hastings31826802013-10-19 00:09:25 -07002472 PyObject *return_value = NULL;
2473 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2474 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002475 int dir_fd = DEFAULT_DIR_FD;
2476 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002477
Larry Hastings31826802013-10-19 00:09:25 -07002478 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2479 "O&|$O&p:stat", _keywords,
2480 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2481 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002482 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002483
2484exit:
2485 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002486 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002487
Larry Hastings9cf065c2012-06-22 16:30:09 -07002488 return return_value;
2489}
2490
Larry Hastings31826802013-10-19 00:09:25 -07002491static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002492os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002493/*[clinic checksum: 85a71ad602e89f8e280118da976f70cd2f9abdf1]*/
Larry Hastings31826802013-10-19 00:09:25 -07002494{
2495 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2496}
2497
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498PyDoc_STRVAR(posix_lstat__doc__,
2499"lstat(path, *, dir_fd=None) -> stat result\n\n\
2500Like stat(), but do not follow symbolic links.\n\
2501Equivalent to stat(path, follow_symlinks=False).");
2502
2503static PyObject *
2504posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2505{
2506 static char *keywords[] = {"path", "dir_fd", NULL};
2507 path_t path;
2508 int dir_fd = DEFAULT_DIR_FD;
2509 int follow_symlinks = 0;
2510 PyObject *return_value;
2511
2512 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002513 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2515 path_converter, &path,
2516#ifdef HAVE_FSTATAT
2517 dir_fd_converter, &dir_fd
2518#else
2519 dir_fd_unavailable, &dir_fd
2520#endif
2521 ))
2522 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002523 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002524 path_cleanup(&path);
2525 return return_value;
2526}
2527
Larry Hastings31826802013-10-19 00:09:25 -07002528
2529#ifdef HAVE_FACCESSAT
2530 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2531#else
2532 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2533#endif
2534/*[clinic]
2535os.access -> object(doc_default='True if granted, False otherwise')
2536
2537 path: path_t(allow_fd=True)
2538 Path to be tested; can be string, bytes, or open-file-descriptor int.
2539
2540 mode: int
2541 Operating-system mode bitfield. Can be F_OK to test existence,
2542 or the inclusive-OR of R_OK, W_OK, and X_OK.
2543
2544 *
2545
2546 dir_fd : dir_fd = None
2547 If not None, it should be a file descriptor open to a directory,
2548 and path should be relative; path will then be relative to that
2549 directory.
2550
2551 effective_ids: bool = False
2552 If True, access will use the effective uid/gid instead of
2553 the real uid/gid.
2554
2555 follow_symlinks: bool = True
2556 If False, and the last element of the path is a symbolic link,
2557 access will examine the symbolic link itself instead of the file
2558 the link points to.
2559
2560Use the real uid/gid to test for access to a path.
2561
2562{parameters}
2563dir_fd, effective_ids, and follow_symlinks may not be implemented
2564 on your platform. If they are unavailable, using them will raise a
2565 NotImplementedError.
2566
2567Note that most operations will use the effective uid/gid, therefore this
2568 routine can be used in a suid/sgid environment to test if the invoking user
2569 has the specified access to the path.
2570
2571[clinic]*/
2572
2573PyDoc_STRVAR(os_access__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002574"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002575"Use the real uid/gid to test for access to a path.\n"
2576"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002577" path\n"
2578" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2579" mode\n"
2580" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2581" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2582" dir_fd\n"
2583" If not None, it should be a file descriptor open to a directory,\n"
2584" and path should be relative; path will then be relative to that\n"
2585" directory.\n"
2586" effective_ids\n"
2587" If True, access will use the effective uid/gid instead of\n"
2588" the real uid/gid.\n"
2589" follow_symlinks\n"
2590" If False, and the last element of the path is a symbolic link,\n"
2591" access will examine the symbolic link itself instead of the file\n"
2592" the link points to.\n"
2593"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002594"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2595" on your platform. If they are unavailable, using them will raise a\n"
2596" NotImplementedError.\n"
2597"\n"
2598"Note that most operations will use the effective uid/gid, therefore this\n"
2599" routine can be used in a suid/sgid environment to test if the invoking user\n"
2600" has the specified access to the path.");
2601
2602#define OS_ACCESS_METHODDEF \
2603 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604
2605static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002606os_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 -07002607
2608static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002609os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610{
Larry Hastings31826802013-10-19 00:09:25 -07002611 PyObject *return_value = NULL;
2612 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2613 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002614 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002615 int dir_fd = DEFAULT_DIR_FD;
2616 int effective_ids = 0;
2617 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002618
2619 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2620 "O&i|$O&pp:access", _keywords,
2621 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2622 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002623 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002624
2625exit:
2626 /* Cleanup for path */
2627 path_cleanup(&path);
2628
2629 return return_value;
2630}
2631
2632static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002633os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002634/*[clinic checksum: 636e835c36562a2fc11acab75314634127fdf769]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002637
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002638#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002639 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002640#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002642#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644#ifndef HAVE_FACCESSAT
2645 if (follow_symlinks_specified("access", follow_symlinks))
2646 goto exit;
2647
2648 if (effective_ids) {
2649 argument_unavailable_error("access", "effective_ids");
2650 goto exit;
2651 }
2652#endif
2653
2654#ifdef MS_WINDOWS
2655 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002656 if (path->wide != NULL)
2657 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002659 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 Py_END_ALLOW_THREADS
2661
2662 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002663 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002664 * * we didn't get a -1, and
2665 * * write access wasn't requested,
2666 * * or the file isn't read-only,
2667 * * or it's a directory.
2668 * (Directories cannot be read-only on Windows.)
2669 */
2670 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002671 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002672 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002673 !(attr & FILE_ATTRIBUTE_READONLY) ||
2674 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2675#else
2676
2677 Py_BEGIN_ALLOW_THREADS
2678#ifdef HAVE_FACCESSAT
2679 if ((dir_fd != DEFAULT_DIR_FD) ||
2680 effective_ids ||
2681 !follow_symlinks) {
2682 int flags = 0;
2683 if (!follow_symlinks)
2684 flags |= AT_SYMLINK_NOFOLLOW;
2685 if (effective_ids)
2686 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002687 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002688 }
2689 else
2690#endif
Larry Hastings31826802013-10-19 00:09:25 -07002691 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692 Py_END_ALLOW_THREADS
2693 return_value = PyBool_FromLong(!result);
2694#endif
2695
2696#ifndef HAVE_FACCESSAT
2697exit:
2698#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002699 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002700}
2701
Guido van Rossumd371ff11999-01-25 16:12:23 +00002702#ifndef F_OK
2703#define F_OK 0
2704#endif
2705#ifndef R_OK
2706#define R_OK 4
2707#endif
2708#ifndef W_OK
2709#define W_OK 2
2710#endif
2711#ifndef X_OK
2712#define X_OK 1
2713#endif
2714
Larry Hastings31826802013-10-19 00:09:25 -07002715
Guido van Rossumd371ff11999-01-25 16:12:23 +00002716#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002717
2718/*[clinic]
2719os.ttyname -> DecodeFSDefault
2720
2721 fd: int
2722 Integer file descriptor handle.
2723
2724 /
2725
2726Return the name of the terminal device connected to 'fd'.
2727[clinic]*/
2728
2729PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002730"ttyname(fd)\n"
Larry Hastings31826802013-10-19 00:09:25 -07002731"Return the name of the terminal device connected to \'fd\'.\n"
2732"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002733" fd\n"
2734" Integer file descriptor handle.");
2735
2736#define OS_TTYNAME_METHODDEF \
2737 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2738
2739static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002740os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002741
2742static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002743os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002744{
Larry Hastings31826802013-10-19 00:09:25 -07002745 PyObject *return_value = NULL;
2746 int fd;
2747 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002748
Larry Hastings31826802013-10-19 00:09:25 -07002749 if (!PyArg_ParseTuple(args,
2750 "i:ttyname",
2751 &fd))
2752 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002753 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002754 if (_return_value == NULL)
2755 goto exit;
2756 return_value = PyUnicode_DecodeFSDefault(_return_value);
2757
2758exit:
2759 return return_value;
2760}
2761
2762static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002763os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002764/*[clinic checksum: 0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002765{
2766 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002767
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002768#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 /* file descriptor 0 only, the default input device (stdin) */
Larry Hastings31826802013-10-19 00:09:25 -07002770 if (fd == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002771 ret = ttyname();
2772 }
2773 else {
2774 ret = NULL;
2775 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002776#else
Larry Hastings31826802013-10-19 00:09:25 -07002777 ret = ttyname(fd);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002779 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002780 posix_error();
2781 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002782}
Larry Hastings31826802013-10-19 00:09:25 -07002783#else
2784#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002786
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002787#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002789"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002791
2792static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002793posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002794{
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 char *ret;
2796 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002797
Greg Wardb48bc172000-03-01 21:51:56 +00002798#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002800#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002802#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002803 if (ret == NULL)
2804 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002805 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002806}
2807#endif
2808
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002809PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002810"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811Change the current working directory to the specified path.\n\
2812\n\
2813path may always be specified as a string.\n\
2814On some platforms, path may also be specified as an open file descriptor.\n\
2815 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Barry Warsaw53699e91996-12-10 23:23:01 +00002817static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002819{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 path_t path;
2821 int result;
2822 PyObject *return_value = NULL;
2823 static char *keywords[] = {"path", NULL};
2824
2825 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002826 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827#ifdef HAVE_FCHDIR
2828 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002829#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2831 path_converter, &path
2832 ))
2833 return NULL;
2834
2835 Py_BEGIN_ALLOW_THREADS
2836#ifdef MS_WINDOWS
2837 if (path.wide)
2838 result = win32_wchdir(path.wide);
2839 else
2840 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002841 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842#else
2843#ifdef HAVE_FCHDIR
2844 if (path.fd != -1)
2845 result = fchdir(path.fd);
2846 else
2847#endif
2848 result = chdir(path.narrow);
2849#endif
2850 Py_END_ALLOW_THREADS
2851
2852 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002853 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 goto exit;
2855 }
2856
2857 return_value = Py_None;
2858 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002859
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860exit:
2861 path_cleanup(&path);
2862 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002863}
2864
Fred Drake4d1e64b2002-04-15 19:40:07 +00002865#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002866PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867"fchdir(fd)\n\n\
2868Change to the directory of the given file descriptor. fd must be\n\
2869opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002870
2871static PyObject *
2872posix_fchdir(PyObject *self, PyObject *fdobj)
2873{
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002875}
2876#endif /* HAVE_FCHDIR */
2877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2881Change the access permissions of a file.\n\
2882\n\
2883path may always be specified as a string.\n\
2884On some platforms, path may also be specified as an open file descriptor.\n\
2885 If this functionality is unavailable, using it raises an exception.\n\
2886If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2887 and path should be relative; path will then be relative to that directory.\n\
2888If follow_symlinks is False, and the last element of the path is a symbolic\n\
2889 link, chmod will modify the symbolic link itself instead of the file the\n\
2890 link points to.\n\
2891It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2892 an open file descriptor.\n\
2893dir_fd and follow_symlinks may not be implemented on your platform.\n\
2894 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002895
Barry Warsaw53699e91996-12-10 23:23:01 +00002896static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002898{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899 path_t path;
2900 int mode;
2901 int dir_fd = DEFAULT_DIR_FD;
2902 int follow_symlinks = 1;
2903 int result;
2904 PyObject *return_value = NULL;
2905 static char *keywords[] = {"path", "mode", "dir_fd",
2906 "follow_symlinks", NULL};
2907
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002908#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002911
Larry Hastings9cf065c2012-06-22 16:30:09 -07002912#ifdef HAVE_FCHMODAT
2913 int fchmodat_nofollow_unsupported = 0;
2914#endif
2915
2916 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002917 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918#ifdef HAVE_FCHMOD
2919 path.allow_fd = 1;
2920#endif
2921 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2922 path_converter, &path,
2923 &mode,
2924#ifdef HAVE_FCHMODAT
2925 dir_fd_converter, &dir_fd,
2926#else
2927 dir_fd_unavailable, &dir_fd,
2928#endif
2929 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931
2932#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2933 if (follow_symlinks_specified("chmod", follow_symlinks))
2934 goto exit;
2935#endif
2936
2937#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002939 if (path.wide)
2940 attr = GetFileAttributesW(path.wide);
2941 else
2942 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002943 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944 result = 0;
2945 else {
2946 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002947 attr &= ~FILE_ATTRIBUTE_READONLY;
2948 else
2949 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002950 if (path.wide)
2951 result = SetFileAttributesW(path.wide, attr);
2952 else
2953 result = SetFileAttributesA(path.narrow, attr);
2954 }
2955 Py_END_ALLOW_THREADS
2956
2957 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002958 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 goto exit;
2960 }
2961#else /* MS_WINDOWS */
2962 Py_BEGIN_ALLOW_THREADS
2963#ifdef HAVE_FCHMOD
2964 if (path.fd != -1)
2965 result = fchmod(path.fd, mode);
2966 else
2967#endif
2968#ifdef HAVE_LCHMOD
2969 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2970 result = lchmod(path.narrow, mode);
2971 else
2972#endif
2973#ifdef HAVE_FCHMODAT
2974 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2975 /*
2976 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2977 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002978 * and then says it isn't implemented yet.
2979 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980 *
2981 * Once it is supported, os.chmod will automatically
2982 * support dir_fd and follow_symlinks=False. (Hopefully.)
2983 * Until then, we need to be careful what exception we raise.
2984 */
2985 result = fchmodat(dir_fd, path.narrow, mode,
2986 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2987 /*
2988 * But wait! We can't throw the exception without allowing threads,
2989 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2990 */
2991 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002992 result &&
2993 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2994 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 }
2996 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002997#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998 result = chmod(path.narrow, mode);
2999 Py_END_ALLOW_THREADS
3000
3001 if (result) {
3002#ifdef HAVE_FCHMODAT
3003 if (fchmodat_nofollow_unsupported) {
3004 if (dir_fd != DEFAULT_DIR_FD)
3005 dir_fd_and_follow_symlinks_invalid("chmod",
3006 dir_fd, follow_symlinks);
3007 else
3008 follow_symlinks_specified("chmod", follow_symlinks);
3009 }
3010 else
3011#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003012 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003013 goto exit;
3014 }
3015#endif
3016
3017 Py_INCREF(Py_None);
3018 return_value = Py_None;
3019exit:
3020 path_cleanup(&path);
3021 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003022}
3023
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024
Christian Heimes4e30a842007-11-30 22:12:06 +00003025#ifdef HAVE_FCHMOD
3026PyDoc_STRVAR(posix_fchmod__doc__,
3027"fchmod(fd, mode)\n\n\
3028Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003029descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003030
3031static PyObject *
3032posix_fchmod(PyObject *self, PyObject *args)
3033{
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 int fd, mode, res;
3035 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3036 return NULL;
3037 Py_BEGIN_ALLOW_THREADS
3038 res = fchmod(fd, mode);
3039 Py_END_ALLOW_THREADS
3040 if (res < 0)
3041 return posix_error();
3042 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003043}
3044#endif /* HAVE_FCHMOD */
3045
3046#ifdef HAVE_LCHMOD
3047PyDoc_STRVAR(posix_lchmod__doc__,
3048"lchmod(path, mode)\n\n\
3049Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050affects the link itself rather than the target.\n\
3051Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003052
3053static PyObject *
3054posix_lchmod(PyObject *self, PyObject *args)
3055{
Victor Stinner292c8352012-10-30 02:17:38 +01003056 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003057 int i;
3058 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003059 memset(&path, 0, sizeof(path));
3060 path.function_name = "lchmod";
3061 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3062 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003063 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003065 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003066 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003067 if (res < 0) {
3068 path_error(&path);
3069 path_cleanup(&path);
3070 return NULL;
3071 }
3072 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003073 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003074}
3075#endif /* HAVE_LCHMOD */
3076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003077
Thomas Wouterscf297e42007-02-23 15:07:44 +00003078#ifdef HAVE_CHFLAGS
3079PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080"chflags(path, flags, *, follow_symlinks=True)\n\n\
3081Set file flags.\n\
3082\n\
3083If follow_symlinks is False, and the last element of the path is a symbolic\n\
3084 link, chflags will change flags on the symbolic link itself instead of the\n\
3085 file the link points to.\n\
3086follow_symlinks may not be implemented on your platform. If it is\n\
3087unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003088
3089static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003091{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003094 int follow_symlinks = 1;
3095 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003096 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3098
3099 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003100 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003101 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3102 path_converter, &path,
3103 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105
3106#ifndef HAVE_LCHFLAGS
3107 if (follow_symlinks_specified("chflags", follow_symlinks))
3108 goto exit;
3109#endif
3110
Victor Stinner8c62be82010-05-06 00:08:46 +00003111 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112#ifdef HAVE_LCHFLAGS
3113 if (!follow_symlinks)
3114 result = lchflags(path.narrow, flags);
3115 else
3116#endif
3117 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003118 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119
3120 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003121 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122 goto exit;
3123 }
3124
3125 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127
3128exit:
3129 path_cleanup(&path);
3130 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003131}
3132#endif /* HAVE_CHFLAGS */
3133
3134#ifdef HAVE_LCHFLAGS
3135PyDoc_STRVAR(posix_lchflags__doc__,
3136"lchflags(path, flags)\n\n\
3137Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138This function will not follow symbolic links.\n\
3139Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003140
3141static PyObject *
3142posix_lchflags(PyObject *self, PyObject *args)
3143{
Victor Stinner292c8352012-10-30 02:17:38 +01003144 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003145 unsigned long flags;
3146 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003147 memset(&path, 0, sizeof(path));
3148 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003150 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003153 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003154 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003155 if (res < 0) {
3156 path_error(&path);
3157 path_cleanup(&path);
3158 return NULL;
3159 }
3160 path_cleanup(&path);
3161 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003162}
3163#endif /* HAVE_LCHFLAGS */
3164
Martin v. Löwis244edc82001-10-04 22:44:26 +00003165#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003166PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003167"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003168Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003169
3170static PyObject *
3171posix_chroot(PyObject *self, PyObject *args)
3172{
Victor Stinner292c8352012-10-30 02:17:38 +01003173 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003174}
3175#endif
3176
Guido van Rossum21142a01999-01-08 21:05:37 +00003177#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003179"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003181
3182static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003183posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003184{
Stefan Krah0e803b32010-11-26 16:16:47 +00003185 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003186}
3187#endif /* HAVE_FSYNC */
3188
Ross Lagerwall7807c352011-03-17 20:20:30 +02003189#ifdef HAVE_SYNC
3190PyDoc_STRVAR(posix_sync__doc__,
3191"sync()\n\n\
3192Force write of everything to disk.");
3193
3194static PyObject *
3195posix_sync(PyObject *self, PyObject *noargs)
3196{
3197 Py_BEGIN_ALLOW_THREADS
3198 sync();
3199 Py_END_ALLOW_THREADS
3200 Py_RETURN_NONE;
3201}
3202#endif
3203
Guido van Rossum21142a01999-01-08 21:05:37 +00003204#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003205
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003206#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003207extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3208#endif
3209
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003211"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003212force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003213 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003214
3215static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003216posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003217{
Stefan Krah0e803b32010-11-26 16:16:47 +00003218 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003219}
3220#endif /* HAVE_FDATASYNC */
3221
3222
Fredrik Lundh10723342000-07-10 16:38:09 +00003223#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003224PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3226Change the owner and group id of path to the numeric uid and gid.\n\
3227\n\
3228path may always be specified as a string.\n\
3229On some platforms, path may also be specified as an open file descriptor.\n\
3230 If this functionality is unavailable, using it raises an exception.\n\
3231If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3232 and path should be relative; path will then be relative to that directory.\n\
3233If follow_symlinks is False, and the last element of the path is a symbolic\n\
3234 link, chown will modify the symbolic link itself instead of the file the\n\
3235 link points to.\n\
3236It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3237 an open file descriptor.\n\
3238dir_fd and follow_symlinks may not be implemented on your platform.\n\
3239 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003240
Barry Warsaw53699e91996-12-10 23:23:01 +00003241static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003243{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003244 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 uid_t uid;
3246 gid_t gid;
3247 int dir_fd = DEFAULT_DIR_FD;
3248 int follow_symlinks = 1;
3249 int result;
3250 PyObject *return_value = NULL;
3251 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3252 "follow_symlinks", NULL};
3253
3254 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003255 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256#ifdef HAVE_FCHOWN
3257 path.allow_fd = 1;
3258#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003259 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003261 _Py_Uid_Converter, &uid,
3262 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003263#ifdef HAVE_FCHOWNAT
3264 dir_fd_converter, &dir_fd,
3265#else
3266 dir_fd_unavailable, &dir_fd,
3267#endif
3268 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270
3271#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3272 if (follow_symlinks_specified("chown", follow_symlinks))
3273 goto exit;
3274#endif
3275 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3276 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3277 goto exit;
3278
3279#ifdef __APPLE__
3280 /*
3281 * This is for Mac OS X 10.3, which doesn't have lchown.
3282 * (But we still have an lchown symbol because of weak-linking.)
3283 * It doesn't have fchownat either. So there's no possibility
3284 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003285 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286 if ((!follow_symlinks) && (lchown == NULL)) {
3287 follow_symlinks_specified("chown", follow_symlinks);
3288 goto exit;
3289 }
3290#endif
3291
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293#ifdef HAVE_FCHOWN
3294 if (path.fd != -1)
3295 result = fchown(path.fd, uid, gid);
3296 else
3297#endif
3298#ifdef HAVE_LCHOWN
3299 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3300 result = lchown(path.narrow, uid, gid);
3301 else
3302#endif
3303#ifdef HAVE_FCHOWNAT
3304 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3305 result = fchownat(dir_fd, path.narrow, uid, gid,
3306 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3307 else
3308#endif
3309 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311
3312 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003313 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003314 goto exit;
3315 }
3316
3317 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319
3320exit:
3321 path_cleanup(&path);
3322 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003323}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003324#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003325
Christian Heimes4e30a842007-11-30 22:12:06 +00003326#ifdef HAVE_FCHOWN
3327PyDoc_STRVAR(posix_fchown__doc__,
3328"fchown(fd, uid, gid)\n\n\
3329Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003331
3332static PyObject *
3333posix_fchown(PyObject *self, PyObject *args)
3334{
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003336 uid_t uid;
3337 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003339 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3340 _Py_Uid_Converter, &uid,
3341 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 return NULL;
3343 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003344 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 Py_END_ALLOW_THREADS
3346 if (res < 0)
3347 return posix_error();
3348 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003349}
3350#endif /* HAVE_FCHOWN */
3351
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003352#ifdef HAVE_LCHOWN
3353PyDoc_STRVAR(posix_lchown__doc__,
3354"lchown(path, uid, gid)\n\n\
3355Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356This function will not follow symbolic links.\n\
3357Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003358
3359static PyObject *
3360posix_lchown(PyObject *self, PyObject *args)
3361{
Victor Stinner292c8352012-10-30 02:17:38 +01003362 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003363 uid_t uid;
3364 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003366 memset(&path, 0, sizeof(path));
3367 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003368 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003369 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003370 _Py_Uid_Converter, &uid,
3371 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003374 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003376 if (res < 0) {
3377 path_error(&path);
3378 path_cleanup(&path);
3379 return NULL;
3380 }
3381 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 Py_INCREF(Py_None);
3383 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003384}
3385#endif /* HAVE_LCHOWN */
3386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003387
Barry Warsaw53699e91996-12-10 23:23:01 +00003388static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003389posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003390{
Victor Stinner8c62be82010-05-06 00:08:46 +00003391 char buf[1026];
3392 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003393
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003394#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 if (!use_bytes) {
3396 wchar_t wbuf[1026];
3397 wchar_t *wbuf2 = wbuf;
3398 PyObject *resobj;
3399 DWORD len;
3400 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003401 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 /* If the buffer is large enough, len does not include the
3403 terminating \0. If the buffer is too small, len includes
3404 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003405 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003406 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 if (wbuf2)
3408 len = GetCurrentDirectoryW(len, wbuf2);
3409 }
3410 Py_END_ALLOW_THREADS
3411 if (!wbuf2) {
3412 PyErr_NoMemory();
3413 return NULL;
3414 }
3415 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003416 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003417 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003418 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 }
3420 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003421 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003422 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 return resobj;
3424 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003425
3426 if (win32_warn_bytes_api())
3427 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003428#endif
3429
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 Py_END_ALLOW_THREADS
3433 if (res == NULL)
3434 return posix_error();
3435 if (use_bytes)
3436 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003437 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003438}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003439
3440PyDoc_STRVAR(posix_getcwd__doc__,
3441"getcwd() -> path\n\n\
3442Return a unicode string representing the current working directory.");
3443
3444static PyObject *
3445posix_getcwd_unicode(PyObject *self)
3446{
3447 return posix_getcwd(0);
3448}
3449
3450PyDoc_STRVAR(posix_getcwdb__doc__,
3451"getcwdb() -> path\n\n\
3452Return a bytes string representing the current working directory.");
3453
3454static PyObject *
3455posix_getcwd_bytes(PyObject *self)
3456{
3457 return posix_getcwd(1);
3458}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003459
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3461#define HAVE_LINK 1
3462#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003463
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003465PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3467Create a hard link to a file.\n\
3468\n\
3469If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3470 descriptor open to a directory, and the respective path string (src or dst)\n\
3471 should be relative; the path will then be relative to that directory.\n\
3472If follow_symlinks is False, and the last element of src is a symbolic\n\
3473 link, link will create a link to the symbolic link itself instead of the\n\
3474 file the link points to.\n\
3475src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3476 platform. If they are unavailable, using them will raise a\n\
3477 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003478
Barry Warsaw53699e91996-12-10 23:23:01 +00003479static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003481{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 path_t src, dst;
3483 int src_dir_fd = DEFAULT_DIR_FD;
3484 int dst_dir_fd = DEFAULT_DIR_FD;
3485 int follow_symlinks = 1;
3486 PyObject *return_value = NULL;
3487 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3488 "follow_symlinks", NULL};
3489#ifdef MS_WINDOWS
3490 BOOL result;
3491#else
3492 int result;
3493#endif
3494
3495 memset(&src, 0, sizeof(src));
3496 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003497 src.function_name = "link";
3498 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3500 path_converter, &src,
3501 path_converter, &dst,
3502 dir_fd_converter, &src_dir_fd,
3503 dir_fd_converter, &dst_dir_fd,
3504 &follow_symlinks))
3505 return NULL;
3506
3507#ifndef HAVE_LINKAT
3508 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3509 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3510 goto exit;
3511 }
3512#endif
3513
3514 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3515 PyErr_SetString(PyExc_NotImplementedError,
3516 "link: src and dst must be the same type");
3517 goto exit;
3518 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003519
Brian Curtin1b9df392010-11-24 20:24:31 +00003520#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 Py_BEGIN_ALLOW_THREADS
3522 if (src.wide)
3523 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3524 else
3525 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3526 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003527
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003529 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003531 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532#else
3533 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003534#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3536 (dst_dir_fd != DEFAULT_DIR_FD) ||
3537 (!follow_symlinks))
3538 result = linkat(src_dir_fd, src.narrow,
3539 dst_dir_fd, dst.narrow,
3540 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3541 else
3542#endif
3543 result = link(src.narrow, dst.narrow);
3544 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003545
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003547 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003549 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550#endif
3551
3552 return_value = Py_None;
3553 Py_INCREF(Py_None);
3554
3555exit:
3556 path_cleanup(&src);
3557 path_cleanup(&dst);
3558 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003559}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560#endif
3561
Brian Curtin1b9df392010-11-24 20:24:31 +00003562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003563
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003564PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003565"listdir(path='.') -> list_of_filenames\n\n\
3566Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003567The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568entries '.' and '..' even if they are present in the directory.\n\
3569\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003570path can be specified as either str or bytes. If path is bytes,\n\
3571 the filenames returned will also be bytes; in all other circumstances\n\
3572 the filenames returned will be str.\n\
3573On some platforms, path may also be specified as an open file descriptor;\n\
3574 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003576
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003577#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003578static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003579_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003580{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003582 PyObject *v;
3583 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3584 BOOL result;
3585 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003586 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 char *bufptr = namebuf;
3588 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003589 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 PyObject *po = NULL;
3591 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003596
Gregory P. Smith40a21602013-03-20 20:52:50 -07003597 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003598 po_wchars = L".";
3599 len = 1;
3600 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003601 po_wchars = path->wide;
3602 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003605 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 if (!wnamebuf) {
3607 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003610 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003612 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003613 if (wch != SEP && wch != ALTSEP && wch != L':')
3614 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 wcscpy(wnamebuf + len, L"*.*");
3616 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 if ((list = PyList_New(0)) == NULL) {
3618 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003620 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003622 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 if (hFindFile == INVALID_HANDLE_VALUE) {
3624 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 if (error == ERROR_FILE_NOT_FOUND)
3626 goto exit;
3627 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003628 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 }
3631 do {
3632 /* Skip over . and .. */
3633 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3634 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 v = PyUnicode_FromWideChar(wFileData.cFileName,
3636 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 Py_DECREF(list);
3639 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 break;
3641 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 Py_DECREF(list);
3645 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 break;
3647 }
3648 Py_DECREF(v);
3649 }
3650 Py_BEGIN_ALLOW_THREADS
3651 result = FindNextFileW(hFindFile, &wFileData);
3652 Py_END_ALLOW_THREADS
3653 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3654 it got to the end of the directory. */
3655 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003657 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003658 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003659 }
3660 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003661
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003664 strcpy(namebuf, path->narrow);
3665 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 if (len > 0) {
3667 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003668 if (ch != '\\' && ch != '/' && ch != ':')
3669 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 strcpy(namebuf + len, "*.*");
3671 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003672
Larry Hastings9cf065c2012-06-22 16:30:09 -07003673 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003674 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003675
Antoine Pitroub73caab2010-08-09 23:39:31 +00003676 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003678 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 if (hFindFile == INVALID_HANDLE_VALUE) {
3680 int error = GetLastError();
3681 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003682 goto exit;
3683 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003684 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 }
3687 do {
3688 /* Skip over . and .. */
3689 if (strcmp(FileData.cFileName, ".") != 0 &&
3690 strcmp(FileData.cFileName, "..") != 0) {
3691 v = PyBytes_FromString(FileData.cFileName);
3692 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 Py_DECREF(list);
3694 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 break;
3696 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003699 Py_DECREF(list);
3700 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 break;
3702 }
3703 Py_DECREF(v);
3704 }
3705 Py_BEGIN_ALLOW_THREADS
3706 result = FindNextFile(hFindFile, &FileData);
3707 Py_END_ALLOW_THREADS
3708 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3709 it got to the end of the directory. */
3710 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003712 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 }
3715 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717exit:
3718 if (hFindFile != INVALID_HANDLE_VALUE) {
3719 if (FindClose(hFindFile) == FALSE) {
3720 if (list != NULL) {
3721 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003722 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 }
3724 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003726 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003727
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003729} /* end of _listdir_windows_no_opendir */
3730
3731#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3732
3733static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003734_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003735{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003736 PyObject *v;
3737 DIR *dirp = NULL;
3738 struct dirent *ep;
3739 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003740#ifdef HAVE_FDOPENDIR
3741 int fd = -1;
3742#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003743
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003746 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003748 fd = _Py_dup(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 if (fd == -1) {
3750 list = posix_error();
3751 goto exit;
3752 }
3753
Larry Hastingsfdaea062012-06-25 04:42:23 -07003754 return_str = 1;
3755
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756 Py_BEGIN_ALLOW_THREADS
3757 dirp = fdopendir(fd);
3758 Py_END_ALLOW_THREADS
3759 }
3760 else
3761#endif
3762 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003763 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003764 if (path->narrow) {
3765 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003766 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003767 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003768 }
3769 else {
3770 name = ".";
3771 return_str = 1;
3772 }
3773
Larry Hastings9cf065c2012-06-22 16:30:09 -07003774 Py_BEGIN_ALLOW_THREADS
3775 dirp = opendir(name);
3776 Py_END_ALLOW_THREADS
3777 }
3778
3779 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003780 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003781#ifdef HAVE_FDOPENDIR
3782 if (fd != -1) {
3783 Py_BEGIN_ALLOW_THREADS
3784 close(fd);
3785 Py_END_ALLOW_THREADS
3786 }
3787#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788 goto exit;
3789 }
3790 if ((list = PyList_New(0)) == NULL) {
3791 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 }
3793 for (;;) {
3794 errno = 0;
3795 Py_BEGIN_ALLOW_THREADS
3796 ep = readdir(dirp);
3797 Py_END_ALLOW_THREADS
3798 if (ep == NULL) {
3799 if (errno == 0) {
3800 break;
3801 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003803 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003804 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 }
3806 }
3807 if (ep->d_name[0] == '.' &&
3808 (NAMLEN(ep) == 1 ||
3809 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3810 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003811 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003812 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3813 else
3814 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003816 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 break;
3818 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003819 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003821 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 break;
3823 }
3824 Py_DECREF(v);
3825 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003826
Larry Hastings9cf065c2012-06-22 16:30:09 -07003827exit:
3828 if (dirp != NULL) {
3829 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003830#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 if (fd > -1)
3832 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003833#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834 closedir(dirp);
3835 Py_END_ALLOW_THREADS
3836 }
3837
Larry Hastings9cf065c2012-06-22 16:30:09 -07003838 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003839} /* end of _posix_listdir */
3840#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003841
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003842static PyObject *
3843posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3844{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003845 path_t path;
3846 PyObject *list = NULL;
3847 static char *keywords[] = {"path", NULL};
3848 PyObject *return_value;
3849
3850 memset(&path, 0, sizeof(path));
3851 path.function_name = "listdir";
3852 path.nullable = 1;
3853#ifdef HAVE_FDOPENDIR
3854 path.allow_fd = 1;
3855 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003856#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003857
3858 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3859 path_converter, &path)) {
3860 return NULL;
3861 }
3862
3863#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3864 return_value = _listdir_windows_no_opendir(&path, list);
3865#else
3866 return_value = _posix_listdir(&path, list);
3867#endif
3868 path_cleanup(&path);
3869 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003870}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003871
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003872#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003873/* A helper function for abspath on win32 */
3874static PyObject *
3875posix__getfullpathname(PyObject *self, PyObject *args)
3876{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003877 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003878 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003880 PyObject *po;
3881
3882 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3883 {
3884 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003885 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003886 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 DWORD result;
3888 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003889
3890 wpath = PyUnicode_AsUnicode(po);
3891 if (wpath == NULL)
3892 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003894 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003896 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003897 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 if (!woutbufp)
3899 return PyErr_NoMemory();
3900 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3901 }
3902 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003903 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003904 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003905 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003907 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 return v;
3909 }
3910 /* Drop the argument parsing error as narrow strings
3911 are also valid. */
3912 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003913
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003914 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3915 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003917 if (win32_warn_bytes_api())
3918 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003919 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 outbuf, &temp)) {
3921 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 return NULL;
3923 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3925 return PyUnicode_Decode(outbuf, strlen(outbuf),
3926 Py_FileSystemDefaultEncoding, NULL);
3927 }
3928 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003929} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003930
Brian Curtind25aef52011-06-13 15:16:04 -05003931
Brian Curtinf5e76d02010-11-24 13:14:05 +00003932
Brian Curtind40e6f72010-07-08 21:39:08 +00003933/* A helper function for samepath on windows */
3934static PyObject *
3935posix__getfinalpathname(PyObject *self, PyObject *args)
3936{
3937 HANDLE hFile;
3938 int buf_size;
3939 wchar_t *target_path;
3940 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003941 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003942 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003943
Victor Stinnereb5657a2011-09-30 01:44:27 +02003944 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003945 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003946 path = PyUnicode_AsUnicode(po);
3947 if (path == NULL)
3948 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003949
3950 if(!check_GetFinalPathNameByHandle()) {
3951 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3952 NotImplementedError. */
3953 return PyErr_Format(PyExc_NotImplementedError,
3954 "GetFinalPathNameByHandle not available on this platform");
3955 }
3956
3957 hFile = CreateFileW(
3958 path,
3959 0, /* desired access */
3960 0, /* share mode */
3961 NULL, /* security attributes */
3962 OPEN_EXISTING,
3963 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3964 FILE_FLAG_BACKUP_SEMANTICS,
3965 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003966
Victor Stinnereb5657a2011-09-30 01:44:27 +02003967 if(hFile == INVALID_HANDLE_VALUE)
3968 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003969
3970 /* We have a good handle to the target, use it to determine the
3971 target path name. */
3972 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3973
3974 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003975 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003976
Victor Stinnerb6404912013-07-07 16:21:41 +02003977 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003978 if(!target_path)
3979 return PyErr_NoMemory();
3980
3981 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3982 buf_size, VOLUME_NAME_DOS);
3983 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003984 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003985
3986 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003987 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003988
3989 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003990 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003991 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003992 return result;
3993
3994} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003995
Brian Curtin95d028f2011-06-09 09:10:38 -05003996PyDoc_STRVAR(posix__isdir__doc__,
3997"Return true if the pathname refers to an existing directory.");
3998
Brian Curtin9c669cc2011-06-08 18:17:18 -05003999static PyObject *
4000posix__isdir(PyObject *self, PyObject *args)
4001{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004002 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004003 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004004 DWORD attributes;
4005
4006 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004007 wchar_t *wpath = PyUnicode_AsUnicode(po);
4008 if (wpath == NULL)
4009 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004010
4011 attributes = GetFileAttributesW(wpath);
4012 if (attributes == INVALID_FILE_ATTRIBUTES)
4013 Py_RETURN_FALSE;
4014 goto check;
4015 }
4016 /* Drop the argument parsing error as narrow strings
4017 are also valid. */
4018 PyErr_Clear();
4019
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004020 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004021 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004022 if (win32_warn_bytes_api())
4023 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004024 attributes = GetFileAttributesA(path);
4025 if (attributes == INVALID_FILE_ATTRIBUTES)
4026 Py_RETURN_FALSE;
4027
4028check:
4029 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4030 Py_RETURN_TRUE;
4031 else
4032 Py_RETURN_FALSE;
4033}
Tim Golden6b528062013-08-01 12:44:00 +01004034
4035PyDoc_STRVAR(posix__getvolumepathname__doc__,
4036"Return volume mount point of the specified path.");
4037
4038/* A helper function for ismount on windows */
4039static PyObject *
4040posix__getvolumepathname(PyObject *self, PyObject *args)
4041{
4042 PyObject *po, *result;
4043 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004044 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004045 BOOL ret;
4046
4047 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4048 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004049 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004050 if (path == NULL)
4051 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004052 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004053
4054 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004055 buflen = Py_MAX(buflen, MAX_PATH);
4056
4057 if (buflen > DWORD_MAX) {
4058 PyErr_SetString(PyExc_OverflowError, "path too long");
4059 return NULL;
4060 }
4061
4062 mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
Tim Golden6b528062013-08-01 12:44:00 +01004063 if (mountpath == NULL)
4064 return PyErr_NoMemory();
4065
4066 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004067 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004068 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004069 Py_END_ALLOW_THREADS
4070
4071 if (!ret) {
4072 result = win32_error_object("_getvolumepathname", po);
4073 goto exit;
4074 }
4075 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4076
4077exit:
4078 PyMem_Free(mountpath);
4079 return result;
4080}
4081/* end of posix__getvolumepathname */
4082
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004083#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4087Create a directory.\n\
4088\n\
4089If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4090 and path should be relative; path will then be relative to that directory.\n\
4091dir_fd may not be implemented on your platform.\n\
4092 If it is unavailable, using it will raise a NotImplementedError.\n\
4093\n\
4094The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004095
Barry Warsaw53699e91996-12-10 23:23:01 +00004096static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004098{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004099 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004100 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004101 int dir_fd = DEFAULT_DIR_FD;
4102 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4103 PyObject *return_value = NULL;
4104 int result;
4105
4106 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004107 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4109 path_converter, &path, &mode,
4110#ifdef HAVE_MKDIRAT
4111 dir_fd_converter, &dir_fd
4112#else
4113 dir_fd_unavailable, &dir_fd
4114#endif
4115 ))
4116 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004117
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004118#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120 if (path.wide)
4121 result = CreateDirectoryW(path.wide, NULL);
4122 else
4123 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004125
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004127 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 goto exit;
4129 }
4130#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132#if HAVE_MKDIRAT
4133 if (dir_fd != DEFAULT_DIR_FD)
4134 result = mkdirat(dir_fd, path.narrow, mode);
4135 else
4136#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004137#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004139#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004141#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004144 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145 goto exit;
4146 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004147#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 return_value = Py_None;
4149 Py_INCREF(Py_None);
4150exit:
4151 path_cleanup(&path);
4152 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004153}
4154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004155
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004156/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4157#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004158#include <sys/resource.h>
4159#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004160
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004161
4162#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004163PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004164"nice(inc) -> new_priority\n\n\
4165Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004166
Barry Warsaw53699e91996-12-10 23:23:01 +00004167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004168posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004169{
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004171
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4173 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004174
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 /* There are two flavours of 'nice': one that returns the new
4176 priority (as required by almost all standards out there) and the
4177 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4178 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004179
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 If we are of the nice family that returns the new priority, we
4181 need to clear errno before the call, and check if errno is filled
4182 before calling posix_error() on a returnvalue of -1, because the
4183 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004184
Victor Stinner8c62be82010-05-06 00:08:46 +00004185 errno = 0;
4186 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004187#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 if (value == 0)
4189 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004190#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004191 if (value == -1 && errno != 0)
4192 /* either nice() or getpriority() returned an error */
4193 return posix_error();
4194 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004196#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004197
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004198
4199#ifdef HAVE_GETPRIORITY
4200PyDoc_STRVAR(posix_getpriority__doc__,
4201"getpriority(which, who) -> current_priority\n\n\
4202Get program scheduling priority.");
4203
4204static PyObject *
4205posix_getpriority(PyObject *self, PyObject *args)
4206{
4207 int which, who, retval;
4208
4209 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4210 return NULL;
4211 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004212 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004213 if (errno != 0)
4214 return posix_error();
4215 return PyLong_FromLong((long)retval);
4216}
4217#endif /* HAVE_GETPRIORITY */
4218
4219
4220#ifdef HAVE_SETPRIORITY
4221PyDoc_STRVAR(posix_setpriority__doc__,
4222"setpriority(which, who, prio) -> None\n\n\
4223Set program scheduling priority.");
4224
4225static PyObject *
4226posix_setpriority(PyObject *self, PyObject *args)
4227{
4228 int which, who, prio, retval;
4229
4230 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4231 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004232 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004233 if (retval == -1)
4234 return posix_error();
4235 Py_RETURN_NONE;
4236}
4237#endif /* HAVE_SETPRIORITY */
4238
4239
Barry Warsaw53699e91996-12-10 23:23:01 +00004240static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004241internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004242{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243 char *function_name = is_replace ? "replace" : "rename";
4244 path_t src;
4245 path_t dst;
4246 int src_dir_fd = DEFAULT_DIR_FD;
4247 int dst_dir_fd = DEFAULT_DIR_FD;
4248 int dir_fd_specified;
4249 PyObject *return_value = NULL;
4250 char format[24];
4251 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4252
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004253#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004254 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004255 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004256#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004258#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004259
4260 memset(&src, 0, sizeof(src));
4261 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004262 src.function_name = function_name;
4263 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004264 strcpy(format, "O&O&|$O&O&:");
4265 strcat(format, function_name);
4266 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4267 path_converter, &src,
4268 path_converter, &dst,
4269 dir_fd_converter, &src_dir_fd,
4270 dir_fd_converter, &dst_dir_fd))
4271 return NULL;
4272
4273 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4274 (dst_dir_fd != DEFAULT_DIR_FD);
4275#ifndef HAVE_RENAMEAT
4276 if (dir_fd_specified) {
4277 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4278 goto exit;
4279 }
4280#endif
4281
4282 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4283 PyErr_Format(PyExc_ValueError,
4284 "%s: src and dst must be the same type", function_name);
4285 goto exit;
4286 }
4287
4288#ifdef MS_WINDOWS
4289 Py_BEGIN_ALLOW_THREADS
4290 if (src.wide)
4291 result = MoveFileExW(src.wide, dst.wide, flags);
4292 else
4293 result = MoveFileExA(src.narrow, dst.narrow, flags);
4294 Py_END_ALLOW_THREADS
4295
4296 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004297 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004298 goto exit;
4299 }
4300
4301#else
4302 Py_BEGIN_ALLOW_THREADS
4303#ifdef HAVE_RENAMEAT
4304 if (dir_fd_specified)
4305 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4306 else
4307#endif
4308 result = rename(src.narrow, dst.narrow);
4309 Py_END_ALLOW_THREADS
4310
4311 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004312 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004313 goto exit;
4314 }
4315#endif
4316
4317 Py_INCREF(Py_None);
4318 return_value = Py_None;
4319exit:
4320 path_cleanup(&src);
4321 path_cleanup(&dst);
4322 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004323}
4324
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004325PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4327Rename a file or directory.\n\
4328\n\
4329If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4330 descriptor open to a directory, and the respective path string (src or dst)\n\
4331 should be relative; the path will then be relative to that directory.\n\
4332src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4333 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004334
4335static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004337{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004338 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004339}
4340
4341PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004342"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4343Rename a file or directory, overwriting the destination.\n\
4344\n\
4345If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4346 descriptor open to a directory, and the respective path string (src or dst)\n\
4347 should be relative; the path will then be relative to that directory.\n\
4348src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4349 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004350
4351static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004353{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004355}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004358"rmdir(path, *, dir_fd=None)\n\n\
4359Remove a directory.\n\
4360\n\
4361If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4362 and path should be relative; path will then be relative to that directory.\n\
4363dir_fd may not be implemented on your platform.\n\
4364 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004365
Barry Warsaw53699e91996-12-10 23:23:01 +00004366static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004367posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004368{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004369 path_t path;
4370 int dir_fd = DEFAULT_DIR_FD;
4371 static char *keywords[] = {"path", "dir_fd", NULL};
4372 int result;
4373 PyObject *return_value = NULL;
4374
4375 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004376 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004377 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4378 path_converter, &path,
4379#ifdef HAVE_UNLINKAT
4380 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004381#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004382 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004383#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004384 ))
4385 return NULL;
4386
4387 Py_BEGIN_ALLOW_THREADS
4388#ifdef MS_WINDOWS
4389 if (path.wide)
4390 result = RemoveDirectoryW(path.wide);
4391 else
4392 result = RemoveDirectoryA(path.narrow);
4393 result = !result; /* Windows, success=1, UNIX, success=0 */
4394#else
4395#ifdef HAVE_UNLINKAT
4396 if (dir_fd != DEFAULT_DIR_FD)
4397 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4398 else
4399#endif
4400 result = rmdir(path.narrow);
4401#endif
4402 Py_END_ALLOW_THREADS
4403
4404 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004405 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004406 goto exit;
4407 }
4408
4409 return_value = Py_None;
4410 Py_INCREF(Py_None);
4411
4412exit:
4413 path_cleanup(&path);
4414 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415}
4416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004417
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004418#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004420"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004421Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Barry Warsaw53699e91996-12-10 23:23:01 +00004423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004424posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004425{
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004427#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 wchar_t *command;
4429 if (!PyArg_ParseTuple(args, "u:system", &command))
4430 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004431
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 Py_BEGIN_ALLOW_THREADS
4433 sts = _wsystem(command);
4434 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004435#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 PyObject *command_obj;
4437 char *command;
4438 if (!PyArg_ParseTuple(args, "O&:system",
4439 PyUnicode_FSConverter, &command_obj))
4440 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004441
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 command = PyBytes_AsString(command_obj);
4443 Py_BEGIN_ALLOW_THREADS
4444 sts = system(command);
4445 Py_END_ALLOW_THREADS
4446 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004447#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004448 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004449}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004450#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004452
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004453PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004454"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004455Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004456
Barry Warsaw53699e91996-12-10 23:23:01 +00004457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004458posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004459{
Victor Stinner8c62be82010-05-06 00:08:46 +00004460 int i;
4461 if (!PyArg_ParseTuple(args, "i:umask", &i))
4462 return NULL;
4463 i = (int)umask(i);
4464 if (i < 0)
4465 return posix_error();
4466 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004467}
4468
Brian Curtind40e6f72010-07-08 21:39:08 +00004469#ifdef MS_WINDOWS
4470
4471/* override the default DeleteFileW behavior so that directory
4472symlinks can be removed with this function, the same as with
4473Unix symlinks */
4474BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4475{
4476 WIN32_FILE_ATTRIBUTE_DATA info;
4477 WIN32_FIND_DATAW find_data;
4478 HANDLE find_data_handle;
4479 int is_directory = 0;
4480 int is_link = 0;
4481
4482 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4483 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004484
Brian Curtind40e6f72010-07-08 21:39:08 +00004485 /* Get WIN32_FIND_DATA structure for the path to determine if
4486 it is a symlink */
4487 if(is_directory &&
4488 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4489 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4490
4491 if(find_data_handle != INVALID_HANDLE_VALUE) {
4492 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4493 FindClose(find_data_handle);
4494 }
4495 }
4496 }
4497
4498 if (is_directory && is_link)
4499 return RemoveDirectoryW(lpFileName);
4500
4501 return DeleteFileW(lpFileName);
4502}
4503#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004505PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004506"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507Remove a file (same as remove()).\n\
4508\n\
4509If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4510 and path should be relative; path will then be relative to that directory.\n\
4511dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004512 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004515"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516Remove a file (same as unlink()).\n\
4517\n\
4518If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4519 and path should be relative; path will then be relative to that directory.\n\
4520dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004521 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004522
Barry Warsaw53699e91996-12-10 23:23:01 +00004523static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004525{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 path_t path;
4527 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004528 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 int result;
4530 PyObject *return_value = NULL;
4531
4532 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004533 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004534 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535 path_converter, &path,
4536#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004537 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004538#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004539 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004540#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004541 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 return NULL;
4543
4544 Py_BEGIN_ALLOW_THREADS
4545#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004546 if (path.wide)
4547 result = Py_DeleteFileW(path.wide);
4548 else
4549 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004550 result = !result; /* Windows, success=1, UNIX, success=0 */
4551#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552#ifdef HAVE_UNLINKAT
4553 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004554 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 else
4556#endif /* HAVE_UNLINKAT */
4557 result = unlink(path.narrow);
4558#endif
4559 Py_END_ALLOW_THREADS
4560
4561 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004562 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 goto exit;
4564 }
4565
4566 return_value = Py_None;
4567 Py_INCREF(Py_None);
4568
4569exit:
4570 path_cleanup(&path);
4571 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004572}
4573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004574
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004575PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004576"uname() -> uname_result\n\n\
4577Return an object identifying the current operating system.\n\
4578The object behaves like a named tuple with the following fields:\n\
4579 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004580
Larry Hastings605a62d2012-06-24 04:33:36 -07004581static PyStructSequence_Field uname_result_fields[] = {
4582 {"sysname", "operating system name"},
4583 {"nodename", "name of machine on network (implementation-defined)"},
4584 {"release", "operating system release"},
4585 {"version", "operating system version"},
4586 {"machine", "hardware identifier"},
4587 {NULL}
4588};
4589
4590PyDoc_STRVAR(uname_result__doc__,
4591"uname_result: Result from os.uname().\n\n\
4592This object may be accessed either as a tuple of\n\
4593 (sysname, nodename, release, version, machine),\n\
4594or via the attributes sysname, nodename, release, version, and machine.\n\
4595\n\
4596See os.uname for more information.");
4597
4598static PyStructSequence_Desc uname_result_desc = {
4599 "uname_result", /* name */
4600 uname_result__doc__, /* doc */
4601 uname_result_fields,
4602 5
4603};
4604
4605static PyTypeObject UnameResultType;
4606
4607
4608#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004609static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004610posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004611{
Victor Stinner8c62be82010-05-06 00:08:46 +00004612 struct utsname u;
4613 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004614 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004615
Victor Stinner8c62be82010-05-06 00:08:46 +00004616 Py_BEGIN_ALLOW_THREADS
4617 res = uname(&u);
4618 Py_END_ALLOW_THREADS
4619 if (res < 0)
4620 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004621
4622 value = PyStructSequence_New(&UnameResultType);
4623 if (value == NULL)
4624 return NULL;
4625
4626#define SET(i, field) \
4627 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004628 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004629 if (!o) { \
4630 Py_DECREF(value); \
4631 return NULL; \
4632 } \
4633 PyStructSequence_SET_ITEM(value, i, o); \
4634 } \
4635
4636 SET(0, u.sysname);
4637 SET(1, u.nodename);
4638 SET(2, u.release);
4639 SET(3, u.version);
4640 SET(4, u.machine);
4641
4642#undef SET
4643
4644 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004645}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004646#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004647
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649PyDoc_STRVAR(posix_utime__doc__,
4650"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4651Set the access and modified time of path.\n\
4652\n\
4653path may always be specified as a string.\n\
4654On some platforms, path may also be specified as an open file descriptor.\n\
4655 If this functionality is unavailable, using it raises an exception.\n\
4656\n\
4657If times is not None, it must be a tuple (atime, mtime);\n\
4658 atime and mtime should be expressed as float seconds since the epoch.\n\
4659If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4660 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4661 since the epoch.\n\
4662If both times and ns are None, utime uses the current time.\n\
4663Specifying tuples for both times and ns is an error.\n\
4664\n\
4665If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4666 and path should be relative; path will then be relative to that directory.\n\
4667If follow_symlinks is False, and the last element of the path is a symbolic\n\
4668 link, utime will modify the symbolic link itself instead of the file the\n\
4669 link points to.\n\
4670It is an error to use dir_fd or follow_symlinks when specifying path\n\
4671 as an open file descriptor.\n\
4672dir_fd and follow_symlinks may not be available on your platform.\n\
4673 If they are unavailable, using them will raise a NotImplementedError.");
4674
4675typedef struct {
4676 int now;
4677 time_t atime_s;
4678 long atime_ns;
4679 time_t mtime_s;
4680 long mtime_ns;
4681} utime_t;
4682
4683/*
4684 * these macros assume that "utime" is a pointer to a utime_t
4685 * they also intentionally leak the declaration of a pointer named "time"
4686 */
4687#define UTIME_TO_TIMESPEC \
4688 struct timespec ts[2]; \
4689 struct timespec *time; \
4690 if (utime->now) \
4691 time = NULL; \
4692 else { \
4693 ts[0].tv_sec = utime->atime_s; \
4694 ts[0].tv_nsec = utime->atime_ns; \
4695 ts[1].tv_sec = utime->mtime_s; \
4696 ts[1].tv_nsec = utime->mtime_ns; \
4697 time = ts; \
4698 } \
4699
4700#define UTIME_TO_TIMEVAL \
4701 struct timeval tv[2]; \
4702 struct timeval *time; \
4703 if (utime->now) \
4704 time = NULL; \
4705 else { \
4706 tv[0].tv_sec = utime->atime_s; \
4707 tv[0].tv_usec = utime->atime_ns / 1000; \
4708 tv[1].tv_sec = utime->mtime_s; \
4709 tv[1].tv_usec = utime->mtime_ns / 1000; \
4710 time = tv; \
4711 } \
4712
4713#define UTIME_TO_UTIMBUF \
4714 struct utimbuf u[2]; \
4715 struct utimbuf *time; \
4716 if (utime->now) \
4717 time = NULL; \
4718 else { \
4719 u.actime = utime->atime_s; \
4720 u.modtime = utime->mtime_s; \
4721 time = u; \
4722 }
4723
4724#define UTIME_TO_TIME_T \
4725 time_t timet[2]; \
4726 struct timet time; \
4727 if (utime->now) \
4728 time = NULL; \
4729 else { \
4730 timet[0] = utime->atime_s; \
4731 timet[1] = utime->mtime_s; \
4732 time = &timet; \
4733 } \
4734
4735
4736#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4737
4738#if UTIME_HAVE_DIR_FD
4739
4740static int
4741utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4742{
4743#ifdef HAVE_UTIMENSAT
4744 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4745 UTIME_TO_TIMESPEC;
4746 return utimensat(dir_fd, path, time, flags);
4747#elif defined(HAVE_FUTIMESAT)
4748 UTIME_TO_TIMEVAL;
4749 /*
4750 * follow_symlinks will never be false here;
4751 * we only allow !follow_symlinks and dir_fd together
4752 * if we have utimensat()
4753 */
4754 assert(follow_symlinks);
4755 return futimesat(dir_fd, path, time);
4756#endif
4757}
4758
4759#endif
4760
4761#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4762
4763#if UTIME_HAVE_FD
4764
4765static int
4766utime_fd(utime_t *utime, int fd)
4767{
4768#ifdef HAVE_FUTIMENS
4769 UTIME_TO_TIMESPEC;
4770 return futimens(fd, time);
4771#else
4772 UTIME_TO_TIMEVAL;
4773 return futimes(fd, time);
4774#endif
4775}
4776
4777#endif
4778
4779
4780#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4781 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4782
4783#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4784
4785static int
4786utime_nofollow_symlinks(utime_t *utime, char *path)
4787{
4788#ifdef HAVE_UTIMENSAT
4789 UTIME_TO_TIMESPEC;
4790 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4791#else
4792 UTIME_TO_TIMEVAL;
4793 return lutimes(path, time);
4794#endif
4795}
4796
4797#endif
4798
4799#ifndef MS_WINDOWS
4800
4801static int
4802utime_default(utime_t *utime, char *path)
4803{
4804#ifdef HAVE_UTIMENSAT
4805 UTIME_TO_TIMESPEC;
4806 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4807#elif defined(HAVE_UTIMES)
4808 UTIME_TO_TIMEVAL;
4809 return utimes(path, time);
4810#elif defined(HAVE_UTIME_H)
4811 UTIME_TO_UTIMBUF;
4812 return utime(path, time);
4813#else
4814 UTIME_TO_TIME_T;
4815 return utime(path, time);
4816#endif
4817}
4818
4819#endif
4820
Larry Hastings76ad59b2012-05-03 00:30:07 -07004821static int
4822split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4823{
4824 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004825 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004826 divmod = PyNumber_Divmod(py_long, billion);
4827 if (!divmod)
4828 goto exit;
4829 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4830 if ((*s == -1) && PyErr_Occurred())
4831 goto exit;
4832 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004833 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004834 goto exit;
4835
4836 result = 1;
4837exit:
4838 Py_XDECREF(divmod);
4839 return result;
4840}
4841
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842static PyObject *
4843posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004844{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004846 PyObject *times = NULL;
4847 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 int dir_fd = DEFAULT_DIR_FD;
4849 int follow_symlinks = 1;
4850 char *keywords[] = {"path", "times", "ns", "dir_fd",
4851 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004852
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004854
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855#ifdef MS_WINDOWS
4856 HANDLE hFile;
4857 FILETIME atime, mtime;
4858#else
4859 int result;
4860#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004861
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004863
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004865 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004866 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867#if UTIME_HAVE_FD
4868 path.allow_fd = 1;
4869#endif
4870 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4871 "O&|O$OO&p:utime", keywords,
4872 path_converter, &path,
4873 &times, &ns,
4874#if UTIME_HAVE_DIR_FD
4875 dir_fd_converter, &dir_fd,
4876#else
4877 dir_fd_unavailable, &dir_fd,
4878#endif
4879 &follow_symlinks
4880 ))
4881 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004882
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 if (times && (times != Py_None) && ns) {
4884 PyErr_SetString(PyExc_ValueError,
4885 "utime: you may specify either 'times'"
4886 " or 'ns' but not both");
4887 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888 }
4889
4890 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004891 time_t a_sec, m_sec;
4892 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004893 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 PyErr_SetString(PyExc_TypeError,
4895 "utime: 'times' must be either"
4896 " a tuple of two ints or None");
4897 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004898 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004900 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004901 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004902 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004903 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004904 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004905 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004906 utime.atime_s = a_sec;
4907 utime.atime_ns = a_nsec;
4908 utime.mtime_s = m_sec;
4909 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004910 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004912 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004913 PyErr_SetString(PyExc_TypeError,
4914 "utime: 'ns' must be a tuple of two ints");
4915 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004916 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004918 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004920 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921 &utime.mtime_s, &utime.mtime_ns)) {
4922 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004923 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924 }
4925 else {
4926 /* times and ns are both None/unspecified. use "now". */
4927 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004928 }
4929
Larry Hastings9cf065c2012-06-22 16:30:09 -07004930#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4931 if (follow_symlinks_specified("utime", follow_symlinks))
4932 goto exit;
4933#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004934
Larry Hastings9cf065c2012-06-22 16:30:09 -07004935 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4936 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4937 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4938 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004939
Larry Hastings9cf065c2012-06-22 16:30:09 -07004940#if !defined(HAVE_UTIMENSAT)
4941 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004942 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943 "utime: cannot use dir_fd and follow_symlinks "
4944 "together on this platform");
4945 goto exit;
4946 }
4947#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004948
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004949#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004950 Py_BEGIN_ALLOW_THREADS
4951 if (path.wide)
4952 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 NULL, OPEN_EXISTING,
4954 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 else
4956 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 NULL, OPEN_EXISTING,
4958 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004959 Py_END_ALLOW_THREADS
4960 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004961 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004962 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004963 }
4964
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004966 GetSystemTimeAsFileTime(&mtime);
4967 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004970 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4971 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 }
4973 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4974 /* Avoid putting the file name into the error here,
4975 as that may confuse the user into believing that
4976 something is wrong with the file, when it also
4977 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004978 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004981#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004983
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4985 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4986 result = utime_nofollow_symlinks(&utime, path.narrow);
4987 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004988#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004989
4990#if UTIME_HAVE_DIR_FD
4991 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4992 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4993 else
4994#endif
4995
4996#if UTIME_HAVE_FD
4997 if (path.fd != -1)
4998 result = utime_fd(&utime, path.fd);
4999 else
5000#endif
5001
5002 result = utime_default(&utime, path.narrow);
5003
5004 Py_END_ALLOW_THREADS
5005
5006 if (result < 0) {
5007 /* see previous comment about not putting filename in error here */
5008 return_value = posix_error();
5009 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005011
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005012#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013
5014 Py_INCREF(Py_None);
5015 return_value = Py_None;
5016
5017exit:
5018 path_cleanup(&path);
5019#ifdef MS_WINDOWS
5020 if (hFile != INVALID_HANDLE_VALUE)
5021 CloseHandle(hFile);
5022#endif
5023 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005024}
5025
Guido van Rossum3b066191991-06-04 19:40:25 +00005026/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005029"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005031
Barry Warsaw53699e91996-12-10 23:23:01 +00005032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005033posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005034{
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 int sts;
5036 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5037 return NULL;
5038 _exit(sts);
5039 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005040}
5041
Martin v. Löwis114619e2002-10-07 06:44:21 +00005042#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5043static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005044free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005045{
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 Py_ssize_t i;
5047 for (i = 0; i < count; i++)
5048 PyMem_Free(array[i]);
5049 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005050}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005051
Antoine Pitrou69f71142009-05-24 21:25:49 +00005052static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005053int fsconvert_strdup(PyObject *o, char**out)
5054{
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 PyObject *bytes;
5056 Py_ssize_t size;
5057 if (!PyUnicode_FSConverter(o, &bytes))
5058 return 0;
5059 size = PyBytes_GET_SIZE(bytes);
5060 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005061 if (!*out) {
5062 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005064 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 memcpy(*out, PyBytes_AsString(bytes), size+1);
5066 Py_DECREF(bytes);
5067 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005068}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005069#endif
5070
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005072static char**
5073parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5074{
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 char **envlist;
5076 Py_ssize_t i, pos, envc;
5077 PyObject *keys=NULL, *vals=NULL;
5078 PyObject *key, *val, *key2, *val2;
5079 char *p, *k, *v;
5080 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005081
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 i = PyMapping_Size(env);
5083 if (i < 0)
5084 return NULL;
5085 envlist = PyMem_NEW(char *, i + 1);
5086 if (envlist == NULL) {
5087 PyErr_NoMemory();
5088 return NULL;
5089 }
5090 envc = 0;
5091 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005092 if (!keys)
5093 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005095 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 goto error;
5097 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5098 PyErr_Format(PyExc_TypeError,
5099 "env.keys() or env.values() is not a list");
5100 goto error;
5101 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 for (pos = 0; pos < i; pos++) {
5104 key = PyList_GetItem(keys, pos);
5105 val = PyList_GetItem(vals, pos);
5106 if (!key || !val)
5107 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 if (PyUnicode_FSConverter(key, &key2) == 0)
5110 goto error;
5111 if (PyUnicode_FSConverter(val, &val2) == 0) {
5112 Py_DECREF(key2);
5113 goto error;
5114 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005115
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 k = PyBytes_AsString(key2);
5117 v = PyBytes_AsString(val2);
5118 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005119
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 p = PyMem_NEW(char, len);
5121 if (p == NULL) {
5122 PyErr_NoMemory();
5123 Py_DECREF(key2);
5124 Py_DECREF(val2);
5125 goto error;
5126 }
5127 PyOS_snprintf(p, len, "%s=%s", k, v);
5128 envlist[envc++] = p;
5129 Py_DECREF(key2);
5130 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 }
5132 Py_DECREF(vals);
5133 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005134
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 envlist[envc] = 0;
5136 *envc_ptr = envc;
5137 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005138
5139error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 Py_XDECREF(keys);
5141 Py_XDECREF(vals);
5142 while (--envc >= 0)
5143 PyMem_DEL(envlist[envc]);
5144 PyMem_DEL(envlist);
5145 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005146}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Ross Lagerwall7807c352011-03-17 20:20:30 +02005148static char**
5149parse_arglist(PyObject* argv, Py_ssize_t *argc)
5150{
5151 int i;
5152 char **argvlist = PyMem_NEW(char *, *argc+1);
5153 if (argvlist == NULL) {
5154 PyErr_NoMemory();
5155 return NULL;
5156 }
5157 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005158 PyObject* item = PySequence_ITEM(argv, i);
5159 if (item == NULL)
5160 goto fail;
5161 if (!fsconvert_strdup(item, &argvlist[i])) {
5162 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005163 goto fail;
5164 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005165 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005166 }
5167 argvlist[*argc] = NULL;
5168 return argvlist;
5169fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005170 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005171 free_string_array(argvlist, *argc);
5172 return NULL;
5173}
5174#endif
5175
5176#ifdef HAVE_EXECV
5177PyDoc_STRVAR(posix_execv__doc__,
5178"execv(path, args)\n\n\
5179Execute an executable path with arguments, replacing current process.\n\
5180\n\
5181 path: path of executable file\n\
5182 args: tuple or list of strings");
5183
5184static PyObject *
5185posix_execv(PyObject *self, PyObject *args)
5186{
5187 PyObject *opath;
5188 char *path;
5189 PyObject *argv;
5190 char **argvlist;
5191 Py_ssize_t argc;
5192
5193 /* execv has two arguments: (path, argv), where
5194 argv is a list or tuple of strings. */
5195
5196 if (!PyArg_ParseTuple(args, "O&O:execv",
5197 PyUnicode_FSConverter,
5198 &opath, &argv))
5199 return NULL;
5200 path = PyBytes_AsString(opath);
5201 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5202 PyErr_SetString(PyExc_TypeError,
5203 "execv() arg 2 must be a tuple or list");
5204 Py_DECREF(opath);
5205 return NULL;
5206 }
5207 argc = PySequence_Size(argv);
5208 if (argc < 1) {
5209 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5210 Py_DECREF(opath);
5211 return NULL;
5212 }
5213
5214 argvlist = parse_arglist(argv, &argc);
5215 if (argvlist == NULL) {
5216 Py_DECREF(opath);
5217 return NULL;
5218 }
5219
5220 execv(path, argvlist);
5221
5222 /* If we get here it's definitely an error */
5223
5224 free_string_array(argvlist, argc);
5225 Py_DECREF(opath);
5226 return posix_error();
5227}
5228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005230"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231Execute a path with arguments and environment, replacing current process.\n\
5232\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 path: path of executable file\n\
5234 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005235 env: dictionary of strings mapping to strings\n\
5236\n\
5237On some platforms, you may specify an open file descriptor for path;\n\
5238 execve will execute the program the file descriptor is open to.\n\
5239 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005240
Barry Warsaw53699e91996-12-10 23:23:01 +00005241static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005242posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005243{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005244 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005246 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005248 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005249 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 /* execve has three arguments: (path, argv, env), where
5252 argv is a list or tuple of strings and env is a dictionary
5253 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005254
Larry Hastings9cf065c2012-06-22 16:30:09 -07005255 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005256 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005257#ifdef HAVE_FEXECVE
5258 path.allow_fd = 1;
5259#endif
5260 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5261 path_converter, &path,
5262 &argv, &env
5263 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005265
Ross Lagerwall7807c352011-03-17 20:20:30 +02005266 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005268 "execve: argv must be a tuple or list");
5269 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005271 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (!PyMapping_Check(env)) {
5273 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005274 "execve: environment must be a mapping object");
5275 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005277
Ross Lagerwall7807c352011-03-17 20:20:30 +02005278 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005280 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005282
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 envlist = parse_envlist(env, &envc);
5284 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005285 goto fail;
5286
Larry Hastings9cf065c2012-06-22 16:30:09 -07005287#ifdef HAVE_FEXECVE
5288 if (path.fd > -1)
5289 fexecve(path.fd, argvlist, envlist);
5290 else
5291#endif
5292 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005293
5294 /* If we get here it's definitely an error */
5295
Victor Stinner292c8352012-10-30 02:17:38 +01005296 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005297
5298 while (--envc >= 0)
5299 PyMem_DEL(envlist[envc]);
5300 PyMem_DEL(envlist);
5301 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005302 if (argvlist)
5303 free_string_array(argvlist, argc);
5304 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005305 return NULL;
5306}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005307#endif /* HAVE_EXECV */
5308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005309
Guido van Rossuma1065681999-01-25 23:20:23 +00005310#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005311PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005312"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005313Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005314\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 mode: mode of process creation\n\
5316 path: path of executable file\n\
5317 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005318
5319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005320posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005321{
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 PyObject *opath;
5323 char *path;
5324 PyObject *argv;
5325 char **argvlist;
5326 int mode, i;
5327 Py_ssize_t argc;
5328 Py_intptr_t spawnval;
5329 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005330
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 /* spawnv has three arguments: (mode, path, argv), where
5332 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005333
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5335 PyUnicode_FSConverter,
5336 &opath, &argv))
5337 return NULL;
5338 path = PyBytes_AsString(opath);
5339 if (PyList_Check(argv)) {
5340 argc = PyList_Size(argv);
5341 getitem = PyList_GetItem;
5342 }
5343 else if (PyTuple_Check(argv)) {
5344 argc = PyTuple_Size(argv);
5345 getitem = PyTuple_GetItem;
5346 }
5347 else {
5348 PyErr_SetString(PyExc_TypeError,
5349 "spawnv() arg 2 must be a tuple or list");
5350 Py_DECREF(opath);
5351 return NULL;
5352 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005353
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 argvlist = PyMem_NEW(char *, argc+1);
5355 if (argvlist == NULL) {
5356 Py_DECREF(opath);
5357 return PyErr_NoMemory();
5358 }
5359 for (i = 0; i < argc; i++) {
5360 if (!fsconvert_strdup((*getitem)(argv, i),
5361 &argvlist[i])) {
5362 free_string_array(argvlist, i);
5363 PyErr_SetString(
5364 PyExc_TypeError,
5365 "spawnv() arg 2 must contain only strings");
5366 Py_DECREF(opath);
5367 return NULL;
5368 }
5369 }
5370 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005371
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 if (mode == _OLD_P_OVERLAY)
5373 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 Py_BEGIN_ALLOW_THREADS
5376 spawnval = _spawnv(mode, path, argvlist);
5377 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005378
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 free_string_array(argvlist, argc);
5380 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 if (spawnval == -1)
5383 return posix_error();
5384 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005385 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005386}
5387
5388
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005389PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005390"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005391Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005392\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 mode: mode of process creation\n\
5394 path: path of executable file\n\
5395 args: tuple or list of arguments\n\
5396 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005397
5398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005399posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005400{
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 PyObject *opath;
5402 char *path;
5403 PyObject *argv, *env;
5404 char **argvlist;
5405 char **envlist;
5406 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005407 int mode;
5408 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 Py_intptr_t spawnval;
5410 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5411 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005412
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 /* spawnve has four arguments: (mode, path, argv, env), where
5414 argv is a list or tuple of strings and env is a dictionary
5415 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005416
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5418 PyUnicode_FSConverter,
5419 &opath, &argv, &env))
5420 return NULL;
5421 path = PyBytes_AsString(opath);
5422 if (PyList_Check(argv)) {
5423 argc = PyList_Size(argv);
5424 getitem = PyList_GetItem;
5425 }
5426 else if (PyTuple_Check(argv)) {
5427 argc = PyTuple_Size(argv);
5428 getitem = PyTuple_GetItem;
5429 }
5430 else {
5431 PyErr_SetString(PyExc_TypeError,
5432 "spawnve() arg 2 must be a tuple or list");
5433 goto fail_0;
5434 }
5435 if (!PyMapping_Check(env)) {
5436 PyErr_SetString(PyExc_TypeError,
5437 "spawnve() arg 3 must be a mapping object");
5438 goto fail_0;
5439 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005440
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 argvlist = PyMem_NEW(char *, argc+1);
5442 if (argvlist == NULL) {
5443 PyErr_NoMemory();
5444 goto fail_0;
5445 }
5446 for (i = 0; i < argc; i++) {
5447 if (!fsconvert_strdup((*getitem)(argv, i),
5448 &argvlist[i]))
5449 {
5450 lastarg = i;
5451 goto fail_1;
5452 }
5453 }
5454 lastarg = argc;
5455 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005456
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 envlist = parse_envlist(env, &envc);
5458 if (envlist == NULL)
5459 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005460
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 if (mode == _OLD_P_OVERLAY)
5462 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005463
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 Py_BEGIN_ALLOW_THREADS
5465 spawnval = _spawnve(mode, path, argvlist, envlist);
5466 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005467
Victor Stinner8c62be82010-05-06 00:08:46 +00005468 if (spawnval == -1)
5469 (void) posix_error();
5470 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005471 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005472
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 while (--envc >= 0)
5474 PyMem_DEL(envlist[envc]);
5475 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005476 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005477 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005478 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005479 Py_DECREF(opath);
5480 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005481}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005482
Guido van Rossuma1065681999-01-25 23:20:23 +00005483#endif /* HAVE_SPAWNV */
5484
5485
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005486#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005488"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005489Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5490\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005492
5493static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005494posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005495{
Victor Stinner8c62be82010-05-06 00:08:46 +00005496 pid_t pid;
5497 int result = 0;
5498 _PyImport_AcquireLock();
5499 pid = fork1();
5500 if (pid == 0) {
5501 /* child: this clobbers and resets the import lock. */
5502 PyOS_AfterFork();
5503 } else {
5504 /* parent: release the import lock. */
5505 result = _PyImport_ReleaseLock();
5506 }
5507 if (pid == -1)
5508 return posix_error();
5509 if (result < 0) {
5510 /* Don't clobber the OSError if the fork failed. */
5511 PyErr_SetString(PyExc_RuntimeError,
5512 "not holding the import lock");
5513 return NULL;
5514 }
5515 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005516}
5517#endif
5518
5519
Guido van Rossumad0ee831995-03-01 10:34:45 +00005520#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005522"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005523Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005525
Barry Warsaw53699e91996-12-10 23:23:01 +00005526static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005527posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005528{
Victor Stinner8c62be82010-05-06 00:08:46 +00005529 pid_t pid;
5530 int result = 0;
5531 _PyImport_AcquireLock();
5532 pid = fork();
5533 if (pid == 0) {
5534 /* child: this clobbers and resets the import lock. */
5535 PyOS_AfterFork();
5536 } else {
5537 /* parent: release the import lock. */
5538 result = _PyImport_ReleaseLock();
5539 }
5540 if (pid == -1)
5541 return posix_error();
5542 if (result < 0) {
5543 /* Don't clobber the OSError if the fork failed. */
5544 PyErr_SetString(PyExc_RuntimeError,
5545 "not holding the import lock");
5546 return NULL;
5547 }
5548 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005549}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005550#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005551
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552#ifdef HAVE_SCHED_H
5553
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005554#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5555
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005556PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5557"sched_get_priority_max(policy)\n\n\
5558Get the maximum scheduling priority for *policy*.");
5559
5560static PyObject *
5561posix_sched_get_priority_max(PyObject *self, PyObject *args)
5562{
5563 int policy, max;
5564
5565 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5566 return NULL;
5567 max = sched_get_priority_max(policy);
5568 if (max < 0)
5569 return posix_error();
5570 return PyLong_FromLong(max);
5571}
5572
5573PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5574"sched_get_priority_min(policy)\n\n\
5575Get the minimum scheduling priority for *policy*.");
5576
5577static PyObject *
5578posix_sched_get_priority_min(PyObject *self, PyObject *args)
5579{
5580 int policy, min;
5581
5582 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5583 return NULL;
5584 min = sched_get_priority_min(policy);
5585 if (min < 0)
5586 return posix_error();
5587 return PyLong_FromLong(min);
5588}
5589
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005590#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5591
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005592#ifdef HAVE_SCHED_SETSCHEDULER
5593
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005594PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5595"sched_getscheduler(pid)\n\n\
5596Get the scheduling policy for the process with a PID of *pid*.\n\
5597Passing a PID of 0 returns the scheduling policy for the calling process.");
5598
5599static PyObject *
5600posix_sched_getscheduler(PyObject *self, PyObject *args)
5601{
5602 pid_t pid;
5603 int policy;
5604
5605 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5606 return NULL;
5607 policy = sched_getscheduler(pid);
5608 if (policy < 0)
5609 return posix_error();
5610 return PyLong_FromLong(policy);
5611}
5612
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005613#endif
5614
5615#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5616
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005617static PyObject *
5618sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5619{
5620 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005621 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005622
5623 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5624 return NULL;
5625 res = PyStructSequence_New(type);
5626 if (!res)
5627 return NULL;
5628 Py_INCREF(priority);
5629 PyStructSequence_SET_ITEM(res, 0, priority);
5630 return res;
5631}
5632
5633PyDoc_STRVAR(sched_param__doc__,
5634"sched_param(sched_priority): A scheduling parameter.\n\n\
5635Current has only one field: sched_priority");
5636
5637static PyStructSequence_Field sched_param_fields[] = {
5638 {"sched_priority", "the scheduling priority"},
5639 {0}
5640};
5641
5642static PyStructSequence_Desc sched_param_desc = {
5643 "sched_param", /* name */
5644 sched_param__doc__, /* doc */
5645 sched_param_fields,
5646 1
5647};
5648
5649static int
5650convert_sched_param(PyObject *param, struct sched_param *res)
5651{
5652 long priority;
5653
5654 if (Py_TYPE(param) != &SchedParamType) {
5655 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5656 return 0;
5657 }
5658 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5659 if (priority == -1 && PyErr_Occurred())
5660 return 0;
5661 if (priority > INT_MAX || priority < INT_MIN) {
5662 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5663 return 0;
5664 }
5665 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5666 return 1;
5667}
5668
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005669#endif
5670
5671#ifdef HAVE_SCHED_SETSCHEDULER
5672
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005673PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5674"sched_setscheduler(pid, policy, param)\n\n\
5675Set the scheduling policy, *policy*, for *pid*.\n\
5676If *pid* is 0, the calling process is changed.\n\
5677*param* is an instance of sched_param.");
5678
5679static PyObject *
5680posix_sched_setscheduler(PyObject *self, PyObject *args)
5681{
5682 pid_t pid;
5683 int policy;
5684 struct sched_param param;
5685
5686 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5687 &pid, &policy, &convert_sched_param, &param))
5688 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005689
5690 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005691 ** sched_setscheduler() returns 0 in Linux, but the previous
5692 ** scheduling policy under Solaris/Illumos, and others.
5693 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005694 */
5695 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005696 return posix_error();
5697 Py_RETURN_NONE;
5698}
5699
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005700#endif
5701
5702#ifdef HAVE_SCHED_SETPARAM
5703
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005704PyDoc_STRVAR(posix_sched_getparam__doc__,
5705"sched_getparam(pid) -> sched_param\n\n\
5706Returns scheduling parameters for the process with *pid* as an instance of the\n\
5707sched_param class. A PID of 0 means the calling process.");
5708
5709static PyObject *
5710posix_sched_getparam(PyObject *self, PyObject *args)
5711{
5712 pid_t pid;
5713 struct sched_param param;
5714 PyObject *res, *priority;
5715
5716 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5717 return NULL;
5718 if (sched_getparam(pid, &param))
5719 return posix_error();
5720 res = PyStructSequence_New(&SchedParamType);
5721 if (!res)
5722 return NULL;
5723 priority = PyLong_FromLong(param.sched_priority);
5724 if (!priority) {
5725 Py_DECREF(res);
5726 return NULL;
5727 }
5728 PyStructSequence_SET_ITEM(res, 0, priority);
5729 return res;
5730}
5731
5732PyDoc_STRVAR(posix_sched_setparam__doc__,
5733"sched_setparam(pid, param)\n\n\
5734Set scheduling parameters for a process with PID *pid*.\n\
5735A PID of 0 means the calling process.");
5736
5737static PyObject *
5738posix_sched_setparam(PyObject *self, PyObject *args)
5739{
5740 pid_t pid;
5741 struct sched_param param;
5742
5743 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5744 &pid, &convert_sched_param, &param))
5745 return NULL;
5746 if (sched_setparam(pid, &param))
5747 return posix_error();
5748 Py_RETURN_NONE;
5749}
5750
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005751#endif
5752
5753#ifdef HAVE_SCHED_RR_GET_INTERVAL
5754
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005755PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5756"sched_rr_get_interval(pid) -> float\n\n\
5757Return the round-robin quantum for the process with PID *pid* in seconds.");
5758
5759static PyObject *
5760posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5761{
5762 pid_t pid;
5763 struct timespec interval;
5764
5765 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5766 return NULL;
5767 if (sched_rr_get_interval(pid, &interval))
5768 return posix_error();
5769 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5770}
5771
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005772#endif
5773
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005774PyDoc_STRVAR(posix_sched_yield__doc__,
5775"sched_yield()\n\n\
5776Voluntarily relinquish the CPU.");
5777
5778static PyObject *
5779posix_sched_yield(PyObject *self, PyObject *noargs)
5780{
5781 if (sched_yield())
5782 return posix_error();
5783 Py_RETURN_NONE;
5784}
5785
Benjamin Peterson2740af82011-08-02 17:41:34 -05005786#ifdef HAVE_SCHED_SETAFFINITY
5787
Antoine Pitrou84869872012-08-04 16:16:35 +02005788/* The minimum number of CPUs allocated in a cpu_set_t */
5789static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005790
5791PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5792"sched_setaffinity(pid, cpu_set)\n\n\
5793Set the affinity of the process with PID *pid* to *cpu_set*.");
5794
5795static PyObject *
5796posix_sched_setaffinity(PyObject *self, PyObject *args)
5797{
5798 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 int ncpus;
5800 size_t setsize;
5801 cpu_set_t *mask = NULL;
5802 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005803
Antoine Pitrou84869872012-08-04 16:16:35 +02005804 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5805 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005806 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005807
5808 iterator = PyObject_GetIter(iterable);
5809 if (iterator == NULL)
5810 return NULL;
5811
5812 ncpus = NCPUS_START;
5813 setsize = CPU_ALLOC_SIZE(ncpus);
5814 mask = CPU_ALLOC(ncpus);
5815 if (mask == NULL) {
5816 PyErr_NoMemory();
5817 goto error;
5818 }
5819 CPU_ZERO_S(setsize, mask);
5820
5821 while ((item = PyIter_Next(iterator))) {
5822 long cpu;
5823 if (!PyLong_Check(item)) {
5824 PyErr_Format(PyExc_TypeError,
5825 "expected an iterator of ints, "
5826 "but iterator yielded %R",
5827 Py_TYPE(item));
5828 Py_DECREF(item);
5829 goto error;
5830 }
5831 cpu = PyLong_AsLong(item);
5832 Py_DECREF(item);
5833 if (cpu < 0) {
5834 if (!PyErr_Occurred())
5835 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5836 goto error;
5837 }
5838 if (cpu > INT_MAX - 1) {
5839 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5840 goto error;
5841 }
5842 if (cpu >= ncpus) {
5843 /* Grow CPU mask to fit the CPU number */
5844 int newncpus = ncpus;
5845 cpu_set_t *newmask;
5846 size_t newsetsize;
5847 while (newncpus <= cpu) {
5848 if (newncpus > INT_MAX / 2)
5849 newncpus = cpu + 1;
5850 else
5851 newncpus = newncpus * 2;
5852 }
5853 newmask = CPU_ALLOC(newncpus);
5854 if (newmask == NULL) {
5855 PyErr_NoMemory();
5856 goto error;
5857 }
5858 newsetsize = CPU_ALLOC_SIZE(newncpus);
5859 CPU_ZERO_S(newsetsize, newmask);
5860 memcpy(newmask, mask, setsize);
5861 CPU_FREE(mask);
5862 setsize = newsetsize;
5863 mask = newmask;
5864 ncpus = newncpus;
5865 }
5866 CPU_SET_S(cpu, setsize, mask);
5867 }
5868 Py_CLEAR(iterator);
5869
5870 if (sched_setaffinity(pid, setsize, mask)) {
5871 posix_error();
5872 goto error;
5873 }
5874 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005876
5877error:
5878 if (mask)
5879 CPU_FREE(mask);
5880 Py_XDECREF(iterator);
5881 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005882}
5883
5884PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5885"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5886Return the affinity of the process with PID *pid*.\n\
5887The returned cpu_set will be of size *ncpus*.");
5888
5889static PyObject *
5890posix_sched_getaffinity(PyObject *self, PyObject *args)
5891{
5892 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005893 int cpu, ncpus, count;
5894 size_t setsize;
5895 cpu_set_t *mask = NULL;
5896 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005897
Antoine Pitrou84869872012-08-04 16:16:35 +02005898 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5899 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005900 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005901
5902 ncpus = NCPUS_START;
5903 while (1) {
5904 setsize = CPU_ALLOC_SIZE(ncpus);
5905 mask = CPU_ALLOC(ncpus);
5906 if (mask == NULL)
5907 return PyErr_NoMemory();
5908 if (sched_getaffinity(pid, setsize, mask) == 0)
5909 break;
5910 CPU_FREE(mask);
5911 if (errno != EINVAL)
5912 return posix_error();
5913 if (ncpus > INT_MAX / 2) {
5914 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5915 "a large enough CPU set");
5916 return NULL;
5917 }
5918 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005919 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005920
5921 res = PySet_New(NULL);
5922 if (res == NULL)
5923 goto error;
5924 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5925 if (CPU_ISSET_S(cpu, setsize, mask)) {
5926 PyObject *cpu_num = PyLong_FromLong(cpu);
5927 --count;
5928 if (cpu_num == NULL)
5929 goto error;
5930 if (PySet_Add(res, cpu_num)) {
5931 Py_DECREF(cpu_num);
5932 goto error;
5933 }
5934 Py_DECREF(cpu_num);
5935 }
5936 }
5937 CPU_FREE(mask);
5938 return res;
5939
5940error:
5941 if (mask)
5942 CPU_FREE(mask);
5943 Py_XDECREF(res);
5944 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005945}
5946
Benjamin Peterson2740af82011-08-02 17:41:34 -05005947#endif /* HAVE_SCHED_SETAFFINITY */
5948
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005949#endif /* HAVE_SCHED_H */
5950
Neal Norwitzb59798b2003-03-21 01:43:31 +00005951/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005952/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5953#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005954#define DEV_PTY_FILE "/dev/ptc"
5955#define HAVE_DEV_PTMX
5956#else
5957#define DEV_PTY_FILE "/dev/ptmx"
5958#endif
5959
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005960#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005961#ifdef HAVE_PTY_H
5962#include <pty.h>
5963#else
5964#ifdef HAVE_LIBUTIL_H
5965#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005966#else
5967#ifdef HAVE_UTIL_H
5968#include <util.h>
5969#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005970#endif /* HAVE_LIBUTIL_H */
5971#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005972#ifdef HAVE_STROPTS_H
5973#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005974#endif
5975#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005976
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005977#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005978PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005979"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005980Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005981
5982static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005983posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005985 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005986#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005988#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005989#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005991#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005993#endif
5994#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005995
Thomas Wouters70c21a12000-07-14 14:28:33 +00005996#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005998 goto posix_error;
5999
6000 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6001 goto error;
6002 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6003 goto error;
6004
Neal Norwitzb59798b2003-03-21 01:43:31 +00006005#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6007 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 goto posix_error;
6009 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6010 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006011
Victor Stinnerdaf45552013-08-28 00:53:59 +02006012 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006014 goto posix_error;
6015
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006016#else
Victor Stinner000de532013-11-25 23:19:58 +01006017 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006019 goto posix_error;
6020
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006022
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 /* change permission of slave */
6024 if (grantpt(master_fd) < 0) {
6025 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006026 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006028
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 /* unlock slave */
6030 if (unlockpt(master_fd) < 0) {
6031 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006032 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006034
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006036
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 slave_name = ptsname(master_fd); /* get name of slave */
6038 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006039 goto posix_error;
6040
6041 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006043 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006044
6045 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6046 goto posix_error;
6047
Neal Norwitzb59798b2003-03-21 01:43:31 +00006048#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6050 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006051#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006053#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006054#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006055#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006058
Victor Stinnerdaf45552013-08-28 00:53:59 +02006059posix_error:
6060 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006061#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006062error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006063#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006064 if (master_fd != -1)
6065 close(master_fd);
6066 if (slave_fd != -1)
6067 close(slave_fd);
6068 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006069}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006070#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006071
6072#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006074"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006075Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6076Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006077To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006078
6079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006080posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006081{
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 int master_fd = -1, result = 0;
6083 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 _PyImport_AcquireLock();
6086 pid = forkpty(&master_fd, NULL, NULL, NULL);
6087 if (pid == 0) {
6088 /* child: this clobbers and resets the import lock. */
6089 PyOS_AfterFork();
6090 } else {
6091 /* parent: release the import lock. */
6092 result = _PyImport_ReleaseLock();
6093 }
6094 if (pid == -1)
6095 return posix_error();
6096 if (result < 0) {
6097 /* Don't clobber the OSError if the fork failed. */
6098 PyErr_SetString(PyExc_RuntimeError,
6099 "not holding the import lock");
6100 return NULL;
6101 }
6102 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006103}
6104#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006105
Ross Lagerwall7807c352011-03-17 20:20:30 +02006106
Guido van Rossumad0ee831995-03-01 10:34:45 +00006107#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006109"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Barry Warsaw53699e91996-12-10 23:23:01 +00006112static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006113posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006114{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006115 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006116}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006117#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006119
Guido van Rossumad0ee831995-03-01 10:34:45 +00006120#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006124
Barry Warsaw53699e91996-12-10 23:23:01 +00006125static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006126posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006127{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006128 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006129}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006130#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006132
Guido van Rossumad0ee831995-03-01 10:34:45 +00006133#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006135"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006137
Barry Warsaw53699e91996-12-10 23:23:01 +00006138static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006139posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006140{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006141 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006142}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006143#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006145
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006147"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006148Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006149
Barry Warsaw53699e91996-12-10 23:23:01 +00006150static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006151posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006152{
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006154}
6155
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006156#ifdef HAVE_GETGROUPLIST
6157PyDoc_STRVAR(posix_getgrouplist__doc__,
6158"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6159Returns a list of groups to which a user belongs.\n\n\
6160 user: username to lookup\n\
6161 group: base group id of the user");
6162
6163static PyObject *
6164posix_getgrouplist(PyObject *self, PyObject *args)
6165{
6166#ifdef NGROUPS_MAX
6167#define MAX_GROUPS NGROUPS_MAX
6168#else
6169 /* defined to be 16 on Solaris7, so this should be a small number */
6170#define MAX_GROUPS 64
6171#endif
6172
6173 const char *user;
6174 int i, ngroups;
6175 PyObject *list;
6176#ifdef __APPLE__
6177 int *groups, basegid;
6178#else
6179 gid_t *groups, basegid;
6180#endif
6181 ngroups = MAX_GROUPS;
6182
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006183#ifdef __APPLE__
6184 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006185 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006186#else
6187 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6188 _Py_Gid_Converter, &basegid))
6189 return NULL;
6190#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006191
6192#ifdef __APPLE__
6193 groups = PyMem_Malloc(ngroups * sizeof(int));
6194#else
6195 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6196#endif
6197 if (groups == NULL)
6198 return PyErr_NoMemory();
6199
6200 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6201 PyMem_Del(groups);
6202 return posix_error();
6203 }
6204
6205 list = PyList_New(ngroups);
6206 if (list == NULL) {
6207 PyMem_Del(groups);
6208 return NULL;
6209 }
6210
6211 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006212#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006213 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006214#else
6215 PyObject *o = _PyLong_FromGid(groups[i]);
6216#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006217 if (o == NULL) {
6218 Py_DECREF(list);
6219 PyMem_Del(groups);
6220 return NULL;
6221 }
6222 PyList_SET_ITEM(list, i, o);
6223 }
6224
6225 PyMem_Del(groups);
6226
6227 return list;
6228}
6229#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006230
Fred Drakec9680921999-12-13 16:37:25 +00006231#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006232PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006233"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006234Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006235
6236static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006237posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006238{
6239 PyObject *result = NULL;
6240
Fred Drakec9680921999-12-13 16:37:25 +00006241#ifdef NGROUPS_MAX
6242#define MAX_GROUPS NGROUPS_MAX
6243#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006245#define MAX_GROUPS 64
6246#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006248
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006249 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006250 * This is a helper variable to store the intermediate result when
6251 * that happens.
6252 *
6253 * To keep the code readable the OSX behaviour is unconditional,
6254 * according to the POSIX spec this should be safe on all unix-y
6255 * systems.
6256 */
6257 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006259
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006260#ifdef __APPLE__
6261 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6262 * there are more groups than can fit in grouplist. Therefore, on OS X
6263 * always first call getgroups with length 0 to get the actual number
6264 * of groups.
6265 */
6266 n = getgroups(0, NULL);
6267 if (n < 0) {
6268 return posix_error();
6269 } else if (n <= MAX_GROUPS) {
6270 /* groups will fit in existing array */
6271 alt_grouplist = grouplist;
6272 } else {
6273 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6274 if (alt_grouplist == NULL) {
6275 errno = EINVAL;
6276 return posix_error();
6277 }
6278 }
6279
6280 n = getgroups(n, alt_grouplist);
6281 if (n == -1) {
6282 if (alt_grouplist != grouplist) {
6283 PyMem_Free(alt_grouplist);
6284 }
6285 return posix_error();
6286 }
6287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006289 if (n < 0) {
6290 if (errno == EINVAL) {
6291 n = getgroups(0, NULL);
6292 if (n == -1) {
6293 return posix_error();
6294 }
6295 if (n == 0) {
6296 /* Avoid malloc(0) */
6297 alt_grouplist = grouplist;
6298 } else {
6299 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6300 if (alt_grouplist == NULL) {
6301 errno = EINVAL;
6302 return posix_error();
6303 }
6304 n = getgroups(n, alt_grouplist);
6305 if (n == -1) {
6306 PyMem_Free(alt_grouplist);
6307 return posix_error();
6308 }
6309 }
6310 } else {
6311 return posix_error();
6312 }
6313 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006314#endif
6315
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006316 result = PyList_New(n);
6317 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 int i;
6319 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006320 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006322 Py_DECREF(result);
6323 result = NULL;
6324 break;
Fred Drakec9680921999-12-13 16:37:25 +00006325 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006327 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006328 }
6329
6330 if (alt_grouplist != grouplist) {
6331 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006333
Fred Drakec9680921999-12-13 16:37:25 +00006334 return result;
6335}
6336#endif
6337
Antoine Pitroub7572f02009-12-02 20:46:48 +00006338#ifdef HAVE_INITGROUPS
6339PyDoc_STRVAR(posix_initgroups__doc__,
6340"initgroups(username, gid) -> None\n\n\
6341Call the system initgroups() to initialize the group access list with all of\n\
6342the groups of which the specified username is a member, plus the specified\n\
6343group id.");
6344
6345static PyObject *
6346posix_initgroups(PyObject *self, PyObject *args)
6347{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006348 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006350 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006351#ifdef __APPLE__
6352 int gid;
6353#else
6354 gid_t gid;
6355#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006356
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006357#ifdef __APPLE__
6358 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6359 PyUnicode_FSConverter, &oname,
6360 &gid))
6361#else
6362 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6363 PyUnicode_FSConverter, &oname,
6364 _Py_Gid_Converter, &gid))
6365#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006367 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006368
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006369 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006370 Py_DECREF(oname);
6371 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006373
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 Py_INCREF(Py_None);
6375 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006376}
6377#endif
6378
Martin v. Löwis606edc12002-06-13 21:09:11 +00006379#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006380PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006381"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006382Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006383
6384static PyObject *
6385posix_getpgid(PyObject *self, PyObject *args)
6386{
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 pid_t pid, pgid;
6388 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6389 return NULL;
6390 pgid = getpgid(pid);
6391 if (pgid < 0)
6392 return posix_error();
6393 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006394}
6395#endif /* HAVE_GETPGID */
6396
6397
Guido van Rossumb6775db1994-08-01 11:34:53 +00006398#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006399PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006400"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006402
Barry Warsaw53699e91996-12-10 23:23:01 +00006403static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006404posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006405{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006406#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006408#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006410#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006411}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Guido van Rossumb6775db1994-08-01 11:34:53 +00006415#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006416PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006417"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006418Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006419
Barry Warsaw53699e91996-12-10 23:23:01 +00006420static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006421posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006422{
Guido van Rossum64933891994-10-20 21:56:42 +00006423#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006425#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006427#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 return posix_error();
6429 Py_INCREF(Py_None);
6430 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006431}
6432
Guido van Rossumb6775db1994-08-01 11:34:53 +00006433#endif /* HAVE_SETPGRP */
6434
Guido van Rossumad0ee831995-03-01 10:34:45 +00006435#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006436
6437#ifdef MS_WINDOWS
6438#include <tlhelp32.h>
6439
6440static PyObject*
6441win32_getppid()
6442{
6443 HANDLE snapshot;
6444 pid_t mypid;
6445 PyObject* result = NULL;
6446 BOOL have_record;
6447 PROCESSENTRY32 pe;
6448
6449 mypid = getpid(); /* This function never fails */
6450
6451 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6452 if (snapshot == INVALID_HANDLE_VALUE)
6453 return PyErr_SetFromWindowsErr(GetLastError());
6454
6455 pe.dwSize = sizeof(pe);
6456 have_record = Process32First(snapshot, &pe);
6457 while (have_record) {
6458 if (mypid == (pid_t)pe.th32ProcessID) {
6459 /* We could cache the ulong value in a static variable. */
6460 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6461 break;
6462 }
6463
6464 have_record = Process32Next(snapshot, &pe);
6465 }
6466
6467 /* If our loop exits and our pid was not found (result will be NULL)
6468 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6469 * error anyway, so let's raise it. */
6470 if (!result)
6471 result = PyErr_SetFromWindowsErr(GetLastError());
6472
6473 CloseHandle(snapshot);
6474
6475 return result;
6476}
6477#endif /*MS_WINDOWS*/
6478
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006479PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006480"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006481Return the parent's process id. If the parent process has already exited,\n\
6482Windows machines will still return its id; others systems will return the id\n\
6483of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006484
Barry Warsaw53699e91996-12-10 23:23:01 +00006485static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006486posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006487{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006488#ifdef MS_WINDOWS
6489 return win32_getppid();
6490#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006492#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006493}
6494#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006496
Fred Drake12c6e2d1999-12-14 21:25:03 +00006497#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006498PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006499"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006500Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006501
6502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006503posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504{
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006506#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006507 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006508 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006509
6510 if (GetUserNameW(user_name, &num_chars)) {
6511 /* num_chars is the number of unicode chars plus null terminator */
6512 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006513 }
6514 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006515 result = PyErr_SetFromWindowsErr(GetLastError());
6516#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 char *name;
6518 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006519
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 errno = 0;
6521 name = getlogin();
6522 if (name == NULL) {
6523 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006524 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006525 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006526 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 }
6528 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006529 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006531#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006532 return result;
6533}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006534#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006535
Guido van Rossumad0ee831995-03-01 10:34:45 +00006536#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006537PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006538"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Barry Warsaw53699e91996-12-10 23:23:01 +00006541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006542posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006543{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006544 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006545}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006546#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006548
Guido van Rossumad0ee831995-03-01 10:34:45 +00006549#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006551"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006552Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006553
Barry Warsaw53699e91996-12-10 23:23:01 +00006554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006555posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006556{
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 pid_t pid;
6558 int sig;
6559 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6560 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 if (kill(pid, sig) == -1)
6562 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 Py_INCREF(Py_None);
6564 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006565}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006566#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006567
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006568#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006570"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006572
6573static PyObject *
6574posix_killpg(PyObject *self, PyObject *args)
6575{
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 int sig;
6577 pid_t pgid;
6578 /* XXX some man pages make the `pgid` parameter an int, others
6579 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6580 take the same type. Moreover, pid_t is always at least as wide as
6581 int (else compilation of this module fails), which is safe. */
6582 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6583 return NULL;
6584 if (killpg(pgid, sig) == -1)
6585 return posix_error();
6586 Py_INCREF(Py_None);
6587 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006588}
6589#endif
6590
Brian Curtineb24d742010-04-12 17:16:38 +00006591#ifdef MS_WINDOWS
6592PyDoc_STRVAR(win32_kill__doc__,
6593"kill(pid, sig)\n\n\
6594Kill a process with a signal.");
6595
6596static PyObject *
6597win32_kill(PyObject *self, PyObject *args)
6598{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006599 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006600 pid_t pid;
6601 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006603
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006604 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006606
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 /* Console processes which share a common console can be sent CTRL+C or
6608 CTRL+BREAK events, provided they handle said events. */
6609 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006610 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 err = GetLastError();
6612 PyErr_SetFromWindowsErr(err);
6613 }
6614 else
6615 Py_RETURN_NONE;
6616 }
Brian Curtineb24d742010-04-12 17:16:38 +00006617
Victor Stinner8c62be82010-05-06 00:08:46 +00006618 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6619 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006620 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 if (handle == NULL) {
6622 err = GetLastError();
6623 return PyErr_SetFromWindowsErr(err);
6624 }
Brian Curtineb24d742010-04-12 17:16:38 +00006625
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 if (TerminateProcess(handle, sig) == 0) {
6627 err = GetLastError();
6628 result = PyErr_SetFromWindowsErr(err);
6629 } else {
6630 Py_INCREF(Py_None);
6631 result = Py_None;
6632 }
Brian Curtineb24d742010-04-12 17:16:38 +00006633
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 CloseHandle(handle);
6635 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006636}
6637#endif /* MS_WINDOWS */
6638
Guido van Rossumc0125471996-06-28 18:55:32 +00006639#ifdef HAVE_PLOCK
6640
6641#ifdef HAVE_SYS_LOCK_H
6642#include <sys/lock.h>
6643#endif
6644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006645PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006646"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006647Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006648
Barry Warsaw53699e91996-12-10 23:23:01 +00006649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006650posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006651{
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 int op;
6653 if (!PyArg_ParseTuple(args, "i:plock", &op))
6654 return NULL;
6655 if (plock(op) == -1)
6656 return posix_error();
6657 Py_INCREF(Py_None);
6658 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006659}
6660#endif
6661
Guido van Rossumb6775db1994-08-01 11:34:53 +00006662#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006664"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006665Set the current process's user id.");
6666
Barry Warsaw53699e91996-12-10 23:23:01 +00006667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006668posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006669{
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006671 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 if (setuid(uid) < 0)
6674 return posix_error();
6675 Py_INCREF(Py_None);
6676 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006677}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006678#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006680
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006681#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006682PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006683"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684Set the current process's effective user id.");
6685
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006686static PyObject *
6687posix_seteuid (PyObject *self, PyObject *args)
6688{
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006690 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 if (seteuid(euid) < 0) {
6693 return posix_error();
6694 } else {
6695 Py_INCREF(Py_None);
6696 return Py_None;
6697 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006698}
6699#endif /* HAVE_SETEUID */
6700
6701#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006702PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006703"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006704Set the current process's effective group id.");
6705
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006706static PyObject *
6707posix_setegid (PyObject *self, PyObject *args)
6708{
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006710 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 if (setegid(egid) < 0) {
6713 return posix_error();
6714 } else {
6715 Py_INCREF(Py_None);
6716 return Py_None;
6717 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006718}
6719#endif /* HAVE_SETEGID */
6720
6721#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006723"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724Set the current process's real and effective user ids.");
6725
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006726static PyObject *
6727posix_setreuid (PyObject *self, PyObject *args)
6728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006730 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6731 _Py_Uid_Converter, &ruid,
6732 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 if (setreuid(ruid, euid) < 0) {
6735 return posix_error();
6736 } else {
6737 Py_INCREF(Py_None);
6738 return Py_None;
6739 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006740}
6741#endif /* HAVE_SETREUID */
6742
6743#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006744PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006745"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006746Set the current process's real and effective group ids.");
6747
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006748static PyObject *
6749posix_setregid (PyObject *self, PyObject *args)
6750{
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006752 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6753 _Py_Gid_Converter, &rgid,
6754 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 if (setregid(rgid, egid) < 0) {
6757 return posix_error();
6758 } else {
6759 Py_INCREF(Py_None);
6760 return Py_None;
6761 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006762}
6763#endif /* HAVE_SETREGID */
6764
Guido van Rossumb6775db1994-08-01 11:34:53 +00006765#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006766PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006767"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006769
Barry Warsaw53699e91996-12-10 23:23:01 +00006770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006771posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006774 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 if (setgid(gid) < 0)
6777 return posix_error();
6778 Py_INCREF(Py_None);
6779 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006780}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006781#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006782
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006783#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006785"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006787
6788static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006789posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006790{
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 int i, len;
6792 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 if (!PySequence_Check(groups)) {
6795 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6796 return NULL;
6797 }
6798 len = PySequence_Size(groups);
6799 if (len > MAX_GROUPS) {
6800 PyErr_SetString(PyExc_ValueError, "too many groups");
6801 return NULL;
6802 }
6803 for(i = 0; i < len; i++) {
6804 PyObject *elem;
6805 elem = PySequence_GetItem(groups, i);
6806 if (!elem)
6807 return NULL;
6808 if (!PyLong_Check(elem)) {
6809 PyErr_SetString(PyExc_TypeError,
6810 "groups must be integers");
6811 Py_DECREF(elem);
6812 return NULL;
6813 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006814 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 Py_DECREF(elem);
6816 return NULL;
6817 }
6818 }
6819 Py_DECREF(elem);
6820 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006821
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 if (setgroups(len, grouplist) < 0)
6823 return posix_error();
6824 Py_INCREF(Py_None);
6825 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006826}
6827#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006828
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6830static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006831wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832{
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 PyObject *result;
6834 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006835 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 if (pid == -1)
6838 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (struct_rusage == NULL) {
6841 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6842 if (m == NULL)
6843 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006844 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 Py_DECREF(m);
6846 if (struct_rusage == NULL)
6847 return NULL;
6848 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6851 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6852 if (!result)
6853 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006854
6855#ifndef doubletime
6856#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6857#endif
6858
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006860 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006862 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6865 SET_INT(result, 2, ru->ru_maxrss);
6866 SET_INT(result, 3, ru->ru_ixrss);
6867 SET_INT(result, 4, ru->ru_idrss);
6868 SET_INT(result, 5, ru->ru_isrss);
6869 SET_INT(result, 6, ru->ru_minflt);
6870 SET_INT(result, 7, ru->ru_majflt);
6871 SET_INT(result, 8, ru->ru_nswap);
6872 SET_INT(result, 9, ru->ru_inblock);
6873 SET_INT(result, 10, ru->ru_oublock);
6874 SET_INT(result, 11, ru->ru_msgsnd);
6875 SET_INT(result, 12, ru->ru_msgrcv);
6876 SET_INT(result, 13, ru->ru_nsignals);
6877 SET_INT(result, 14, ru->ru_nvcsw);
6878 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879#undef SET_INT
6880
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 if (PyErr_Occurred()) {
6882 Py_DECREF(result);
6883 return NULL;
6884 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006885
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006887}
6888#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6889
6890#ifdef HAVE_WAIT3
6891PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006892"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893Wait for completion of a child process.");
6894
6895static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006896posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897{
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 pid_t pid;
6899 int options;
6900 struct rusage ru;
6901 WAIT_TYPE status;
6902 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903
Victor Stinner4195b5c2012-02-08 23:03:19 +01006904 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006906
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 Py_BEGIN_ALLOW_THREADS
6908 pid = wait3(&status, options, &ru);
6909 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910
Victor Stinner4195b5c2012-02-08 23:03:19 +01006911 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912}
6913#endif /* HAVE_WAIT3 */
6914
6915#ifdef HAVE_WAIT4
6916PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006917"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918Wait for completion of a given child process.");
6919
6920static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006921posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922{
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 pid_t pid;
6924 int options;
6925 struct rusage ru;
6926 WAIT_TYPE status;
6927 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006928
Victor Stinner4195b5c2012-02-08 23:03:19 +01006929 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 Py_BEGIN_ALLOW_THREADS
6933 pid = wait4(pid, &status, options, &ru);
6934 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006935
Victor Stinner4195b5c2012-02-08 23:03:19 +01006936 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937}
6938#endif /* HAVE_WAIT4 */
6939
Ross Lagerwall7807c352011-03-17 20:20:30 +02006940#if defined(HAVE_WAITID) && !defined(__APPLE__)
6941PyDoc_STRVAR(posix_waitid__doc__,
6942"waitid(idtype, id, options) -> waitid_result\n\n\
6943Wait for the completion of one or more child processes.\n\n\
6944idtype can be P_PID, P_PGID or P_ALL.\n\
6945id specifies the pid to wait on.\n\
6946options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6947or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6948Returns either waitid_result or None if WNOHANG is specified and there are\n\
6949no children in a waitable state.");
6950
6951static PyObject *
6952posix_waitid(PyObject *self, PyObject *args)
6953{
6954 PyObject *result;
6955 idtype_t idtype;
6956 id_t id;
6957 int options, res;
6958 siginfo_t si;
6959 si.si_pid = 0;
6960 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6961 return NULL;
6962 Py_BEGIN_ALLOW_THREADS
6963 res = waitid(idtype, id, &si, options);
6964 Py_END_ALLOW_THREADS
6965 if (res == -1)
6966 return posix_error();
6967
6968 if (si.si_pid == 0)
6969 Py_RETURN_NONE;
6970
6971 result = PyStructSequence_New(&WaitidResultType);
6972 if (!result)
6973 return NULL;
6974
6975 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006976 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006977 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6978 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6979 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6980 if (PyErr_Occurred()) {
6981 Py_DECREF(result);
6982 return NULL;
6983 }
6984
6985 return result;
6986}
6987#endif
6988
Guido van Rossumb6775db1994-08-01 11:34:53 +00006989#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006990PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006991"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006993
Barry Warsaw53699e91996-12-10 23:23:01 +00006994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006995posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006996{
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 pid_t pid;
6998 int options;
6999 WAIT_TYPE status;
7000 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007001
Victor Stinner8c62be82010-05-06 00:08:46 +00007002 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7003 return NULL;
7004 Py_BEGIN_ALLOW_THREADS
7005 pid = waitpid(pid, &status, options);
7006 Py_END_ALLOW_THREADS
7007 if (pid == -1)
7008 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007009
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007011}
7012
Tim Petersab034fa2002-02-01 11:27:43 +00007013#elif defined(HAVE_CWAIT)
7014
7015/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007016PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007017"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007018"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007019
7020static PyObject *
7021posix_waitpid(PyObject *self, PyObject *args)
7022{
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 Py_intptr_t pid;
7024 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007025
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007026 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 return NULL;
7028 Py_BEGIN_ALLOW_THREADS
7029 pid = _cwait(&status, pid, options);
7030 Py_END_ALLOW_THREADS
7031 if (pid == -1)
7032 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007033
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007035 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007036}
7037#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007038
Guido van Rossumad0ee831995-03-01 10:34:45 +00007039#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007040PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007041"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007042Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007043
Barry Warsaw53699e91996-12-10 23:23:01 +00007044static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007045posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007046{
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 pid_t pid;
7048 WAIT_TYPE status;
7049 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007050
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 Py_BEGIN_ALLOW_THREADS
7052 pid = wait(&status);
7053 Py_END_ALLOW_THREADS
7054 if (pid == -1)
7055 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007056
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007058}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007059#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Larry Hastings9cf065c2012-06-22 16:30:09 -07007062#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7063PyDoc_STRVAR(readlink__doc__,
7064"readlink(path, *, dir_fd=None) -> path\n\n\
7065Return a string representing the path to which the symbolic link points.\n\
7066\n\
7067If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7068 and path should be relative; path will then be relative to that directory.\n\
7069dir_fd may not be implemented on your platform.\n\
7070 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007071#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007072
Guido van Rossumb6775db1994-08-01 11:34:53 +00007073#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007074
Barry Warsaw53699e91996-12-10 23:23:01 +00007075static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007076posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007077{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007078 path_t path;
7079 int dir_fd = DEFAULT_DIR_FD;
7080 char buffer[MAXPATHLEN];
7081 ssize_t length;
7082 PyObject *return_value = NULL;
7083 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007084
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007086 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7088 path_converter, &path,
7089#ifdef HAVE_READLINKAT
7090 dir_fd_converter, &dir_fd
7091#else
7092 dir_fd_unavailable, &dir_fd
7093#endif
7094 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007096
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007098#ifdef HAVE_READLINKAT
7099 if (dir_fd != DEFAULT_DIR_FD)
7100 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007101 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102#endif
7103 length = readlink(path.narrow, buffer, sizeof(buffer));
7104 Py_END_ALLOW_THREADS
7105
7106 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007107 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 goto exit;
7109 }
7110
7111 if (PyUnicode_Check(path.object))
7112 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7113 else
7114 return_value = PyBytes_FromStringAndSize(buffer, length);
7115exit:
7116 path_cleanup(&path);
7117 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007118}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007119
7120
Guido van Rossumb6775db1994-08-01 11:34:53 +00007121#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007123
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007125PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7127Create a symbolic link pointing to src named dst.\n\n\
7128target_is_directory is required on Windows if the target is to be\n\
7129 interpreted as a directory. (On Windows, symlink requires\n\
7130 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7131 target_is_directory is ignored on non-Windows platforms.\n\
7132\n\
7133If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7134 and path should be relative; path will then be relative to that directory.\n\
7135dir_fd may not be implemented on your platform.\n\
7136 If it is unavailable, using it will raise a NotImplementedError.");
7137
7138#if defined(MS_WINDOWS)
7139
7140/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7141static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7142static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007143
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007145check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146{
7147 HINSTANCE hKernel32;
7148 /* only recheck */
7149 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7150 return 1;
7151 hKernel32 = GetModuleHandleW(L"KERNEL32");
7152 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7153 "CreateSymbolicLinkW");
7154 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7155 "CreateSymbolicLinkA");
7156 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7157}
7158
Victor Stinner31b3b922013-06-05 01:49:17 +02007159/* Remove the last portion of the path */
7160static void
7161_dirnameW(WCHAR *path)
7162{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007163 WCHAR *ptr;
7164
7165 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007166 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007167 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007168 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007169 }
7170 *ptr = 0;
7171}
7172
Victor Stinner31b3b922013-06-05 01:49:17 +02007173/* Remove the last portion of the path */
7174static void
7175_dirnameA(char *path)
7176{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007177 char *ptr;
7178
7179 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007180 for(ptr = path + strlen(path); ptr != path; ptr--) {
7181 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007182 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007183 }
7184 *ptr = 0;
7185}
7186
Victor Stinner31b3b922013-06-05 01:49:17 +02007187/* Is this path absolute? */
7188static int
7189_is_absW(const WCHAR *path)
7190{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007191 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7192
7193}
7194
Victor Stinner31b3b922013-06-05 01:49:17 +02007195/* Is this path absolute? */
7196static int
7197_is_absA(const char *path)
7198{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007199 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7200
7201}
7202
Victor Stinner31b3b922013-06-05 01:49:17 +02007203/* join root and rest with a backslash */
7204static void
7205_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *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_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007210 wcscpy(dest_path, rest);
7211 return;
7212 }
7213
7214 root_len = wcslen(root);
7215
7216 wcscpy(dest_path, root);
7217 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007218 dest_path[root_len] = L'\\';
7219 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007220 }
7221 wcscpy(dest_path+root_len, rest);
7222}
7223
Victor Stinner31b3b922013-06-05 01:49:17 +02007224/* join root and rest with a backslash */
7225static void
7226_joinA(char *dest_path, const char *root, const char *rest)
7227{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007228 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007229
Victor Stinner31b3b922013-06-05 01:49:17 +02007230 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231 strcpy(dest_path, rest);
7232 return;
7233 }
7234
7235 root_len = strlen(root);
7236
7237 strcpy(dest_path, root);
7238 if(root_len) {
7239 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007240 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007241 }
7242 strcpy(dest_path+root_len, rest);
7243}
7244
Victor Stinner31b3b922013-06-05 01:49:17 +02007245/* Return True if the path at src relative to dest is a directory */
7246static int
7247_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 WIN32_FILE_ATTRIBUTE_DATA src_info;
7250 WCHAR dest_parent[MAX_PATH];
7251 WCHAR src_resolved[MAX_PATH] = L"";
7252
7253 /* dest_parent = os.path.dirname(dest) */
7254 wcscpy(dest_parent, dest);
7255 _dirnameW(dest_parent);
7256 /* src_resolved = os.path.join(dest_parent, src) */
7257 _joinW(src_resolved, dest_parent, src);
7258 return (
7259 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7260 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7261 );
7262}
7263
Victor Stinner31b3b922013-06-05 01:49:17 +02007264/* Return True if the path at src relative to dest is a directory */
7265static int
7266_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007267{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268 WIN32_FILE_ATTRIBUTE_DATA src_info;
7269 char dest_parent[MAX_PATH];
7270 char src_resolved[MAX_PATH] = "";
7271
7272 /* dest_parent = os.path.dirname(dest) */
7273 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007274 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007276 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 return (
7278 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7279 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7280 );
7281}
7282
Larry Hastings9cf065c2012-06-22 16:30:09 -07007283#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007284
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007286posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288 path_t src;
7289 path_t dst;
7290 int dir_fd = DEFAULT_DIR_FD;
7291 int target_is_directory = 0;
7292 static char *keywords[] = {"src", "dst", "target_is_directory",
7293 "dir_fd", NULL};
7294 PyObject *return_value;
7295#ifdef MS_WINDOWS
7296 DWORD result;
7297#else
7298 int result;
7299#endif
7300
7301 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007302 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007303 src.argument_name = "src";
7304 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007305 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007306 dst.argument_name = "dst";
7307
7308#ifdef MS_WINDOWS
7309 if (!check_CreateSymbolicLink()) {
7310 PyErr_SetString(PyExc_NotImplementedError,
7311 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007312 return NULL;
7313 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007314 if (!win32_can_symlink) {
7315 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007316 return NULL;
7317 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007318#endif
7319
7320 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7321 keywords,
7322 path_converter, &src,
7323 path_converter, &dst,
7324 &target_is_directory,
7325#ifdef HAVE_SYMLINKAT
7326 dir_fd_converter, &dir_fd
7327#else
7328 dir_fd_unavailable, &dir_fd
7329#endif
7330 ))
7331 return NULL;
7332
7333 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7334 PyErr_SetString(PyExc_ValueError,
7335 "symlink: src and dst must be the same type");
7336 return_value = NULL;
7337 goto exit;
7338 }
7339
7340#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007341
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 if (dst.wide) {
7344 /* if src is a directory, ensure target_is_directory==1 */
7345 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007346 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7347 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007348 }
7349 else {
7350 /* if src is a directory, ensure target_is_directory==1 */
7351 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007352 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7353 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007354 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007355 Py_END_ALLOW_THREADS
7356
7357 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007358 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359 goto exit;
7360 }
7361
7362#else
7363
7364 Py_BEGIN_ALLOW_THREADS
7365#if HAVE_SYMLINKAT
7366 if (dir_fd != DEFAULT_DIR_FD)
7367 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7368 else
7369#endif
7370 result = symlink(src.narrow, dst.narrow);
7371 Py_END_ALLOW_THREADS
7372
7373 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007374 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007375 goto exit;
7376 }
7377#endif
7378
7379 return_value = Py_None;
7380 Py_INCREF(Py_None);
7381 goto exit; /* silence "unused label" warning */
7382exit:
7383 path_cleanup(&src);
7384 path_cleanup(&dst);
7385 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007386}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007387
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007388#endif /* HAVE_SYMLINK */
7389
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390
Brian Curtind40e6f72010-07-08 21:39:08 +00007391#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7392
Brian Curtind40e6f72010-07-08 21:39:08 +00007393static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007395{
7396 wchar_t *path;
7397 DWORD n_bytes_returned;
7398 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007399 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007400 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007401 HANDLE reparse_point_handle;
7402
7403 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7404 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7405 wchar_t *print_name;
7406
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 static char *keywords[] = {"path", "dir_fd", NULL};
7408
7409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7410 &po,
7411 dir_fd_unavailable, &dir_fd
7412 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007413 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414
Victor Stinnereb5657a2011-09-30 01:44:27 +02007415 path = PyUnicode_AsUnicode(po);
7416 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007417 return NULL;
7418
7419 /* First get a handle to the reparse point */
7420 Py_BEGIN_ALLOW_THREADS
7421 reparse_point_handle = CreateFileW(
7422 path,
7423 0,
7424 0,
7425 0,
7426 OPEN_EXISTING,
7427 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7428 0);
7429 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007430
Brian Curtind40e6f72010-07-08 21:39:08 +00007431 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007432 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007433
Brian Curtind40e6f72010-07-08 21:39:08 +00007434 Py_BEGIN_ALLOW_THREADS
7435 /* New call DeviceIoControl to read the reparse point */
7436 io_result = DeviceIoControl(
7437 reparse_point_handle,
7438 FSCTL_GET_REPARSE_POINT,
7439 0, 0, /* in buffer */
7440 target_buffer, sizeof(target_buffer),
7441 &n_bytes_returned,
7442 0 /* we're not using OVERLAPPED_IO */
7443 );
7444 CloseHandle(reparse_point_handle);
7445 Py_END_ALLOW_THREADS
7446
7447 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007448 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007449
7450 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7451 {
7452 PyErr_SetString(PyExc_ValueError,
7453 "not a symbolic link");
7454 return NULL;
7455 }
Brian Curtin74e45612010-07-09 15:58:59 +00007456 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7457 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7458
7459 result = PyUnicode_FromWideChar(print_name,
7460 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007461 return result;
7462}
7463
7464#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7465
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007466
Larry Hastings605a62d2012-06-24 04:33:36 -07007467static PyStructSequence_Field times_result_fields[] = {
7468 {"user", "user time"},
7469 {"system", "system time"},
7470 {"children_user", "user time of children"},
7471 {"children_system", "system time of children"},
7472 {"elapsed", "elapsed time since an arbitrary point in the past"},
7473 {NULL}
7474};
7475
7476PyDoc_STRVAR(times_result__doc__,
7477"times_result: Result from os.times().\n\n\
7478This object may be accessed either as a tuple of\n\
7479 (user, system, children_user, children_system, elapsed),\n\
7480or via the attributes user, system, children_user, children_system,\n\
7481and elapsed.\n\
7482\n\
7483See os.times for more information.");
7484
7485static PyStructSequence_Desc times_result_desc = {
7486 "times_result", /* name */
7487 times_result__doc__, /* doc */
7488 times_result_fields,
7489 5
7490};
7491
7492static PyTypeObject TimesResultType;
7493
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007494#ifdef MS_WINDOWS
7495#define HAVE_TIMES /* mandatory, for the method table */
7496#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007497
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007498#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007499
7500static PyObject *
7501build_times_result(double user, double system,
7502 double children_user, double children_system,
7503 double elapsed)
7504{
7505 PyObject *value = PyStructSequence_New(&TimesResultType);
7506 if (value == NULL)
7507 return NULL;
7508
7509#define SET(i, field) \
7510 { \
7511 PyObject *o = PyFloat_FromDouble(field); \
7512 if (!o) { \
7513 Py_DECREF(value); \
7514 return NULL; \
7515 } \
7516 PyStructSequence_SET_ITEM(value, i, o); \
7517 } \
7518
7519 SET(0, user);
7520 SET(1, system);
7521 SET(2, children_user);
7522 SET(3, children_system);
7523 SET(4, elapsed);
7524
7525#undef SET
7526
7527 return value;
7528}
7529
7530PyDoc_STRVAR(posix_times__doc__,
7531"times() -> times_result\n\n\
7532Return an object containing floating point numbers indicating process\n\
7533times. The object behaves like a named tuple with these fields:\n\
7534 (utime, stime, cutime, cstime, elapsed_time)");
7535
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007536#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007537static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007538posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007539{
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 FILETIME create, exit, kernel, user;
7541 HANDLE hProc;
7542 hProc = GetCurrentProcess();
7543 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7544 /* The fields of a FILETIME structure are the hi and lo part
7545 of a 64-bit value expressed in 100 nanosecond units.
7546 1e7 is one second in such units; 1e-7 the inverse.
7547 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7548 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007549 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007550 (double)(user.dwHighDateTime*429.4967296 +
7551 user.dwLowDateTime*1e-7),
7552 (double)(kernel.dwHighDateTime*429.4967296 +
7553 kernel.dwLowDateTime*1e-7),
7554 (double)0,
7555 (double)0,
7556 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007557}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007558#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007559#define NEED_TICKS_PER_SECOND
7560static long ticks_per_second = -1;
7561static PyObject *
7562posix_times(PyObject *self, PyObject *noargs)
7563{
7564 struct tms t;
7565 clock_t c;
7566 errno = 0;
7567 c = times(&t);
7568 if (c == (clock_t) -1)
7569 return posix_error();
7570 return build_times_result(
7571 (double)t.tms_utime / ticks_per_second,
7572 (double)t.tms_stime / ticks_per_second,
7573 (double)t.tms_cutime / ticks_per_second,
7574 (double)t.tms_cstime / ticks_per_second,
7575 (double)c / ticks_per_second);
7576}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007577#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007578
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007579#endif /* HAVE_TIMES */
7580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007581
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007582#ifdef HAVE_GETSID
7583PyDoc_STRVAR(posix_getsid__doc__,
7584"getsid(pid) -> sid\n\n\
7585Call the system call getsid().");
7586
7587static PyObject *
7588posix_getsid(PyObject *self, PyObject *args)
7589{
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 pid_t pid;
7591 int sid;
7592 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7593 return NULL;
7594 sid = getsid(pid);
7595 if (sid < 0)
7596 return posix_error();
7597 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007598}
7599#endif /* HAVE_GETSID */
7600
7601
Guido van Rossumb6775db1994-08-01 11:34:53 +00007602#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007603PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007604"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007605Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007606
Barry Warsaw53699e91996-12-10 23:23:01 +00007607static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007608posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609{
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 if (setsid() < 0)
7611 return posix_error();
7612 Py_INCREF(Py_None);
7613 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007614}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007615#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007616
Guido van Rossumb6775db1994-08-01 11:34:53 +00007617#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007618PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007619"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007620Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007621
Barry Warsaw53699e91996-12-10 23:23:01 +00007622static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007623posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007624{
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 pid_t pid;
7626 int pgrp;
7627 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7628 return NULL;
7629 if (setpgid(pid, pgrp) < 0)
7630 return posix_error();
7631 Py_INCREF(Py_None);
7632 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007633}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007634#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007636
Guido van Rossumb6775db1994-08-01 11:34:53 +00007637#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007638PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007639"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007640Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007641
Barry Warsaw53699e91996-12-10 23:23:01 +00007642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007643posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007644{
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 int fd;
7646 pid_t pgid;
7647 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7648 return NULL;
7649 pgid = tcgetpgrp(fd);
7650 if (pgid < 0)
7651 return posix_error();
7652 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007653}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007655
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007656
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007658PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007659"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007660Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007661
Barry Warsaw53699e91996-12-10 23:23:01 +00007662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007663posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007664{
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 int fd;
7666 pid_t pgid;
7667 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7668 return NULL;
7669 if (tcsetpgrp(fd, pgid) < 0)
7670 return posix_error();
7671 Py_INCREF(Py_None);
7672 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007673}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007675
Guido van Rossum687dd131993-05-17 08:34:16 +00007676/* Functions acting on file descriptors */
7677
Victor Stinnerdaf45552013-08-28 00:53:59 +02007678#ifdef O_CLOEXEC
7679extern int _Py_open_cloexec_works;
7680#endif
7681
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007682PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007683"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7684Open a file for low level IO. Returns a file handle (integer).\n\
7685\n\
7686If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7687 and path should be relative; path will then be relative to that directory.\n\
7688dir_fd may not be implemented on your platform.\n\
7689 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007690
Barry Warsaw53699e91996-12-10 23:23:01 +00007691static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007692posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007693{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694 path_t path;
7695 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007699 PyObject *return_value = NULL;
7700 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701#ifdef O_CLOEXEC
7702 int *atomic_flag_works = &_Py_open_cloexec_works;
7703#elif !defined(MS_WINDOWS)
7704 int *atomic_flag_works = NULL;
7705#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007706
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007708 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007709 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7710 path_converter, &path,
7711 &flags, &mode,
7712#ifdef HAVE_OPENAT
7713 dir_fd_converter, &dir_fd
7714#else
7715 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007716#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007717 ))
7718 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007719
Victor Stinnerdaf45552013-08-28 00:53:59 +02007720#ifdef MS_WINDOWS
7721 flags |= O_NOINHERIT;
7722#elif defined(O_CLOEXEC)
7723 flags |= O_CLOEXEC;
7724#endif
7725
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727#ifdef MS_WINDOWS
7728 if (path.wide)
7729 fd = _wopen(path.wide, flags, mode);
7730 else
7731#endif
7732#ifdef HAVE_OPENAT
7733 if (dir_fd != DEFAULT_DIR_FD)
7734 fd = openat(dir_fd, path.narrow, flags, mode);
7735 else
7736#endif
7737 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007739
Larry Hastings9cf065c2012-06-22 16:30:09 -07007740 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007741 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742 goto exit;
7743 }
7744
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifndef MS_WINDOWS
7746 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7747 close(fd);
7748 goto exit;
7749 }
7750#endif
7751
Larry Hastings9cf065c2012-06-22 16:30:09 -07007752 return_value = PyLong_FromLong((long)fd);
7753
7754exit:
7755 path_cleanup(&path);
7756 return return_value;
7757}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007759PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007760"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007761Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007762
Barry Warsaw53699e91996-12-10 23:23:01 +00007763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007764posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007765{
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 int fd, res;
7767 if (!PyArg_ParseTuple(args, "i:close", &fd))
7768 return NULL;
7769 if (!_PyVerify_fd(fd))
7770 return posix_error();
7771 Py_BEGIN_ALLOW_THREADS
7772 res = close(fd);
7773 Py_END_ALLOW_THREADS
7774 if (res < 0)
7775 return posix_error();
7776 Py_INCREF(Py_None);
7777 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007778}
7779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007780
Victor Stinner8c62be82010-05-06 00:08:46 +00007781PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007782"closerange(fd_low, fd_high)\n\n\
7783Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7784
7785static PyObject *
7786posix_closerange(PyObject *self, PyObject *args)
7787{
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 int fd_from, fd_to, i;
7789 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7790 return NULL;
7791 Py_BEGIN_ALLOW_THREADS
7792 for (i = fd_from; i < fd_to; i++)
7793 if (_PyVerify_fd(i))
7794 close(i);
7795 Py_END_ALLOW_THREADS
7796 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007797}
7798
7799
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007800PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007801"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007802Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007803
Barry Warsaw53699e91996-12-10 23:23:01 +00007804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007805posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007806{
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007808
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7810 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007811
Victor Stinnerdaf45552013-08-28 00:53:59 +02007812 fd = _Py_dup(fd);
7813 if (fd == -1)
7814 return NULL;
7815
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007817}
7818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007820PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007821"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007822Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007823
Barry Warsaw53699e91996-12-10 23:23:01 +00007824static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007825posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007826{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007827 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7828 int fd, fd2;
7829 int inheritable = 1;
7830 int res;
7831#if defined(HAVE_DUP3) && \
7832 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7833 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7834 int dup3_works = -1;
7835#endif
7836
7837 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7838 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 if (!_PyVerify_fd_dup2(fd, fd2))
7842 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007843
7844#ifdef MS_WINDOWS
7845 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007847 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 if (res < 0)
7849 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007850
7851 /* Character files like console cannot be make non-inheritable */
7852 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7853 close(fd2);
7854 return NULL;
7855 }
7856
7857#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7858 Py_BEGIN_ALLOW_THREADS
7859 if (!inheritable)
7860 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7861 else
7862 res = dup2(fd, fd2);
7863 Py_END_ALLOW_THREADS
7864 if (res < 0)
7865 return posix_error();
7866
7867#else
7868
7869#ifdef HAVE_DUP3
7870 if (!inheritable && dup3_works != 0) {
7871 Py_BEGIN_ALLOW_THREADS
7872 res = dup3(fd, fd2, O_CLOEXEC);
7873 Py_END_ALLOW_THREADS
7874 if (res < 0) {
7875 if (dup3_works == -1)
7876 dup3_works = (errno != ENOSYS);
7877 if (dup3_works)
7878 return posix_error();
7879 }
7880 }
7881
7882 if (inheritable || dup3_works == 0)
7883 {
7884#endif
7885 Py_BEGIN_ALLOW_THREADS
7886 res = dup2(fd, fd2);
7887 Py_END_ALLOW_THREADS
7888 if (res < 0)
7889 return posix_error();
7890
7891 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7892 close(fd2);
7893 return NULL;
7894 }
7895#ifdef HAVE_DUP3
7896 }
7897#endif
7898
7899#endif
7900
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 Py_INCREF(Py_None);
7902 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007903}
7904
Ross Lagerwall7807c352011-03-17 20:20:30 +02007905#ifdef HAVE_LOCKF
7906PyDoc_STRVAR(posix_lockf__doc__,
7907"lockf(fd, cmd, len)\n\n\
7908Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7909fd is an open file descriptor.\n\
7910cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7911F_TEST.\n\
7912len specifies the section of the file to lock.");
7913
7914static PyObject *
7915posix_lockf(PyObject *self, PyObject *args)
7916{
7917 int fd, cmd, res;
7918 off_t len;
7919 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7920 &fd, &cmd, _parse_off_t, &len))
7921 return NULL;
7922
7923 Py_BEGIN_ALLOW_THREADS
7924 res = lockf(fd, cmd, len);
7925 Py_END_ALLOW_THREADS
7926
7927 if (res < 0)
7928 return posix_error();
7929
7930 Py_RETURN_NONE;
7931}
7932#endif
7933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007934
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007935PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007936"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007937Set the current position of a file descriptor.\n\
7938Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007939
Barry Warsaw53699e91996-12-10 23:23:01 +00007940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007941posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007942{
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007944#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007946#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007948#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007949 PyObject *posobj;
7950 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007952#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7954 switch (how) {
7955 case 0: how = SEEK_SET; break;
7956 case 1: how = SEEK_CUR; break;
7957 case 2: how = SEEK_END; break;
7958 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007959#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007960
Ross Lagerwall8e749672011-03-17 21:54:07 +02007961#if !defined(HAVE_LARGEFILE_SUPPORT)
7962 pos = PyLong_AsLong(posobj);
7963#else
7964 pos = PyLong_AsLongLong(posobj);
7965#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (PyErr_Occurred())
7967 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007968
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 if (!_PyVerify_fd(fd))
7970 return posix_error();
7971 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007972#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007974#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 Py_END_ALLOW_THREADS
7978 if (res < 0)
7979 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980
7981#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007985#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007986}
7987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007989PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007990"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007991Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007992
Barry Warsaw53699e91996-12-10 23:23:01 +00007993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007994posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007995{
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 int fd, size;
7997 Py_ssize_t n;
7998 PyObject *buffer;
7999 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8000 return NULL;
8001 if (size < 0) {
8002 errno = EINVAL;
8003 return posix_error();
8004 }
8005 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8006 if (buffer == NULL)
8007 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008008 if (!_PyVerify_fd(fd)) {
8009 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008011 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 Py_BEGIN_ALLOW_THREADS
8013 n = read(fd, PyBytes_AS_STRING(buffer), size);
8014 Py_END_ALLOW_THREADS
8015 if (n < 0) {
8016 Py_DECREF(buffer);
8017 return posix_error();
8018 }
8019 if (n != size)
8020 _PyBytes_Resize(&buffer, n);
8021 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008022}
8023
Ross Lagerwall7807c352011-03-17 20:20:30 +02008024#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8025 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008026static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008027iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8028{
8029 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008030 Py_ssize_t blen, total = 0;
8031
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 *iov = PyMem_New(struct iovec, cnt);
8033 if (*iov == NULL) {
8034 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008036 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008037
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 *buf = PyMem_New(Py_buffer, cnt);
8039 if (*buf == NULL) {
8040 PyMem_Del(*iov);
8041 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008042 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 }
8044
8045 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008046 PyObject *item = PySequence_GetItem(seq, i);
8047 if (item == NULL)
8048 goto fail;
8049 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8050 Py_DECREF(item);
8051 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008052 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008053 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008055 blen = (*buf)[i].len;
8056 (*iov)[i].iov_len = blen;
8057 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008059 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008060
8061fail:
8062 PyMem_Del(*iov);
8063 for (j = 0; j < i; j++) {
8064 PyBuffer_Release(&(*buf)[j]);
8065 }
8066 PyMem_Del(*buf);
8067 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068}
8069
8070static void
8071iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8072{
8073 int i;
8074 PyMem_Del(iov);
8075 for (i = 0; i < cnt; i++) {
8076 PyBuffer_Release(&buf[i]);
8077 }
8078 PyMem_Del(buf);
8079}
8080#endif
8081
Ross Lagerwall7807c352011-03-17 20:20:30 +02008082#ifdef HAVE_READV
8083PyDoc_STRVAR(posix_readv__doc__,
8084"readv(fd, buffers) -> bytesread\n\n\
8085Read from a file descriptor into a number of writable buffers. buffers\n\
8086is an arbitrary sequence of writable buffers.\n\
8087Returns the total number of bytes read.");
8088
8089static PyObject *
8090posix_readv(PyObject *self, PyObject *args)
8091{
8092 int fd, cnt;
8093 Py_ssize_t n;
8094 PyObject *seq;
8095 struct iovec *iov;
8096 Py_buffer *buf;
8097
8098 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8099 return NULL;
8100 if (!PySequence_Check(seq)) {
8101 PyErr_SetString(PyExc_TypeError,
8102 "readv() arg 2 must be a sequence");
8103 return NULL;
8104 }
8105 cnt = PySequence_Size(seq);
8106
8107 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8108 return NULL;
8109
8110 Py_BEGIN_ALLOW_THREADS
8111 n = readv(fd, iov, cnt);
8112 Py_END_ALLOW_THREADS
8113
8114 iov_cleanup(iov, buf, cnt);
8115 return PyLong_FromSsize_t(n);
8116}
8117#endif
8118
8119#ifdef HAVE_PREAD
8120PyDoc_STRVAR(posix_pread__doc__,
8121"pread(fd, buffersize, offset) -> string\n\n\
8122Read from a file descriptor, fd, at a position of offset. It will read up\n\
8123to buffersize number of bytes. The file offset remains unchanged.");
8124
8125static PyObject *
8126posix_pread(PyObject *self, PyObject *args)
8127{
8128 int fd, size;
8129 off_t offset;
8130 Py_ssize_t n;
8131 PyObject *buffer;
8132 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8133 return NULL;
8134
8135 if (size < 0) {
8136 errno = EINVAL;
8137 return posix_error();
8138 }
8139 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8140 if (buffer == NULL)
8141 return NULL;
8142 if (!_PyVerify_fd(fd)) {
8143 Py_DECREF(buffer);
8144 return posix_error();
8145 }
8146 Py_BEGIN_ALLOW_THREADS
8147 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8148 Py_END_ALLOW_THREADS
8149 if (n < 0) {
8150 Py_DECREF(buffer);
8151 return posix_error();
8152 }
8153 if (n != size)
8154 _PyBytes_Resize(&buffer, n);
8155 return buffer;
8156}
8157#endif
8158
8159PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008160"write(fd, data) -> byteswritten\n\n\
8161Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008162
8163static PyObject *
8164posix_write(PyObject *self, PyObject *args)
8165{
8166 Py_buffer pbuf;
8167 int fd;
8168 Py_ssize_t size, len;
8169
8170 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8171 return NULL;
8172 if (!_PyVerify_fd(fd)) {
8173 PyBuffer_Release(&pbuf);
8174 return posix_error();
8175 }
8176 len = pbuf.len;
8177 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008178#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008179 if (len > INT_MAX)
8180 len = INT_MAX;
8181 size = write(fd, pbuf.buf, (int)len);
8182#else
8183 size = write(fd, pbuf.buf, len);
8184#endif
8185 Py_END_ALLOW_THREADS
8186 PyBuffer_Release(&pbuf);
8187 if (size < 0)
8188 return posix_error();
8189 return PyLong_FromSsize_t(size);
8190}
8191
8192#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008193PyDoc_STRVAR(posix_sendfile__doc__,
8194"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8195sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8196 -> byteswritten\n\
8197Copy nbytes bytes from file descriptor in to file descriptor out.");
8198
8199static PyObject *
8200posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8201{
8202 int in, out;
8203 Py_ssize_t ret;
8204 off_t offset;
8205
8206#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8207#ifndef __APPLE__
8208 Py_ssize_t len;
8209#endif
8210 PyObject *headers = NULL, *trailers = NULL;
8211 Py_buffer *hbuf, *tbuf;
8212 off_t sbytes;
8213 struct sf_hdtr sf;
8214 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008215 static char *keywords[] = {"out", "in",
8216 "offset", "count",
8217 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008219 sf.headers = NULL;
8220 sf.trailers = NULL;
8221
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008222#ifdef __APPLE__
8223 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008224 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225#else
8226 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008227 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008228#endif
8229 &headers, &trailers, &flags))
8230 return NULL;
8231 if (headers != NULL) {
8232 if (!PySequence_Check(headers)) {
8233 PyErr_SetString(PyExc_TypeError,
8234 "sendfile() headers must be a sequence or None");
8235 return NULL;
8236 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008237 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008239 if (sf.hdr_cnt > 0 &&
8240 !(i = iov_setup(&(sf.headers), &hbuf,
8241 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008243#ifdef __APPLE__
8244 sbytes += i;
8245#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008246 }
8247 }
8248 if (trailers != NULL) {
8249 if (!PySequence_Check(trailers)) {
8250 PyErr_SetString(PyExc_TypeError,
8251 "sendfile() trailers must be a sequence or None");
8252 return NULL;
8253 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008254 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008256 if (sf.trl_cnt > 0 &&
8257 !(i = iov_setup(&(sf.trailers), &tbuf,
8258 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008259 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008260#ifdef __APPLE__
8261 sbytes += i;
8262#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008263 }
8264 }
8265
8266 Py_BEGIN_ALLOW_THREADS
8267#ifdef __APPLE__
8268 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8269#else
8270 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8271#endif
8272 Py_END_ALLOW_THREADS
8273
8274 if (sf.headers != NULL)
8275 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8276 if (sf.trailers != NULL)
8277 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8278
8279 if (ret < 0) {
8280 if ((errno == EAGAIN) || (errno == EBUSY)) {
8281 if (sbytes != 0) {
8282 // some data has been sent
8283 goto done;
8284 }
8285 else {
8286 // no data has been sent; upper application is supposed
8287 // to retry on EAGAIN or EBUSY
8288 return posix_error();
8289 }
8290 }
8291 return posix_error();
8292 }
8293 goto done;
8294
8295done:
8296 #if !defined(HAVE_LARGEFILE_SUPPORT)
8297 return Py_BuildValue("l", sbytes);
8298 #else
8299 return Py_BuildValue("L", sbytes);
8300 #endif
8301
8302#else
8303 Py_ssize_t count;
8304 PyObject *offobj;
8305 static char *keywords[] = {"out", "in",
8306 "offset", "count", NULL};
8307 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8308 keywords, &out, &in, &offobj, &count))
8309 return NULL;
8310#ifdef linux
8311 if (offobj == Py_None) {
8312 Py_BEGIN_ALLOW_THREADS
8313 ret = sendfile(out, in, NULL, count);
8314 Py_END_ALLOW_THREADS
8315 if (ret < 0)
8316 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008317 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 }
8319#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008320 if (!_parse_off_t(offobj, &offset))
8321 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 Py_BEGIN_ALLOW_THREADS
8323 ret = sendfile(out, in, &offset, count);
8324 Py_END_ALLOW_THREADS
8325 if (ret < 0)
8326 return posix_error();
8327 return Py_BuildValue("n", ret);
8328#endif
8329}
8330#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008331
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008332PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008333"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008334Like stat(), but for an open file descriptor.\n\
8335Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008336
Barry Warsaw53699e91996-12-10 23:23:01 +00008337static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008338posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008339{
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 int fd;
8341 STRUCT_STAT st;
8342 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008343 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008345#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 /* on OpenVMS we must ensure that all bytes are written to the file */
8347 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008348#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 Py_BEGIN_ALLOW_THREADS
8350 res = FSTAT(fd, &st);
8351 Py_END_ALLOW_THREADS
8352 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008353#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008354 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008355#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008357#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 }
Tim Peters5aa91602002-01-30 05:46:57 +00008359
Victor Stinner4195b5c2012-02-08 23:03:19 +01008360 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008361}
8362
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008363PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008364"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008365Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008366connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008367
8368static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008369posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008370{
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 int fd;
8372 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8373 return NULL;
8374 if (!_PyVerify_fd(fd))
8375 return PyBool_FromLong(0);
8376 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008377}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008378
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008379#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008380PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008381"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008382Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008383
Barry Warsaw53699e91996-12-10 23:23:01 +00008384static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008385posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008386{
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008388#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008390 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008392#else
8393 int res;
8394#endif
8395
8396#ifdef MS_WINDOWS
8397 attr.nLength = sizeof(attr);
8398 attr.lpSecurityDescriptor = NULL;
8399 attr.bInheritHandle = FALSE;
8400
8401 Py_BEGIN_ALLOW_THREADS
8402 ok = CreatePipe(&read, &write, &attr, 0);
8403 if (ok) {
8404 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8405 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8406 if (fds[0] == -1 || fds[1] == -1) {
8407 CloseHandle(read);
8408 CloseHandle(write);
8409 ok = 0;
8410 }
8411 }
8412 Py_END_ALLOW_THREADS
8413
Victor Stinner8c62be82010-05-06 00:08:46 +00008414 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008415 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008416#else
8417
8418#ifdef HAVE_PIPE2
8419 Py_BEGIN_ALLOW_THREADS
8420 res = pipe2(fds, O_CLOEXEC);
8421 Py_END_ALLOW_THREADS
8422
8423 if (res != 0 && errno == ENOSYS)
8424 {
8425#endif
8426 Py_BEGIN_ALLOW_THREADS
8427 res = pipe(fds);
8428 Py_END_ALLOW_THREADS
8429
8430 if (res == 0) {
8431 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8432 close(fds[0]);
8433 close(fds[1]);
8434 return NULL;
8435 }
8436 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8437 close(fds[0]);
8438 close(fds[1]);
8439 return NULL;
8440 }
8441 }
8442#ifdef HAVE_PIPE2
8443 }
8444#endif
8445
8446 if (res != 0)
8447 return PyErr_SetFromErrno(PyExc_OSError);
8448#endif /* !MS_WINDOWS */
8449 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008450}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008451#endif /* HAVE_PIPE */
8452
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008453#ifdef HAVE_PIPE2
8454PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008455"pipe2(flags) -> (read_end, write_end)\n\n\
8456Create a pipe with flags set atomically.\n\
8457flags can be constructed by ORing together one or more of these values:\n\
8458O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008459");
8460
8461static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008462posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008463{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008464 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008465 int fds[2];
8466 int res;
8467
Serhiy Storchaka78980432013-01-15 01:12:17 +02008468 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008469 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008470 return NULL;
8471
8472 res = pipe2(fds, flags);
8473 if (res != 0)
8474 return posix_error();
8475 return Py_BuildValue("(ii)", fds[0], fds[1]);
8476}
8477#endif /* HAVE_PIPE2 */
8478
Ross Lagerwall7807c352011-03-17 20:20:30 +02008479#ifdef HAVE_WRITEV
8480PyDoc_STRVAR(posix_writev__doc__,
8481"writev(fd, buffers) -> byteswritten\n\n\
8482Write the contents of buffers to a file descriptor, where buffers is an\n\
8483arbitrary sequence of buffers.\n\
8484Returns the total bytes written.");
8485
8486static PyObject *
8487posix_writev(PyObject *self, PyObject *args)
8488{
8489 int fd, cnt;
8490 Py_ssize_t res;
8491 PyObject *seq;
8492 struct iovec *iov;
8493 Py_buffer *buf;
8494 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8495 return NULL;
8496 if (!PySequence_Check(seq)) {
8497 PyErr_SetString(PyExc_TypeError,
8498 "writev() arg 2 must be a sequence");
8499 return NULL;
8500 }
8501 cnt = PySequence_Size(seq);
8502
8503 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8504 return NULL;
8505 }
8506
8507 Py_BEGIN_ALLOW_THREADS
8508 res = writev(fd, iov, cnt);
8509 Py_END_ALLOW_THREADS
8510
8511 iov_cleanup(iov, buf, cnt);
8512 return PyLong_FromSsize_t(res);
8513}
8514#endif
8515
8516#ifdef HAVE_PWRITE
8517PyDoc_STRVAR(posix_pwrite__doc__,
8518"pwrite(fd, string, offset) -> byteswritten\n\n\
8519Write string to a file descriptor, fd, from offset, leaving the file\n\
8520offset unchanged.");
8521
8522static PyObject *
8523posix_pwrite(PyObject *self, PyObject *args)
8524{
8525 Py_buffer pbuf;
8526 int fd;
8527 off_t offset;
8528 Py_ssize_t size;
8529
8530 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8531 return NULL;
8532
8533 if (!_PyVerify_fd(fd)) {
8534 PyBuffer_Release(&pbuf);
8535 return posix_error();
8536 }
8537 Py_BEGIN_ALLOW_THREADS
8538 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8539 Py_END_ALLOW_THREADS
8540 PyBuffer_Release(&pbuf);
8541 if (size < 0)
8542 return posix_error();
8543 return PyLong_FromSsize_t(size);
8544}
8545#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008546
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008547#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008548PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008549"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8550Create a FIFO (a POSIX named pipe).\n\
8551\n\
8552If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8553 and path should be relative; path will then be relative to that directory.\n\
8554dir_fd may not be implemented on your platform.\n\
8555 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008556
Barry Warsaw53699e91996-12-10 23:23:01 +00008557static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008558posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008559{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008560 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008562 int dir_fd = DEFAULT_DIR_FD;
8563 int result;
8564 PyObject *return_value = NULL;
8565 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8566
8567 memset(&path, 0, sizeof(path));
8568 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8569 path_converter, &path,
8570 &mode,
8571#ifdef HAVE_MKFIFOAT
8572 dir_fd_converter, &dir_fd
8573#else
8574 dir_fd_unavailable, &dir_fd
8575#endif
8576 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008578
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008580#ifdef HAVE_MKFIFOAT
8581 if (dir_fd != DEFAULT_DIR_FD)
8582 result = mkfifoat(dir_fd, path.narrow, mode);
8583 else
8584#endif
8585 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008587
8588 if (result < 0) {
8589 return_value = posix_error();
8590 goto exit;
8591 }
8592
8593 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008594 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008595
8596exit:
8597 path_cleanup(&path);
8598 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008599}
8600#endif
8601
Neal Norwitz11690112002-07-30 01:08:28 +00008602#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008603PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008604"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008605Create a filesystem node (file, device special file or named pipe)\n\
8606named filename. mode specifies both the permissions to use and the\n\
8607type of node to be created, being combined (bitwise OR) with one of\n\
8608S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008609device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008610os.makedev()), otherwise it is ignored.\n\
8611\n\
8612If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8613 and path should be relative; path will then be relative to that directory.\n\
8614dir_fd may not be implemented on your platform.\n\
8615 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008616
8617
8618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008619posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008621 path_t path;
8622 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008624 int dir_fd = DEFAULT_DIR_FD;
8625 int result;
8626 PyObject *return_value = NULL;
8627 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8628
8629 memset(&path, 0, sizeof(path));
8630 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8631 path_converter, &path,
8632 &mode, &device,
8633#ifdef HAVE_MKNODAT
8634 dir_fd_converter, &dir_fd
8635#else
8636 dir_fd_unavailable, &dir_fd
8637#endif
8638 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008640
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008642#ifdef HAVE_MKNODAT
8643 if (dir_fd != DEFAULT_DIR_FD)
8644 result = mknodat(dir_fd, path.narrow, mode, device);
8645 else
8646#endif
8647 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008649
8650 if (result < 0) {
8651 return_value = posix_error();
8652 goto exit;
8653 }
8654
8655 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008656 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008657
Larry Hastings9cf065c2012-06-22 16:30:09 -07008658exit:
8659 path_cleanup(&path);
8660 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008661}
8662#endif
8663
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008664#ifdef HAVE_DEVICE_MACROS
8665PyDoc_STRVAR(posix_major__doc__,
8666"major(device) -> major number\n\
8667Extracts a device major number from a raw device number.");
8668
8669static PyObject *
8670posix_major(PyObject *self, PyObject *args)
8671{
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 int device;
8673 if (!PyArg_ParseTuple(args, "i:major", &device))
8674 return NULL;
8675 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008676}
8677
8678PyDoc_STRVAR(posix_minor__doc__,
8679"minor(device) -> minor number\n\
8680Extracts a device minor number from a raw device number.");
8681
8682static PyObject *
8683posix_minor(PyObject *self, PyObject *args)
8684{
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 int device;
8686 if (!PyArg_ParseTuple(args, "i:minor", &device))
8687 return NULL;
8688 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008689}
8690
8691PyDoc_STRVAR(posix_makedev__doc__,
8692"makedev(major, minor) -> device number\n\
8693Composes a raw device number from the major and minor device numbers.");
8694
8695static PyObject *
8696posix_makedev(PyObject *self, PyObject *args)
8697{
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 int major, minor;
8699 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8700 return NULL;
8701 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008702}
8703#endif /* device macros */
8704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008705
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008706#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008707PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008708"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008709Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008710
Barry Warsaw53699e91996-12-10 23:23:01 +00008711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008712posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008713{
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 int fd;
8715 off_t length;
8716 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008717
Ross Lagerwall7807c352011-03-17 20:20:30 +02008718 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008720
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 Py_BEGIN_ALLOW_THREADS
8722 res = ftruncate(fd, length);
8723 Py_END_ALLOW_THREADS
8724 if (res < 0)
8725 return posix_error();
8726 Py_INCREF(Py_None);
8727 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008728}
8729#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008730
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731#ifdef HAVE_TRUNCATE
8732PyDoc_STRVAR(posix_truncate__doc__,
8733"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008734Truncate the file given by path to length bytes.\n\
8735On some platforms, path may also be specified as an open file descriptor.\n\
8736 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008737
8738static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008739posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008740{
Georg Brandl306336b2012-06-24 12:55:33 +02008741 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742 off_t length;
8743 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008744 PyObject *result = NULL;
8745 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008746
Georg Brandl306336b2012-06-24 12:55:33 +02008747 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008748 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008749#ifdef HAVE_FTRUNCATE
8750 path.allow_fd = 1;
8751#endif
8752 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8753 path_converter, &path,
8754 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008755 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756
8757 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008758#ifdef HAVE_FTRUNCATE
8759 if (path.fd != -1)
8760 res = ftruncate(path.fd, length);
8761 else
8762#endif
8763 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008764 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008765 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008766 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008767 else {
8768 Py_INCREF(Py_None);
8769 result = Py_None;
8770 }
8771 path_cleanup(&path);
8772 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008773}
8774#endif
8775
8776#ifdef HAVE_POSIX_FALLOCATE
8777PyDoc_STRVAR(posix_posix_fallocate__doc__,
8778"posix_fallocate(fd, offset, len)\n\n\
8779Ensures that enough disk space is allocated for the file specified by fd\n\
8780starting from offset and continuing for len bytes.");
8781
8782static PyObject *
8783posix_posix_fallocate(PyObject *self, PyObject *args)
8784{
8785 off_t len, offset;
8786 int res, fd;
8787
8788 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8789 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8790 return NULL;
8791
8792 Py_BEGIN_ALLOW_THREADS
8793 res = posix_fallocate(fd, offset, len);
8794 Py_END_ALLOW_THREADS
8795 if (res != 0) {
8796 errno = res;
8797 return posix_error();
8798 }
8799 Py_RETURN_NONE;
8800}
8801#endif
8802
8803#ifdef HAVE_POSIX_FADVISE
8804PyDoc_STRVAR(posix_posix_fadvise__doc__,
8805"posix_fadvise(fd, offset, len, advice)\n\n\
8806Announces an intention to access data in a specific pattern thus allowing\n\
8807the kernel to make optimizations.\n\
8808The advice applies to the region of the file specified by fd starting at\n\
8809offset and continuing for len bytes.\n\
8810advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8811POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8812POSIX_FADV_DONTNEED.");
8813
8814static PyObject *
8815posix_posix_fadvise(PyObject *self, PyObject *args)
8816{
8817 off_t len, offset;
8818 int res, fd, advice;
8819
8820 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8821 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8822 return NULL;
8823
8824 Py_BEGIN_ALLOW_THREADS
8825 res = posix_fadvise(fd, offset, len, advice);
8826 Py_END_ALLOW_THREADS
8827 if (res != 0) {
8828 errno = res;
8829 return posix_error();
8830 }
8831 Py_RETURN_NONE;
8832}
8833#endif
8834
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008835#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008836PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008837"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008838Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008839
Fred Drake762e2061999-08-26 17:23:54 +00008840/* Save putenv() parameters as values here, so we can collect them when they
8841 * get re-set with another call for the same key. */
8842static PyObject *posix_putenv_garbage;
8843
Tim Peters5aa91602002-01-30 05:46:57 +00008844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008845posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008846{
Victor Stinner84ae1182010-05-06 22:05:07 +00008847 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008848#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008849 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008850 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008851
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008853 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008854 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008856
Victor Stinner65170952011-11-22 22:16:17 +01008857 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008858 if (newstr == NULL) {
8859 PyErr_NoMemory();
8860 goto error;
8861 }
Victor Stinner65170952011-11-22 22:16:17 +01008862 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8863 PyErr_Format(PyExc_ValueError,
8864 "the environment variable is longer than %u characters",
8865 _MAX_ENV);
8866 goto error;
8867 }
8868
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008870 if (newenv == NULL)
8871 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008874 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008875 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008876#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008877 PyObject *os1, *os2;
8878 char *s1, *s2;
8879 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008880
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008881 if (!PyArg_ParseTuple(args,
8882 "O&O&:putenv",
8883 PyUnicode_FSConverter, &os1,
8884 PyUnicode_FSConverter, &os2))
8885 return NULL;
8886 s1 = PyBytes_AsString(os1);
8887 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008888
Victor Stinner65170952011-11-22 22:16:17 +01008889 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008890 if (newstr == NULL) {
8891 PyErr_NoMemory();
8892 goto error;
8893 }
8894
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008898 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008900#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008901
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 /* Install the first arg and newstr in posix_putenv_garbage;
8903 * this will cause previous value to be collected. This has to
8904 * happen after the real putenv() call because the old value
8905 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008906 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 /* really not much we can do; just leak */
8908 PyErr_Clear();
8909 }
8910 else {
8911 Py_DECREF(newstr);
8912 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008913
Martin v. Löwis011e8422009-05-05 04:43:17 +00008914#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 Py_DECREF(os1);
8916 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008917#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008918 Py_RETURN_NONE;
8919
8920error:
8921#ifndef MS_WINDOWS
8922 Py_DECREF(os1);
8923 Py_DECREF(os2);
8924#endif
8925 Py_XDECREF(newstr);
8926 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008927}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008928#endif /* putenv */
8929
Guido van Rossumc524d952001-10-19 01:31:59 +00008930#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008931PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008932"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008933Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008934
8935static PyObject *
8936posix_unsetenv(PyObject *self, PyObject *args)
8937{
Victor Stinner65170952011-11-22 22:16:17 +01008938 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008939#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008940 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008941#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008942
8943 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008944
Victor Stinner65170952011-11-22 22:16:17 +01008945 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008946 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008947
Victor Stinner984890f2011-11-24 13:53:38 +01008948#ifdef HAVE_BROKEN_UNSETENV
8949 unsetenv(PyBytes_AS_STRING(name));
8950#else
Victor Stinner65170952011-11-22 22:16:17 +01008951 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008952 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008953 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008954 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008955 }
Victor Stinner984890f2011-11-24 13:53:38 +01008956#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008957
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 /* Remove the key from posix_putenv_garbage;
8959 * this will cause it to be collected. This has to
8960 * happen after the real unsetenv() call because the
8961 * old value was still accessible until then.
8962 */
Victor Stinner65170952011-11-22 22:16:17 +01008963 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 /* really not much we can do; just leak */
8965 PyErr_Clear();
8966 }
Victor Stinner65170952011-11-22 22:16:17 +01008967 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008968 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008969}
8970#endif /* unsetenv */
8971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008972PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008973"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008974Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008975
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008977posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008978{
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 int code;
8980 char *message;
8981 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8982 return NULL;
8983 message = strerror(code);
8984 if (message == NULL) {
8985 PyErr_SetString(PyExc_ValueError,
8986 "strerror() argument out of range");
8987 return NULL;
8988 }
Victor Stinner1b579672011-12-17 05:47:23 +01008989 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008990}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008991
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008992
Guido van Rossumc9641791998-08-04 15:26:23 +00008993#ifdef HAVE_SYS_WAIT_H
8994
Fred Drake106c1a02002-04-23 15:58:02 +00008995#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008996PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008997"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008998Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008999
9000static PyObject *
9001posix_WCOREDUMP(PyObject *self, PyObject *args)
9002{
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 WAIT_TYPE status;
9004 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009005
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9007 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009008
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009010}
9011#endif /* WCOREDUMP */
9012
9013#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009014PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009015"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009016Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009017job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009018
9019static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009020posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009021{
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 WAIT_TYPE status;
9023 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009024
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9026 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009027
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009029}
9030#endif /* WIFCONTINUED */
9031
Guido van Rossumc9641791998-08-04 15:26:23 +00009032#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009033PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009034"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009035Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009036
9037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009038posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009039{
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 WAIT_TYPE status;
9041 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009042
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9044 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009045
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009047}
9048#endif /* WIFSTOPPED */
9049
9050#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009051PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009052"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009053Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009054
9055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009056posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009057{
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 WAIT_TYPE status;
9059 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009060
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9062 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009063
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009065}
9066#endif /* WIFSIGNALED */
9067
9068#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009069PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009070"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009071Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009072system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009073
9074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009075posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009076{
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 WAIT_TYPE status;
9078 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009079
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9081 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009082
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009084}
9085#endif /* WIFEXITED */
9086
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009087#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009088PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009089"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009090Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009091
9092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009093posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009094{
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 WAIT_TYPE status;
9096 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009097
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9099 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009100
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009102}
9103#endif /* WEXITSTATUS */
9104
9105#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009106PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009107"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009108Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009109value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009110
9111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009112posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009113{
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 WAIT_TYPE status;
9115 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009116
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9118 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009119
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009121}
9122#endif /* WTERMSIG */
9123
9124#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009125PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009126"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009127Return the signal that stopped the process that provided\n\
9128the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009129
9130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009131posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009132{
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 WAIT_TYPE status;
9134 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009135
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9137 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009138
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009140}
9141#endif /* WSTOPSIG */
9142
9143#endif /* HAVE_SYS_WAIT_H */
9144
9145
Thomas Wouters477c8d52006-05-27 19:21:47 +00009146#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009147#ifdef _SCO_DS
9148/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9149 needed definitions in sys/statvfs.h */
9150#define _SVID3
9151#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009152#include <sys/statvfs.h>
9153
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009154static PyObject*
9155_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9157 if (v == NULL)
9158 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009159
9160#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9162 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9163 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9164 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9165 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9166 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9167 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9168 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9169 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9170 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009171#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009172 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9173 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9174 PyStructSequence_SET_ITEM(v, 2,
9175 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9176 PyStructSequence_SET_ITEM(v, 3,
9177 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9178 PyStructSequence_SET_ITEM(v, 4,
9179 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9180 PyStructSequence_SET_ITEM(v, 5,
9181 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9182 PyStructSequence_SET_ITEM(v, 6,
9183 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9184 PyStructSequence_SET_ITEM(v, 7,
9185 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9186 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9187 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009188#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009189 if (PyErr_Occurred()) {
9190 Py_DECREF(v);
9191 return NULL;
9192 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009193
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009195}
9196
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009197PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009198"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009199Perform an fstatvfs system call on the given fd.\n\
9200Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009201
9202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009203posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009204{
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 int fd, res;
9206 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009207
Victor Stinner8c62be82010-05-06 00:08:46 +00009208 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9209 return NULL;
9210 Py_BEGIN_ALLOW_THREADS
9211 res = fstatvfs(fd, &st);
9212 Py_END_ALLOW_THREADS
9213 if (res != 0)
9214 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009215
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009217}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009218#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219
9220
Thomas Wouters477c8d52006-05-27 19:21:47 +00009221#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009222#include <sys/statvfs.h>
9223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009224PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009225"statvfs(path)\n\n\
9226Perform a statvfs system call on the given path.\n\
9227\n\
9228path may always be specified as a string.\n\
9229On some platforms, path may also be specified as an open file descriptor.\n\
9230 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009231
9232static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009233posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009234{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009235 static char *keywords[] = {"path", NULL};
9236 path_t path;
9237 int result;
9238 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009240
Larry Hastings9cf065c2012-06-22 16:30:09 -07009241 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009242 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009243#ifdef HAVE_FSTATVFS
9244 path.allow_fd = 1;
9245#endif
9246 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9247 path_converter, &path
9248 ))
9249 return NULL;
9250
9251 Py_BEGIN_ALLOW_THREADS
9252#ifdef HAVE_FSTATVFS
9253 if (path.fd != -1) {
9254#ifdef __APPLE__
9255 /* handle weak-linking on Mac OS X 10.3 */
9256 if (fstatvfs == NULL) {
9257 fd_specified("statvfs", path.fd);
9258 goto exit;
9259 }
9260#endif
9261 result = fstatvfs(path.fd, &st);
9262 }
9263 else
9264#endif
9265 result = statvfs(path.narrow, &st);
9266 Py_END_ALLOW_THREADS
9267
9268 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009269 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009270 goto exit;
9271 }
9272
9273 return_value = _pystatvfs_fromstructstatvfs(st);
9274
9275exit:
9276 path_cleanup(&path);
9277 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009278}
9279#endif /* HAVE_STATVFS */
9280
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009281#ifdef MS_WINDOWS
9282PyDoc_STRVAR(win32__getdiskusage__doc__,
9283"_getdiskusage(path) -> (total, free)\n\n\
9284Return disk usage statistics about the given path as (total, free) tuple.");
9285
9286static PyObject *
9287win32__getdiskusage(PyObject *self, PyObject *args)
9288{
9289 BOOL retval;
9290 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009291 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009292
Victor Stinner6139c1b2011-11-09 22:14:14 +01009293 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009294 return NULL;
9295
9296 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009297 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009298 Py_END_ALLOW_THREADS
9299 if (retval == 0)
9300 return PyErr_SetFromWindowsErr(0);
9301
9302 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9303}
9304#endif
9305
9306
Fred Drakec9680921999-12-13 16:37:25 +00009307/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9308 * It maps strings representing configuration variable names to
9309 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009310 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009311 * rarely-used constants. There are three separate tables that use
9312 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009313 *
9314 * This code is always included, even if none of the interfaces that
9315 * need it are included. The #if hackery needed to avoid it would be
9316 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009317 */
9318struct constdef {
9319 char *name;
9320 long value;
9321};
9322
Fred Drake12c6e2d1999-12-14 21:25:03 +00009323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009324conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009325 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009326{
Christian Heimes217cfd12007-12-02 14:31:20 +00009327 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009328 *valuep = PyLong_AS_LONG(arg);
9329 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009330 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009331 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009332 /* look up the value in the table using a binary search */
9333 size_t lo = 0;
9334 size_t mid;
9335 size_t hi = tablesize;
9336 int cmp;
9337 const char *confname;
9338 if (!PyUnicode_Check(arg)) {
9339 PyErr_SetString(PyExc_TypeError,
9340 "configuration names must be strings or integers");
9341 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009343 confname = _PyUnicode_AsString(arg);
9344 if (confname == NULL)
9345 return 0;
9346 while (lo < hi) {
9347 mid = (lo + hi) / 2;
9348 cmp = strcmp(confname, table[mid].name);
9349 if (cmp < 0)
9350 hi = mid;
9351 else if (cmp > 0)
9352 lo = mid + 1;
9353 else {
9354 *valuep = table[mid].value;
9355 return 1;
9356 }
9357 }
9358 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9359 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009361}
9362
9363
9364#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9365static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009366#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009368#endif
9369#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009371#endif
Fred Drakec9680921999-12-13 16:37:25 +00009372#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009417#ifdef _PC_ACL_ENABLED
9418 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9419#endif
9420#ifdef _PC_MIN_HOLE_SIZE
9421 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9422#endif
9423#ifdef _PC_ALLOC_SIZE_MIN
9424 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9425#endif
9426#ifdef _PC_REC_INCR_XFER_SIZE
9427 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9428#endif
9429#ifdef _PC_REC_MAX_XFER_SIZE
9430 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9431#endif
9432#ifdef _PC_REC_MIN_XFER_SIZE
9433 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9434#endif
9435#ifdef _PC_REC_XFER_ALIGN
9436 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9437#endif
9438#ifdef _PC_SYMLINK_MAX
9439 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9440#endif
9441#ifdef _PC_XATTR_ENABLED
9442 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9443#endif
9444#ifdef _PC_XATTR_EXISTS
9445 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9446#endif
9447#ifdef _PC_TIMESTAMP_RESOLUTION
9448 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9449#endif
Fred Drakec9680921999-12-13 16:37:25 +00009450};
9451
Fred Drakec9680921999-12-13 16:37:25 +00009452static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009453conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009454{
9455 return conv_confname(arg, valuep, posix_constants_pathconf,
9456 sizeof(posix_constants_pathconf)
9457 / sizeof(struct constdef));
9458}
9459#endif
9460
9461#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009462PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009463"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009464Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009465If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009466
9467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009468posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009469{
9470 PyObject *result = NULL;
9471 int name, fd;
9472
Fred Drake12c6e2d1999-12-14 21:25:03 +00009473 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9474 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009475 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009476
Stefan Krah0e803b32010-11-26 16:16:47 +00009477 errno = 0;
9478 limit = fpathconf(fd, name);
9479 if (limit == -1 && errno != 0)
9480 posix_error();
9481 else
9482 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009483 }
9484 return result;
9485}
9486#endif
9487
9488
9489#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009490PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009491"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009492Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009493If there is no limit, return -1.\n\
9494On some platforms, path may also be specified as an open file descriptor.\n\
9495 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009496
9497static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009498posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009499{
Georg Brandl306336b2012-06-24 12:55:33 +02009500 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009501 PyObject *result = NULL;
9502 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009503 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009504
Georg Brandl306336b2012-06-24 12:55:33 +02009505 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009506 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009507#ifdef HAVE_FPATHCONF
9508 path.allow_fd = 1;
9509#endif
9510 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9511 path_converter, &path,
9512 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009514
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009516#ifdef HAVE_FPATHCONF
9517 if (path.fd != -1)
9518 limit = fpathconf(path.fd, name);
9519 else
9520#endif
9521 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 if (limit == -1 && errno != 0) {
9523 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009524 /* could be a path or name problem */
9525 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009526 else
Victor Stinner292c8352012-10-30 02:17:38 +01009527 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 }
9529 else
9530 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009531 }
Georg Brandl306336b2012-06-24 12:55:33 +02009532 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009533 return result;
9534}
9535#endif
9536
9537#ifdef HAVE_CONFSTR
9538static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009539#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009542#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009544#endif
9545#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009547#endif
Fred Draked86ed291999-12-15 15:34:33 +00009548#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009550#endif
9551#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009553#endif
9554#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009556#endif
9557#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009559#endif
Fred Drakec9680921999-12-13 16:37:25 +00009560#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
Fred Draked86ed291999-12-15 15:34:33 +00009584#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009586#endif
Fred Drakec9680921999-12-13 16:37:25 +00009587#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
Fred Draked86ed291999-12-15 15:34:33 +00009590#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009592#endif
9593#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009595#endif
9596#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009598#endif
9599#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009601#endif
Fred Drakec9680921999-12-13 16:37:25 +00009602#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
Fred Draked86ed291999-12-15 15:34:33 +00009650#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
9653#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009655#endif
9656#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
9665#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
9668#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009670#endif
9671#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009673#endif
9674#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009676#endif
9677#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009679#endif
9680#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009682#endif
9683#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009685#endif
9686#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009688#endif
Fred Drakec9680921999-12-13 16:37:25 +00009689};
9690
9691static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009692conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009693{
9694 return conv_confname(arg, valuep, posix_constants_confstr,
9695 sizeof(posix_constants_confstr)
9696 / sizeof(struct constdef));
9697}
9698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009699PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009700"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009701Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009702
9703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009704posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009705{
9706 PyObject *result = NULL;
9707 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009708 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009709 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009710
Victor Stinnercb043522010-09-10 23:49:04 +00009711 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9712 return NULL;
9713
9714 errno = 0;
9715 len = confstr(name, buffer, sizeof(buffer));
9716 if (len == 0) {
9717 if (errno) {
9718 posix_error();
9719 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009720 }
9721 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009722 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009723 }
9724 }
Victor Stinnercb043522010-09-10 23:49:04 +00009725
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009726 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009727 char *buf = PyMem_Malloc(len);
9728 if (buf == NULL)
9729 return PyErr_NoMemory();
9730 confstr(name, buf, len);
9731 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9732 PyMem_Free(buf);
9733 }
9734 else
9735 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009736 return result;
9737}
9738#endif
9739
9740
9741#ifdef HAVE_SYSCONF
9742static struct constdef posix_constants_sysconf[] = {
9743#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
Fred Draked86ed291999-12-15 15:34:33 +00009773#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009775#endif
9776#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
Fred Drakec9680921999-12-13 16:37:25 +00009779#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
Fred Drakec9680921999-12-13 16:37:25 +00009782#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
Fred Draked86ed291999-12-15 15:34:33 +00009797#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
Fred Draked86ed291999-12-15 15:34:33 +00009815#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
Fred Drakec9680921999-12-13 16:37:25 +00009818#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
Fred Draked86ed291999-12-15 15:34:33 +00009887#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
Fred Drakec9680921999-12-13 16:37:25 +00009890#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
Fred Draked86ed291999-12-15 15:34:33 +00009899#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009901#endif
Fred Drakec9680921999-12-13 16:37:25 +00009902#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
Fred Draked86ed291999-12-15 15:34:33 +00009905#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009907#endif
9908#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
Fred Drakec9680921999-12-13 16:37:25 +00009911#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
Fred Draked86ed291999-12-15 15:34:33 +00009923#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009925#endif
Fred Drakec9680921999-12-13 16:37:25 +00009926#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
Fred Draked86ed291999-12-15 15:34:33 +00009947#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009949#endif
Fred Drakec9680921999-12-13 16:37:25 +00009950#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
Fred Draked86ed291999-12-15 15:34:33 +00009956#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009958#endif
Fred Drakec9680921999-12-13 16:37:25 +00009959#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
Fred Draked86ed291999-12-15 15:34:33 +00009986#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009988#endif
9989#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009991#endif
Fred Drakec9680921999-12-13 16:37:25 +00009992#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
Fred Draked86ed291999-12-15 15:34:33 +000010097#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010099#endif
Fred Drakec9680921999-12-13 16:37:25 +000010100#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235};
10236
10237static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010238conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010239{
10240 return conv_confname(arg, valuep, posix_constants_sysconf,
10241 sizeof(posix_constants_sysconf)
10242 / sizeof(struct constdef));
10243}
10244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010245PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010246"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010247Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010248
10249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010250posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010251{
10252 PyObject *result = NULL;
10253 int name;
10254
10255 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010256 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010257
10258 errno = 0;
10259 value = sysconf(name);
10260 if (value == -1 && errno != 0)
10261 posix_error();
10262 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010263 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010264 }
10265 return result;
10266}
10267#endif
10268
10269
Fred Drakebec628d1999-12-15 18:31:10 +000010270/* This code is used to ensure that the tables of configuration value names
10271 * are in sorted order as required by conv_confname(), and also to build the
10272 * the exported dictionaries that are used to publish information about the
10273 * names available on the host platform.
10274 *
10275 * Sorting the table at runtime ensures that the table is properly ordered
10276 * when used, even for platforms we're not able to test on. It also makes
10277 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010278 */
Fred Drakebec628d1999-12-15 18:31:10 +000010279
10280static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010281cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010282{
10283 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010285 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010287
10288 return strcmp(c1->name, c2->name);
10289}
10290
10291static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010292setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010294{
Fred Drakebec628d1999-12-15 18:31:10 +000010295 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010296 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010297
10298 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10299 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010300 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010302
Barry Warsaw3155db32000-04-13 15:20:40 +000010303 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 PyObject *o = PyLong_FromLong(table[i].value);
10305 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10306 Py_XDECREF(o);
10307 Py_DECREF(d);
10308 return -1;
10309 }
10310 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010311 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010312 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010313}
10314
Fred Drakebec628d1999-12-15 18:31:10 +000010315/* Return -1 on failure, 0 on success. */
10316static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010317setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010318{
10319#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010320 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010321 sizeof(posix_constants_pathconf)
10322 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010323 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010324 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010325#endif
10326#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010327 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010328 sizeof(posix_constants_confstr)
10329 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010330 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010331 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010332#endif
10333#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010334 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010335 sizeof(posix_constants_sysconf)
10336 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010337 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010338 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010339#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010340 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010341}
Fred Draked86ed291999-12-15 15:34:33 +000010342
10343
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010344PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010345"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010346Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010347in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010348
10349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010350posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010351{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010352 abort();
10353 /*NOTREACHED*/
10354 Py_FatalError("abort() called from Python code didn't abort!");
10355 return NULL;
10356}
Fred Drakebec628d1999-12-15 18:31:10 +000010357
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010358#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010359PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010360"startfile(filepath [, operation]) - Start a file with its associated\n\
10361application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010362\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010363When \"operation\" is not specified or \"open\", this acts like\n\
10364double-clicking the file in Explorer, or giving the file name as an\n\
10365argument to the DOS \"start\" command: the file is opened with whatever\n\
10366application (if any) its extension is associated.\n\
10367When another \"operation\" is given, it specifies what should be done with\n\
10368the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010369\n\
10370startfile returns as soon as the associated application is launched.\n\
10371There is no option to wait for the application to close, and no way\n\
10372to retrieve the application's exit status.\n\
10373\n\
10374The filepath is relative to the current directory. If you want to use\n\
10375an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010376the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010377
10378static PyObject *
10379win32_startfile(PyObject *self, PyObject *args)
10380{
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 PyObject *ofilepath;
10382 char *filepath;
10383 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010384 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010386
Victor Stinnereb5657a2011-09-30 01:44:27 +020010387 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 if (!PyArg_ParseTuple(args, "U|s:startfile",
10389 &unipath, &operation)) {
10390 PyErr_Clear();
10391 goto normal;
10392 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010393
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010395 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010397 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 PyErr_Clear();
10399 operation = NULL;
10400 goto normal;
10401 }
10402 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010403
Victor Stinnereb5657a2011-09-30 01:44:27 +020010404 wpath = PyUnicode_AsUnicode(unipath);
10405 if (wpath == NULL)
10406 goto normal;
10407 if (uoperation) {
10408 woperation = PyUnicode_AsUnicode(uoperation);
10409 if (woperation == NULL)
10410 goto normal;
10411 }
10412 else
10413 woperation = NULL;
10414
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010416 rc = ShellExecuteW((HWND)0, woperation, wpath,
10417 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 Py_END_ALLOW_THREADS
10419
Victor Stinnereb5657a2011-09-30 01:44:27 +020010420 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010422 win32_error_object("startfile", unipath);
10423 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 }
10425 Py_INCREF(Py_None);
10426 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010427
10428normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10430 PyUnicode_FSConverter, &ofilepath,
10431 &operation))
10432 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010433 if (win32_warn_bytes_api()) {
10434 Py_DECREF(ofilepath);
10435 return NULL;
10436 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 filepath = PyBytes_AsString(ofilepath);
10438 Py_BEGIN_ALLOW_THREADS
10439 rc = ShellExecute((HWND)0, operation, filepath,
10440 NULL, NULL, SW_SHOWNORMAL);
10441 Py_END_ALLOW_THREADS
10442 if (rc <= (HINSTANCE)32) {
10443 PyObject *errval = win32_error("startfile", filepath);
10444 Py_DECREF(ofilepath);
10445 return errval;
10446 }
10447 Py_DECREF(ofilepath);
10448 Py_INCREF(Py_None);
10449 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010450}
10451#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010452
Martin v. Löwis438b5342002-12-27 10:16:42 +000010453#ifdef HAVE_GETLOADAVG
10454PyDoc_STRVAR(posix_getloadavg__doc__,
10455"getloadavg() -> (float, float, float)\n\n\
10456Return the number of processes in the system run queue averaged over\n\
10457the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10458was unobtainable");
10459
10460static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010461posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010462{
10463 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010464 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010465 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10466 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010467 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010468 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010469}
10470#endif
10471
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010472PyDoc_STRVAR(device_encoding__doc__,
10473"device_encoding(fd) -> str\n\n\
10474Return a string describing the encoding of the device\n\
10475if the output is a terminal; else return None.");
10476
10477static PyObject *
10478device_encoding(PyObject *self, PyObject *args)
10479{
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010481
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10483 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010484
10485 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010486}
10487
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010488#ifdef HAVE_SETRESUID
10489PyDoc_STRVAR(posix_setresuid__doc__,
10490"setresuid(ruid, euid, suid)\n\n\
10491Set the current process's real, effective, and saved user ids.");
10492
10493static PyObject*
10494posix_setresuid (PyObject *self, PyObject *args)
10495{
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010497 uid_t ruid, euid, suid;
10498 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10499 _Py_Uid_Converter, &ruid,
10500 _Py_Uid_Converter, &euid,
10501 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 return NULL;
10503 if (setresuid(ruid, euid, suid) < 0)
10504 return posix_error();
10505 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010506}
10507#endif
10508
10509#ifdef HAVE_SETRESGID
10510PyDoc_STRVAR(posix_setresgid__doc__,
10511"setresgid(rgid, egid, sgid)\n\n\
10512Set the current process's real, effective, and saved group ids.");
10513
10514static PyObject*
10515posix_setresgid (PyObject *self, PyObject *args)
10516{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010517 gid_t rgid, egid, sgid;
10518 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10519 _Py_Gid_Converter, &rgid,
10520 _Py_Gid_Converter, &egid,
10521 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 return NULL;
10523 if (setresgid(rgid, egid, sgid) < 0)
10524 return posix_error();
10525 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010526}
10527#endif
10528
10529#ifdef HAVE_GETRESUID
10530PyDoc_STRVAR(posix_getresuid__doc__,
10531"getresuid() -> (ruid, euid, suid)\n\n\
10532Get tuple of the current process's real, effective, and saved user ids.");
10533
10534static PyObject*
10535posix_getresuid (PyObject *self, PyObject *noargs)
10536{
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 if (getresuid(&ruid, &euid, &suid) < 0)
10539 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010540 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10541 _PyLong_FromUid(euid),
10542 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010543}
10544#endif
10545
10546#ifdef HAVE_GETRESGID
10547PyDoc_STRVAR(posix_getresgid__doc__,
10548"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010549Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010550
10551static PyObject*
10552posix_getresgid (PyObject *self, PyObject *noargs)
10553{
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 if (getresgid(&rgid, &egid, &sgid) < 0)
10556 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010557 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10558 _PyLong_FromGid(egid),
10559 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010560}
10561#endif
10562
Benjamin Peterson9428d532011-09-14 11:45:52 -040010563#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564
Benjamin Peterson799bd802011-08-31 22:15:17 -040010565PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010566"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10567Return the value of extended attribute attribute on path.\n\
10568\n\
10569path may be either a string or an open file descriptor.\n\
10570If follow_symlinks is False, and the last element of the path is a symbolic\n\
10571 link, getxattr will examine the symbolic link itself instead of the file\n\
10572 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010573
10574static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010575posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010576{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010577 path_t path;
10578 path_t attribute;
10579 int follow_symlinks = 1;
10580 PyObject *buffer = NULL;
10581 int i;
10582 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584 memset(&path, 0, sizeof(path));
10585 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010586 path.function_name = "getxattr";
10587 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010588 path.allow_fd = 1;
10589 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10590 path_converter, &path,
10591 path_converter, &attribute,
10592 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010593 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010594
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10596 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010597
Larry Hastings9cf065c2012-06-22 16:30:09 -070010598 for (i = 0; ; i++) {
10599 void *ptr;
10600 ssize_t result;
10601 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10602 Py_ssize_t buffer_size = buffer_sizes[i];
10603 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010604 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010605 goto exit;
10606 }
10607 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10608 if (!buffer)
10609 goto exit;
10610 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 Py_BEGIN_ALLOW_THREADS;
10613 if (path.fd >= 0)
10614 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10615 else if (follow_symlinks)
10616 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10617 else
10618 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10619 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 if (result < 0) {
10622 Py_DECREF(buffer);
10623 buffer = NULL;
10624 if (errno == ERANGE)
10625 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010626 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010627 goto exit;
10628 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010629
Larry Hastings9cf065c2012-06-22 16:30:09 -070010630 if (result != buffer_size) {
10631 /* Can only shrink. */
10632 _PyBytes_Resize(&buffer, result);
10633 }
10634 break;
10635 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010636
Larry Hastings9cf065c2012-06-22 16:30:09 -070010637exit:
10638 path_cleanup(&path);
10639 path_cleanup(&attribute);
10640 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010641}
10642
10643PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010644"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10645Set extended attribute attribute on path to value.\n\
10646path may be either a string or an open file descriptor.\n\
10647If follow_symlinks is False, and the last element of the path is a symbolic\n\
10648 link, setxattr will modify the symbolic link itself instead of the file\n\
10649 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
10651static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010652posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010653{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010654 path_t path;
10655 path_t attribute;
10656 Py_buffer value;
10657 int flags = 0;
10658 int follow_symlinks = 1;
10659 int result;
10660 PyObject *return_value = NULL;
10661 static char *keywords[] = {"path", "attribute", "value",
10662 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010663
Larry Hastings9cf065c2012-06-22 16:30:09 -070010664 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010665 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 path.allow_fd = 1;
10667 memset(&attribute, 0, sizeof(attribute));
10668 memset(&value, 0, sizeof(value));
10669 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10670 keywords,
10671 path_converter, &path,
10672 path_converter, &attribute,
10673 &value, &flags,
10674 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010676
10677 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10678 goto exit;
10679
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010681 if (path.fd > -1)
10682 result = fsetxattr(path.fd, attribute.narrow,
10683 value.buf, value.len, flags);
10684 else if (follow_symlinks)
10685 result = setxattr(path.narrow, attribute.narrow,
10686 value.buf, value.len, flags);
10687 else
10688 result = lsetxattr(path.narrow, attribute.narrow,
10689 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010690 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691
Larry Hastings9cf065c2012-06-22 16:30:09 -070010692 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010693 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010694 goto exit;
10695 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696
Larry Hastings9cf065c2012-06-22 16:30:09 -070010697 return_value = Py_None;
10698 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010699
Larry Hastings9cf065c2012-06-22 16:30:09 -070010700exit:
10701 path_cleanup(&path);
10702 path_cleanup(&attribute);
10703 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010706}
10707
10708PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010709"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10710Remove extended attribute attribute on path.\n\
10711path may be either a string or an open file descriptor.\n\
10712If follow_symlinks is False, and the last element of the path is a symbolic\n\
10713 link, removexattr will modify the symbolic link itself instead of the file\n\
10714 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010715
10716static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010718{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719 path_t path;
10720 path_t attribute;
10721 int follow_symlinks = 1;
10722 int result;
10723 PyObject *return_value = NULL;
10724 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010727 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010729 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010730 path.allow_fd = 1;
10731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10732 keywords,
10733 path_converter, &path,
10734 path_converter, &attribute,
10735 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010736 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010737
10738 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10739 goto exit;
10740
Benjamin Peterson799bd802011-08-31 22:15:17 -040010741 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 if (path.fd > -1)
10743 result = fremovexattr(path.fd, attribute.narrow);
10744 else if (follow_symlinks)
10745 result = removexattr(path.narrow, attribute.narrow);
10746 else
10747 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010748 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010749
Larry Hastings9cf065c2012-06-22 16:30:09 -070010750 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010751 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010753 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010754
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 return_value = Py_None;
10756 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010757
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758exit:
10759 path_cleanup(&path);
10760 path_cleanup(&attribute);
10761
10762 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010763}
10764
10765PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766"listxattr(path='.', *, follow_symlinks=True)\n\n\
10767Return a list of extended attributes on path.\n\
10768\n\
10769path may be either None, a string, or an open file descriptor.\n\
10770if path is None, listxattr will examine the current directory.\n\
10771If follow_symlinks is False, and the last element of the path is a symbolic\n\
10772 link, listxattr will examine the symbolic link itself instead of the file\n\
10773 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010774
10775static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 path_t path;
10779 int follow_symlinks = 1;
10780 Py_ssize_t i;
10781 PyObject *result = NULL;
10782 char *buffer = NULL;
10783 char *name;
10784 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010785
Larry Hastings9cf065c2012-06-22 16:30:09 -070010786 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010787 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 path.allow_fd = 1;
10789 path.fd = -1;
10790 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10791 path_converter, &path,
10792 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010793 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010794
Larry Hastings9cf065c2012-06-22 16:30:09 -070010795 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10796 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010797
Larry Hastings9cf065c2012-06-22 16:30:09 -070010798 name = path.narrow ? path.narrow : ".";
10799 for (i = 0; ; i++) {
10800 char *start, *trace, *end;
10801 ssize_t length;
10802 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10803 Py_ssize_t buffer_size = buffer_sizes[i];
10804 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010805 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010806 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 break;
10808 }
10809 buffer = PyMem_MALLOC(buffer_size);
10810 if (!buffer) {
10811 PyErr_NoMemory();
10812 break;
10813 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 Py_BEGIN_ALLOW_THREADS;
10816 if (path.fd > -1)
10817 length = flistxattr(path.fd, buffer, buffer_size);
10818 else if (follow_symlinks)
10819 length = listxattr(name, buffer, buffer_size);
10820 else
10821 length = llistxattr(name, buffer, buffer_size);
10822 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010825 if (errno == ERANGE) {
10826 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010827 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010829 }
Victor Stinner292c8352012-10-30 02:17:38 +010010830 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010831 break;
10832 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010833
Larry Hastings9cf065c2012-06-22 16:30:09 -070010834 result = PyList_New(0);
10835 if (!result) {
10836 goto exit;
10837 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 end = buffer + length;
10840 for (trace = start = buffer; trace != end; trace++) {
10841 if (!*trace) {
10842 int error;
10843 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10844 trace - start);
10845 if (!attribute) {
10846 Py_DECREF(result);
10847 result = NULL;
10848 goto exit;
10849 }
10850 error = PyList_Append(result, attribute);
10851 Py_DECREF(attribute);
10852 if (error) {
10853 Py_DECREF(result);
10854 result = NULL;
10855 goto exit;
10856 }
10857 start = trace + 1;
10858 }
10859 }
10860 break;
10861 }
10862exit:
10863 path_cleanup(&path);
10864 if (buffer)
10865 PyMem_FREE(buffer);
10866 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010867}
10868
Benjamin Peterson9428d532011-09-14 11:45:52 -040010869#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010870
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010871
Georg Brandl2fb477c2012-02-21 00:33:36 +010010872PyDoc_STRVAR(posix_urandom__doc__,
10873"urandom(n) -> str\n\n\
10874Return n random bytes suitable for cryptographic use.");
10875
10876static PyObject *
10877posix_urandom(PyObject *self, PyObject *args)
10878{
10879 Py_ssize_t size;
10880 PyObject *result;
10881 int ret;
10882
10883 /* Read arguments */
10884 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10885 return NULL;
10886 if (size < 0)
10887 return PyErr_Format(PyExc_ValueError,
10888 "negative argument not allowed");
10889 result = PyBytes_FromStringAndSize(NULL, size);
10890 if (result == NULL)
10891 return NULL;
10892
10893 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10894 PyBytes_GET_SIZE(result));
10895 if (ret == -1) {
10896 Py_DECREF(result);
10897 return NULL;
10898 }
10899 return result;
10900}
10901
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010902/* Terminal size querying */
10903
10904static PyTypeObject TerminalSizeType;
10905
10906PyDoc_STRVAR(TerminalSize_docstring,
10907 "A tuple of (columns, lines) for holding terminal window size");
10908
10909static PyStructSequence_Field TerminalSize_fields[] = {
10910 {"columns", "width of the terminal window in characters"},
10911 {"lines", "height of the terminal window in characters"},
10912 {NULL, NULL}
10913};
10914
10915static PyStructSequence_Desc TerminalSize_desc = {
10916 "os.terminal_size",
10917 TerminalSize_docstring,
10918 TerminalSize_fields,
10919 2,
10920};
10921
10922#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10923PyDoc_STRVAR(termsize__doc__,
10924 "Return the size of the terminal window as (columns, lines).\n" \
10925 "\n" \
10926 "The optional argument fd (default standard output) specifies\n" \
10927 "which file descriptor should be queried.\n" \
10928 "\n" \
10929 "If the file descriptor is not connected to a terminal, an OSError\n" \
10930 "is thrown.\n" \
10931 "\n" \
10932 "This function will only be defined if an implementation is\n" \
10933 "available for this system.\n" \
10934 "\n" \
10935 "shutil.get_terminal_size is the high-level function which should \n" \
10936 "normally be used, os.get_terminal_size is the low-level implementation.");
10937
10938static PyObject*
10939get_terminal_size(PyObject *self, PyObject *args)
10940{
10941 int columns, lines;
10942 PyObject *termsize;
10943
10944 int fd = fileno(stdout);
10945 /* Under some conditions stdout may not be connected and
10946 * fileno(stdout) may point to an invalid file descriptor. For example
10947 * GUI apps don't have valid standard streams by default.
10948 *
10949 * If this happens, and the optional fd argument is not present,
10950 * the ioctl below will fail returning EBADF. This is what we want.
10951 */
10952
10953 if (!PyArg_ParseTuple(args, "|i", &fd))
10954 return NULL;
10955
10956#ifdef TERMSIZE_USE_IOCTL
10957 {
10958 struct winsize w;
10959 if (ioctl(fd, TIOCGWINSZ, &w))
10960 return PyErr_SetFromErrno(PyExc_OSError);
10961 columns = w.ws_col;
10962 lines = w.ws_row;
10963 }
10964#endif /* TERMSIZE_USE_IOCTL */
10965
10966#ifdef TERMSIZE_USE_CONIO
10967 {
10968 DWORD nhandle;
10969 HANDLE handle;
10970 CONSOLE_SCREEN_BUFFER_INFO csbi;
10971 switch (fd) {
10972 case 0: nhandle = STD_INPUT_HANDLE;
10973 break;
10974 case 1: nhandle = STD_OUTPUT_HANDLE;
10975 break;
10976 case 2: nhandle = STD_ERROR_HANDLE;
10977 break;
10978 default:
10979 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10980 }
10981 handle = GetStdHandle(nhandle);
10982 if (handle == NULL)
10983 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10984 if (handle == INVALID_HANDLE_VALUE)
10985 return PyErr_SetFromWindowsErr(0);
10986
10987 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10988 return PyErr_SetFromWindowsErr(0);
10989
10990 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10991 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10992 }
10993#endif /* TERMSIZE_USE_CONIO */
10994
10995 termsize = PyStructSequence_New(&TerminalSizeType);
10996 if (termsize == NULL)
10997 return NULL;
10998 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10999 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11000 if (PyErr_Occurred()) {
11001 Py_DECREF(termsize);
11002 return NULL;
11003 }
11004 return termsize;
11005}
11006#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11007
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011008PyDoc_STRVAR(posix_cpu_count__doc__,
11009"cpu_count() -> integer\n\n\
11010Return the number of CPUs in the system, or None if this value cannot be\n\
11011established.");
11012
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011013static PyObject *
11014posix_cpu_count(PyObject *self)
11015{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011016 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011017#ifdef MS_WINDOWS
11018 SYSTEM_INFO sysinfo;
11019 GetSystemInfo(&sysinfo);
11020 ncpu = sysinfo.dwNumberOfProcessors;
11021#elif defined(__hpux)
11022 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11023#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11024 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011025#elif defined(__DragonFly__) || \
11026 defined(__OpenBSD__) || \
11027 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011028 defined(__NetBSD__) || \
11029 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011030 int mib[2];
11031 size_t len = sizeof(ncpu);
11032 mib[0] = CTL_HW;
11033 mib[1] = HW_NCPU;
11034 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11035 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011036#endif
11037 if (ncpu >= 1)
11038 return PyLong_FromLong(ncpu);
11039 else
11040 Py_RETURN_NONE;
11041}
11042
Victor Stinnerdaf45552013-08-28 00:53:59 +020011043PyDoc_STRVAR(get_inheritable__doc__,
11044 "get_inheritable(fd) -> bool\n" \
11045 "\n" \
11046 "Get the close-on-exe flag of the specified file descriptor.");
11047
11048static PyObject*
11049posix_get_inheritable(PyObject *self, PyObject *args)
11050{
11051 int fd;
11052 int inheritable;
11053
11054 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11055 return NULL;
11056
11057 if (!_PyVerify_fd(fd))
11058 return posix_error();
11059
11060 inheritable = _Py_get_inheritable(fd);
11061 if (inheritable < 0)
11062 return NULL;
11063 return PyBool_FromLong(inheritable);
11064}
11065
11066PyDoc_STRVAR(set_inheritable__doc__,
11067 "set_inheritable(fd, inheritable)\n" \
11068 "\n" \
11069 "Set the inheritable flag of the specified file descriptor.");
11070
11071static PyObject*
11072posix_set_inheritable(PyObject *self, PyObject *args)
11073{
11074 int fd, inheritable;
11075
11076 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11077 return NULL;
11078
11079 if (!_PyVerify_fd(fd))
11080 return posix_error();
11081
11082 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11083 return NULL;
11084 Py_RETURN_NONE;
11085}
11086
11087
11088#ifdef MS_WINDOWS
11089PyDoc_STRVAR(get_handle_inheritable__doc__,
11090 "get_handle_inheritable(fd) -> bool\n" \
11091 "\n" \
11092 "Get the close-on-exe flag of the specified file descriptor.");
11093
11094static PyObject*
11095posix_get_handle_inheritable(PyObject *self, PyObject *args)
11096{
11097 Py_intptr_t handle;
11098 DWORD flags;
11099
11100 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11101 return NULL;
11102
11103 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11104 PyErr_SetFromWindowsErr(0);
11105 return NULL;
11106 }
11107
11108 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11109}
11110
11111PyDoc_STRVAR(set_handle_inheritable__doc__,
11112 "set_handle_inheritable(fd, inheritable)\n" \
11113 "\n" \
11114 "Set the inheritable flag of the specified handle.");
11115
11116static PyObject*
11117posix_set_handle_inheritable(PyObject *self, PyObject *args)
11118{
11119 int inheritable = 1;
11120 Py_intptr_t handle;
11121 DWORD flags;
11122
11123 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11124 &handle, &inheritable))
11125 return NULL;
11126
11127 if (inheritable)
11128 flags = HANDLE_FLAG_INHERIT;
11129 else
11130 flags = 0;
11131 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11132 PyErr_SetFromWindowsErr(0);
11133 return NULL;
11134 }
11135 Py_RETURN_NONE;
11136}
11137#endif /* MS_WINDOWS */
11138
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011139
Larry Hastings31826802013-10-19 00:09:25 -070011140
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011141static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011142
11143 OS_STAT_METHODDEF
11144 OS_ACCESS_METHODDEF
11145 OS_TTYNAME_METHODDEF
11146
Larry Hastings9cf065c2012-06-22 16:30:09 -070011147 {"chdir", (PyCFunction)posix_chdir,
11148 METH_VARARGS | METH_KEYWORDS,
11149 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011150#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011151 {"chflags", (PyCFunction)posix_chflags,
11152 METH_VARARGS | METH_KEYWORDS,
11153 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011154#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011155 {"chmod", (PyCFunction)posix_chmod,
11156 METH_VARARGS | METH_KEYWORDS,
11157 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011158#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011160#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011161#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011162 {"chown", (PyCFunction)posix_chown,
11163 METH_VARARGS | METH_KEYWORDS,
11164 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011165#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011166#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011168#endif /* HAVE_LCHMOD */
11169#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011171#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011172#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011174#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011175#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011177#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011178#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011180#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011181#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011183#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11185 METH_NOARGS, posix_getcwd__doc__},
11186 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11187 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11189 {"link", (PyCFunction)posix_link,
11190 METH_VARARGS | METH_KEYWORDS,
11191 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011192#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011193 {"listdir", (PyCFunction)posix_listdir,
11194 METH_VARARGS | METH_KEYWORDS,
11195 posix_listdir__doc__},
11196 {"lstat", (PyCFunction)posix_lstat,
11197 METH_VARARGS | METH_KEYWORDS,
11198 posix_lstat__doc__},
11199 {"mkdir", (PyCFunction)posix_mkdir,
11200 METH_VARARGS | METH_KEYWORDS,
11201 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011202#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011204#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011205#ifdef HAVE_GETPRIORITY
11206 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11207#endif /* HAVE_GETPRIORITY */
11208#ifdef HAVE_SETPRIORITY
11209 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11210#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011211#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 {"readlink", (PyCFunction)posix_readlink,
11213 METH_VARARGS | METH_KEYWORDS,
11214 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011215#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011216#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011217 {"readlink", (PyCFunction)win_readlink,
11218 METH_VARARGS | METH_KEYWORDS,
11219 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011220#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011221 {"rename", (PyCFunction)posix_rename,
11222 METH_VARARGS | METH_KEYWORDS,
11223 posix_rename__doc__},
11224 {"replace", (PyCFunction)posix_replace,
11225 METH_VARARGS | METH_KEYWORDS,
11226 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011227 {"rmdir", (PyCFunction)posix_rmdir,
11228 METH_VARARGS | METH_KEYWORDS,
11229 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011231#if defined(HAVE_SYMLINK)
11232 {"symlink", (PyCFunction)posix_symlink,
11233 METH_VARARGS | METH_KEYWORDS,
11234 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011235#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011236#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011240#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011242#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011243 {"unlink", (PyCFunction)posix_unlink,
11244 METH_VARARGS | METH_KEYWORDS,
11245 posix_unlink__doc__},
11246 {"remove", (PyCFunction)posix_unlink,
11247 METH_VARARGS | METH_KEYWORDS,
11248 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011249 {"utime", (PyCFunction)posix_utime,
11250 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011251#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011253#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011255#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011257 {"execve", (PyCFunction)posix_execve,
11258 METH_VARARGS | METH_KEYWORDS,
11259 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011260#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011261#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11263 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011264#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011265#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011267#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011268#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011270#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011271#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011272#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011273 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11274 {"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 +020011275#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011276#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011277 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011278#endif
11279#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011280 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011281#endif
11282#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011283 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011284#endif
11285#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011286 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011287#endif
11288#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011289 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011290#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011291 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011292#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011293 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11294 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11295#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011296#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011297#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011299#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011300#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011302#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011303#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011305#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011306#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011308#endif /* HAVE_GETEUID */
11309#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011311#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011312#ifdef HAVE_GETGROUPLIST
11313 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11314#endif
Fred Drakec9680921999-12-13 16:37:25 +000011315#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011319#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011321#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011322#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011324#endif /* HAVE_GETPPID */
11325#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011327#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011328#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011330#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011331#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011333#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011334#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011336#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011337#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011339#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011340#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11342 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011343#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011344#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011346#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011347#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011349#endif /* HAVE_SETEUID */
11350#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011352#endif /* HAVE_SETEGID */
11353#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011355#endif /* HAVE_SETREUID */
11356#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011358#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011359#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011361#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011362#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011364#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011365#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011367#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011368#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011370#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011371#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011373#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011374#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011376#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011377#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011378 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011379#endif /* HAVE_WAIT3 */
11380#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011381 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011382#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011383#if defined(HAVE_WAITID) && !defined(__APPLE__)
11384 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11385#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011386#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011388#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011389#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011391#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011392#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011394#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011395#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011397#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011398#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011400#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011401#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011403#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011404 {"open", (PyCFunction)posix_open,\
11405 METH_VARARGS | METH_KEYWORDS,
11406 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11408 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11409 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11410 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011411 {"dup2", (PyCFunction)posix_dup2,
11412 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011413#ifdef HAVE_LOCKF
11414 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11415#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11417 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011418#ifdef HAVE_READV
11419 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11420#endif
11421#ifdef HAVE_PREAD
11422 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11423#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011425#ifdef HAVE_WRITEV
11426 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11427#endif
11428#ifdef HAVE_PWRITE
11429 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11430#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011431#ifdef HAVE_SENDFILE
11432 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11433 posix_sendfile__doc__},
11434#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011435 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011437#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011439#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011440#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011441 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011442#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011443#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 {"mkfifo", (PyCFunction)posix_mkfifo,
11445 METH_VARARGS | METH_KEYWORDS,
11446 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011447#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011448#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011449 {"mknod", (PyCFunction)posix_mknod,
11450 METH_VARARGS | METH_KEYWORDS,
11451 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011452#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011453#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11455 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11456 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011457#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011458#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011460#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011461#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011462 {"truncate", (PyCFunction)posix_truncate,
11463 METH_VARARGS | METH_KEYWORDS,
11464 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011465#endif
11466#ifdef HAVE_POSIX_FALLOCATE
11467 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11468#endif
11469#ifdef HAVE_POSIX_FADVISE
11470 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11471#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011472#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011474#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011475#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011477#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011479#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011481#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011482#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011484#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011485#ifdef HAVE_SYNC
11486 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11487#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011488#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011490#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011491#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011492#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011494#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011495#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011497#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011498#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011500#endif /* WIFSTOPPED */
11501#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011503#endif /* WIFSIGNALED */
11504#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011506#endif /* WIFEXITED */
11507#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011509#endif /* WEXITSTATUS */
11510#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011512#endif /* WTERMSIG */
11513#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011515#endif /* WSTOPSIG */
11516#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011517#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011518 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011519#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011520#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011521 {"statvfs", (PyCFunction)posix_statvfs,
11522 METH_VARARGS | METH_KEYWORDS,
11523 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011524#endif
Fred Drakec9680921999-12-13 16:37:25 +000011525#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011527#endif
11528#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011530#endif
11531#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011533#endif
11534#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011535 {"pathconf", (PyCFunction)posix_pathconf,
11536 METH_VARARGS | METH_KEYWORDS,
11537 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011540#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011542 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011543 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011544 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011545 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011546#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011547#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011549#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011550 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011551#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011553#endif
11554#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011556#endif
11557#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011559#endif
11560#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011562#endif
11563
Benjamin Peterson9428d532011-09-14 11:45:52 -040011564#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011565 {"setxattr", (PyCFunction)posix_setxattr,
11566 METH_VARARGS | METH_KEYWORDS,
11567 posix_setxattr__doc__},
11568 {"getxattr", (PyCFunction)posix_getxattr,
11569 METH_VARARGS | METH_KEYWORDS,
11570 posix_getxattr__doc__},
11571 {"removexattr", (PyCFunction)posix_removexattr,
11572 METH_VARARGS | METH_KEYWORDS,
11573 posix_removexattr__doc__},
11574 {"listxattr", (PyCFunction)posix_listxattr,
11575 METH_VARARGS | METH_KEYWORDS,
11576 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011577#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011578#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11579 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11580#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011581 {"cpu_count", (PyCFunction)posix_cpu_count,
11582 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011583 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11584 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11585#ifdef MS_WINDOWS
11586 {"get_handle_inheritable", posix_get_handle_inheritable,
11587 METH_VARARGS, get_handle_inheritable__doc__},
11588 {"set_handle_inheritable", posix_set_handle_inheritable,
11589 METH_VARARGS, set_handle_inheritable__doc__},
11590#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011592};
11593
11594
Brian Curtin52173d42010-12-02 18:29:18 +000011595#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011596static int
Brian Curtin52173d42010-12-02 18:29:18 +000011597enable_symlink()
11598{
11599 HANDLE tok;
11600 TOKEN_PRIVILEGES tok_priv;
11601 LUID luid;
11602 int meth_idx = 0;
11603
11604 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011605 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011606
11607 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011608 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011609
11610 tok_priv.PrivilegeCount = 1;
11611 tok_priv.Privileges[0].Luid = luid;
11612 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11613
11614 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11615 sizeof(TOKEN_PRIVILEGES),
11616 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011617 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011618
Brian Curtin3b4499c2010-12-28 14:31:47 +000011619 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11620 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011621}
11622#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11623
Barry Warsaw4a342091996-12-19 23:50:02 +000011624static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011625all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011626{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011627#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011628 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011629#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011630#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011631 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011632#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011633#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011634 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011635#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011636#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011637 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011638#endif
Fred Drakec9680921999-12-13 16:37:25 +000011639#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011640 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011642#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011643 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011644#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011645#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011646 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011647#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011648#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011649 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011650#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011651#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011652 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011653#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011654#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011655 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011656#endif
11657#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011658 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011659#endif
11660#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011661 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011662#endif
11663#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011664 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011665#endif
11666#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011667 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011668#endif
11669#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011670 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011671#endif
11672#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011673 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011674#endif
11675#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011676 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011677#endif
11678#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011679 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011680#endif
11681#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011682 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011683#endif
11684#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011685 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011686#endif
11687#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011688 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011689#endif
11690#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011691 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011692#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011693#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011694 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011695#endif
11696#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011697 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011698#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011699#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011701#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011702#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011704#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011705#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011707#endif
11708#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011709 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011710#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011711#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011712 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011713#endif
11714#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011715 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011716#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011717#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011718 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011719#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011720#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011722#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011723#ifdef O_TMPFILE
11724 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11725#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011726#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011727 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011728#endif
11729#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011730 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011731#endif
11732#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011733 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011734#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011735#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011736 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011737#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011738#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011739 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011740#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011741
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011742
Jesus Cea94363612012-06-22 18:32:07 +020011743#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011744 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011745#endif
11746#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011747 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011748#endif
11749
Tim Peters5aa91602002-01-30 05:46:57 +000011750/* MS Windows */
11751#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011752 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011753 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011754#endif
11755#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011756 /* Optimize for short life (keep in memory). */
11757 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011758 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011759#endif
11760#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011761 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011762 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011763#endif
11764#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011767#endif
11768#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011769 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011770 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011771#endif
11772
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011773/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011774#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011775 /* Send a SIGIO signal whenever input or output
11776 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011777 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011778#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011779#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011780 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011781 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011782#endif
11783#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011784 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011785 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011786#endif
11787#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011788 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011789 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011790#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011791#ifdef O_NOLINKS
11792 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011793 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011794#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011795#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011796 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011797 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011798#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011799
Victor Stinner8c62be82010-05-06 00:08:46 +000011800 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011801#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011802 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011803#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011804#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011805 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011806#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011807#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011809#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011810#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011811 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011812#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011813#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011814 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011815#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011816#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011817 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011818#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011819#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011820 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011821#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011822#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011823 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011824#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011825#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011826 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011827#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011828#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011829 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011830#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011831#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011832 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011833#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011834#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011835 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011836#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011837#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011838 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011839#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011840#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011841 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011842#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011843#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011844 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011845#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011846#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011847 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011848#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011849#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011850 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011851#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011852
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011853 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011854#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011855 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011856#endif /* ST_RDONLY */
11857#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011858 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011859#endif /* ST_NOSUID */
11860
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011861 /* FreeBSD sendfile() constants */
11862#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011863 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011864#endif
11865#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011866 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011867#endif
11868#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011869 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011870#endif
11871
Ross Lagerwall7807c352011-03-17 20:20:30 +020011872 /* constants for posix_fadvise */
11873#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011874 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011875#endif
11876#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011877 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011878#endif
11879#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011880 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011881#endif
11882#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011883 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011884#endif
11885#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011886 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011887#endif
11888#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011889 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011890#endif
11891
11892 /* constants for waitid */
11893#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011894 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11895 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11896 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011897#endif
11898#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011899 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011900#endif
11901#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011902 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011903#endif
11904#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011905 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011906#endif
11907#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011908 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011909#endif
11910#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011911 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011912#endif
11913#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011914 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011915#endif
11916#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011917 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011918#endif
11919
11920 /* constants for lockf */
11921#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011923#endif
11924#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011925 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011926#endif
11927#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011928 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011929#endif
11930#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011931 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011932#endif
11933
Guido van Rossum246bc171999-02-01 23:54:31 +000011934#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011935 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11936 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11937 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11938 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11939 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011940#endif
11941
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011942#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011943 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11944 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11945 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011946#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011947 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011948#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011949#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011950 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011951#endif
11952#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011953 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011954#endif
11955#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011956 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011957#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011958#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011959 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011960#endif
11961#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011962 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011963#endif
11964#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011965 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011966#endif
11967#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011968 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011969#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011970#endif
11971
Benjamin Peterson9428d532011-09-14 11:45:52 -040011972#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11974 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11975 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011976#endif
11977
Victor Stinner8b905bd2011-10-25 13:34:04 +020011978#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011979 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011980#endif
11981#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011982 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011983#endif
11984#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011985 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011986#endif
11987#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011988 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011989#endif
11990#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011991 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011992#endif
11993#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011994 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011995#endif
11996#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011997 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011998#endif
11999
Victor Stinner8c62be82010-05-06 00:08:46 +000012000 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012001}
12002
12003
Tim Peters5aa91602002-01-30 05:46:57 +000012004#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012005#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012006#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012007
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012008#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012009#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012010#define MODNAME "posix"
12011#endif
12012
Martin v. Löwis1a214512008-06-11 05:26:20 +000012013static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012014 PyModuleDef_HEAD_INIT,
12015 MODNAME,
12016 posix__doc__,
12017 -1,
12018 posix_methods,
12019 NULL,
12020 NULL,
12021 NULL,
12022 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012023};
12024
12025
Larry Hastings9cf065c2012-06-22 16:30:09 -070012026static char *have_functions[] = {
12027
12028#ifdef HAVE_FACCESSAT
12029 "HAVE_FACCESSAT",
12030#endif
12031
12032#ifdef HAVE_FCHDIR
12033 "HAVE_FCHDIR",
12034#endif
12035
12036#ifdef HAVE_FCHMOD
12037 "HAVE_FCHMOD",
12038#endif
12039
12040#ifdef HAVE_FCHMODAT
12041 "HAVE_FCHMODAT",
12042#endif
12043
12044#ifdef HAVE_FCHOWN
12045 "HAVE_FCHOWN",
12046#endif
12047
Larry Hastings00964ed2013-08-12 13:49:30 -040012048#ifdef HAVE_FCHOWNAT
12049 "HAVE_FCHOWNAT",
12050#endif
12051
Larry Hastings9cf065c2012-06-22 16:30:09 -070012052#ifdef HAVE_FEXECVE
12053 "HAVE_FEXECVE",
12054#endif
12055
12056#ifdef HAVE_FDOPENDIR
12057 "HAVE_FDOPENDIR",
12058#endif
12059
Georg Brandl306336b2012-06-24 12:55:33 +020012060#ifdef HAVE_FPATHCONF
12061 "HAVE_FPATHCONF",
12062#endif
12063
Larry Hastings9cf065c2012-06-22 16:30:09 -070012064#ifdef HAVE_FSTATAT
12065 "HAVE_FSTATAT",
12066#endif
12067
12068#ifdef HAVE_FSTATVFS
12069 "HAVE_FSTATVFS",
12070#endif
12071
Georg Brandl306336b2012-06-24 12:55:33 +020012072#ifdef HAVE_FTRUNCATE
12073 "HAVE_FTRUNCATE",
12074#endif
12075
Larry Hastings9cf065c2012-06-22 16:30:09 -070012076#ifdef HAVE_FUTIMENS
12077 "HAVE_FUTIMENS",
12078#endif
12079
12080#ifdef HAVE_FUTIMES
12081 "HAVE_FUTIMES",
12082#endif
12083
12084#ifdef HAVE_FUTIMESAT
12085 "HAVE_FUTIMESAT",
12086#endif
12087
12088#ifdef HAVE_LINKAT
12089 "HAVE_LINKAT",
12090#endif
12091
12092#ifdef HAVE_LCHFLAGS
12093 "HAVE_LCHFLAGS",
12094#endif
12095
12096#ifdef HAVE_LCHMOD
12097 "HAVE_LCHMOD",
12098#endif
12099
12100#ifdef HAVE_LCHOWN
12101 "HAVE_LCHOWN",
12102#endif
12103
12104#ifdef HAVE_LSTAT
12105 "HAVE_LSTAT",
12106#endif
12107
12108#ifdef HAVE_LUTIMES
12109 "HAVE_LUTIMES",
12110#endif
12111
12112#ifdef HAVE_MKDIRAT
12113 "HAVE_MKDIRAT",
12114#endif
12115
12116#ifdef HAVE_MKFIFOAT
12117 "HAVE_MKFIFOAT",
12118#endif
12119
12120#ifdef HAVE_MKNODAT
12121 "HAVE_MKNODAT",
12122#endif
12123
12124#ifdef HAVE_OPENAT
12125 "HAVE_OPENAT",
12126#endif
12127
12128#ifdef HAVE_READLINKAT
12129 "HAVE_READLINKAT",
12130#endif
12131
12132#ifdef HAVE_RENAMEAT
12133 "HAVE_RENAMEAT",
12134#endif
12135
12136#ifdef HAVE_SYMLINKAT
12137 "HAVE_SYMLINKAT",
12138#endif
12139
12140#ifdef HAVE_UNLINKAT
12141 "HAVE_UNLINKAT",
12142#endif
12143
12144#ifdef HAVE_UTIMENSAT
12145 "HAVE_UTIMENSAT",
12146#endif
12147
12148#ifdef MS_WINDOWS
12149 "MS_WINDOWS",
12150#endif
12151
12152 NULL
12153};
12154
12155
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012156PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012157INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012158{
Victor Stinner8c62be82010-05-06 00:08:46 +000012159 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012160 PyObject *list;
12161 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012162
Brian Curtin52173d42010-12-02 18:29:18 +000012163#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012164 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012165#endif
12166
Victor Stinner8c62be82010-05-06 00:08:46 +000012167 m = PyModule_Create(&posixmodule);
12168 if (m == NULL)
12169 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012170
Victor Stinner8c62be82010-05-06 00:08:46 +000012171 /* Initialize environ dictionary */
12172 v = convertenviron();
12173 Py_XINCREF(v);
12174 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12175 return NULL;
12176 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012177
Victor Stinner8c62be82010-05-06 00:08:46 +000012178 if (all_ins(m))
12179 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012180
Victor Stinner8c62be82010-05-06 00:08:46 +000012181 if (setup_confname_tables(m))
12182 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012183
Victor Stinner8c62be82010-05-06 00:08:46 +000012184 Py_INCREF(PyExc_OSError);
12185 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012186
Guido van Rossumb3d39562000-01-31 18:41:26 +000012187#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 if (posix_putenv_garbage == NULL)
12189 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012190#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012191
Victor Stinner8c62be82010-05-06 00:08:46 +000012192 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012193#if defined(HAVE_WAITID) && !defined(__APPLE__)
12194 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012195 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12196 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012197#endif
12198
Christian Heimes25827622013-10-12 01:27:08 +020012199 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012200 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12201 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12202 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012203 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12204 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012205 structseq_new = StatResultType.tp_new;
12206 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012207
Christian Heimes25827622013-10-12 01:27:08 +020012208 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012209 if (PyStructSequence_InitType2(&StatVFSResultType,
12210 &statvfs_result_desc) < 0)
12211 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012212#ifdef NEED_TICKS_PER_SECOND
12213# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012214 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012215# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012216 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012217# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012219# endif
12220#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012221
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012222#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012223 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012224 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12225 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012226 SchedParamType.tp_new = sched_param_new;
12227#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012228
12229 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012230 if (PyStructSequence_InitType2(&TerminalSizeType,
12231 &TerminalSize_desc) < 0)
12232 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012233 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012234#if defined(HAVE_WAITID) && !defined(__APPLE__)
12235 Py_INCREF((PyObject*) &WaitidResultType);
12236 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12237#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012238 Py_INCREF((PyObject*) &StatResultType);
12239 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12240 Py_INCREF((PyObject*) &StatVFSResultType);
12241 PyModule_AddObject(m, "statvfs_result",
12242 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012243
12244#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012245 Py_INCREF(&SchedParamType);
12246 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012247#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012248
Larry Hastings605a62d2012-06-24 04:33:36 -070012249 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012250 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12251 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012252 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12253
12254 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012255 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12256 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012257 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12258
Thomas Wouters477c8d52006-05-27 19:21:47 +000012259#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 /*
12261 * Step 2 of weak-linking support on Mac OS X.
12262 *
12263 * The code below removes functions that are not available on the
12264 * currently active platform.
12265 *
12266 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012267 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012268 * OSX 10.4.
12269 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012270#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012271 if (fstatvfs == NULL) {
12272 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12273 return NULL;
12274 }
12275 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012276#endif /* HAVE_FSTATVFS */
12277
12278#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012279 if (statvfs == NULL) {
12280 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12281 return NULL;
12282 }
12283 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012284#endif /* HAVE_STATVFS */
12285
12286# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012287 if (lchown == NULL) {
12288 if (PyObject_DelAttrString(m, "lchown") == -1) {
12289 return NULL;
12290 }
12291 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012292#endif /* HAVE_LCHOWN */
12293
12294
12295#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012296
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012297 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012298 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12299
Larry Hastings6fe20b32012-04-19 15:07:49 -070012300 billion = PyLong_FromLong(1000000000);
12301 if (!billion)
12302 return NULL;
12303
Larry Hastings9cf065c2012-06-22 16:30:09 -070012304 /* suppress "function not used" warnings */
12305 {
12306 int ignored;
12307 fd_specified("", -1);
12308 follow_symlinks_specified("", 1);
12309 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12310 dir_fd_converter(Py_None, &ignored);
12311 dir_fd_unavailable(Py_None, &ignored);
12312 }
12313
12314 /*
12315 * provide list of locally available functions
12316 * so os.py can populate support_* lists
12317 */
12318 list = PyList_New(0);
12319 if (!list)
12320 return NULL;
12321 for (trace = have_functions; *trace; trace++) {
12322 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12323 if (!unicode)
12324 return NULL;
12325 if (PyList_Append(list, unicode))
12326 return NULL;
12327 Py_DECREF(unicode);
12328 }
12329 PyModule_AddObject(m, "_have_functions", list);
12330
12331 initialized = 1;
12332
Victor Stinner8c62be82010-05-06 00:08:46 +000012333 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012334}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012335
12336#ifdef __cplusplus
12337}
12338#endif