blob: f282f998332a3442d372875b8387d753807746c5 [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
193
194
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000196
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000197#if defined(__sgi)&&_COMPILER_VERSION>=700
198/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
199 (default) */
200extern char *ctermid_r(char *);
201#endif
202
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000203#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000207#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000212#endif
213#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int chdir(char *);
215extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chdir(const char *);
218extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000220#ifdef __BORLANDC__
221extern int chmod(const char *, int);
222#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000223extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000224#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000225/*#ifdef HAVE_FCHMOD
226extern int fchmod(int, mode_t);
227#endif*/
228/*#ifdef HAVE_LCHMOD
229extern int lchmod(const char *, mode_t);
230#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chown(const char *, uid_t, gid_t);
232extern char *getcwd(char *, int);
233extern char *strerror(int);
234extern int link(const char *, const char *);
235extern int rename(const char *, const char *);
236extern int stat(const char *, struct stat *);
237extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000239extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000240#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000243#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000245
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_UTIME_H
249#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000252#ifdef HAVE_SYS_UTIME_H
253#include <sys/utime.h>
254#define HAVE_UTIME_H /* pretend we do for the rest of this file */
255#endif /* HAVE_SYS_UTIME_H */
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_SYS_TIMES_H
258#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_PARAM_H
262#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_UTSNAME_H
266#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#include <direct.h>
275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
295#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
304#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000311#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000312#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000313#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000314#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000315#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
316#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000317static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000318#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000319#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000322#if defined(PATH_MAX) && PATH_MAX > 1024
323#define MAXPATHLEN PATH_MAX
324#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#endif /* MAXPATHLEN */
328
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000329#ifdef UNION_WAIT
330/* Emulate some macros on systems that have a union instead of macros */
331
332#ifndef WIFEXITED
333#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
334#endif
335
336#ifndef WEXITSTATUS
337#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
338#endif
339
340#ifndef WTERMSIG
341#define WTERMSIG(u_wait) ((u_wait).w_termsig)
342#endif
343
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000344#define WAIT_TYPE union wait
345#define WAIT_STATUS_INT(s) (s.w_status)
346
347#else /* !UNION_WAIT */
348#define WAIT_TYPE int
349#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000350#endif /* UNION_WAIT */
351
Greg Wardb48bc172000-03-01 21:51:56 +0000352/* Don't use the "_r" form if we don't need it (also, won't have a
353 prototype for it, at least on Solaris -- maybe others as well?). */
354#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
355#define USE_CTERMID_R
356#endif
357
Fred Drake699f3522000-06-29 21:12:41 +0000358/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000359#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000360#undef FSTAT
361#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200362#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000363# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700364# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define FSTAT win32_fstat
366# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000367#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700369# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000370# define FSTAT fstat
371# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000372#endif
373
Tim Peters11b23062003-04-23 02:39:17 +0000374#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000375#include <sys/mkdev.h>
376#else
377#if defined(MAJOR_IN_SYSMACROS)
378#include <sys/sysmacros.h>
379#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000380#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
381#include <sys/mkdev.h>
382#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#endif
Fred Drake699f3522000-06-29 21:12:41 +0000384
Larry Hastings9cf065c2012-06-22 16:30:09 -0700385
386#ifdef MS_WINDOWS
387static int
388win32_warn_bytes_api()
389{
390 return PyErr_WarnEx(PyExc_DeprecationWarning,
391 "The Windows bytes API has been deprecated, "
392 "use Unicode filenames instead",
393 1);
394}
395#endif
396
397
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200398#ifndef MS_WINDOWS
399PyObject *
400_PyLong_FromUid(uid_t uid)
401{
402 if (uid == (uid_t)-1)
403 return PyLong_FromLong(-1);
404 return PyLong_FromUnsignedLong(uid);
405}
406
407PyObject *
408_PyLong_FromGid(gid_t gid)
409{
410 if (gid == (gid_t)-1)
411 return PyLong_FromLong(-1);
412 return PyLong_FromUnsignedLong(gid);
413}
414
415int
416_Py_Uid_Converter(PyObject *obj, void *p)
417{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 uid_t uid;
419 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200421 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700422 unsigned long uresult;
423
424 index = PyNumber_Index(obj);
425 if (index == NULL) {
426 PyErr_Format(PyExc_TypeError,
427 "uid should be integer, not %.200s",
428 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200429 return 0;
430 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700431
432 /*
433 * Handling uid_t is complicated for two reasons:
434 * * Although uid_t is (always?) unsigned, it still
435 * accepts -1.
436 * * We don't know its size in advance--it may be
437 * bigger than an int, or it may be smaller than
438 * a long.
439 *
440 * So a bit of defensive programming is in order.
441 * Start with interpreting the value passed
442 * in as a signed long and see if it works.
443 */
444
445 result = PyLong_AsLongAndOverflow(index, &overflow);
446
447 if (!overflow) {
448 uid = (uid_t)result;
449
450 if (result == -1) {
451 if (PyErr_Occurred())
452 goto fail;
453 /* It's a legitimate -1, we're done. */
454 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200455 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700456
457 /* Any other negative number is disallowed. */
458 if (result < 0)
459 goto underflow;
460
461 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463 (long)uid != result)
464 goto underflow;
465 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200466 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700467
468 if (overflow < 0)
469 goto underflow;
470
471 /*
472 * Okay, the value overflowed a signed long. If it
473 * fits in an *unsigned* long, it may still be okay,
474 * as uid_t may be unsigned long on this platform.
475 */
476 uresult = PyLong_AsUnsignedLong(index);
477 if (PyErr_Occurred()) {
478 if (PyErr_ExceptionMatches(PyExc_OverflowError))
479 goto overflow;
480 goto fail;
481 }
482
483 uid = (uid_t)uresult;
484
485 /*
486 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
487 * but this value would get interpreted as (uid_t)-1 by chown
488 * and its siblings. That's not what the user meant! So we
489 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100490 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700491 */
492 if (uid == (uid_t)-1)
493 goto overflow;
494
495 /* Ensure the value wasn't truncated. */
496 if (sizeof(uid_t) < sizeof(long) &&
497 (unsigned long)uid != uresult)
498 goto overflow;
499 /* fallthrough */
500
501success:
502 Py_DECREF(index);
503 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200504 return 1;
505
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700506underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200507 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700508 "uid is less than minimum");
509 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is greater than maximum");
514 /* fallthrough */
515
516fail:
517 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200518 return 0;
519}
520
521int
522_Py_Gid_Converter(PyObject *obj, void *p)
523{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 gid_t gid;
525 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200527 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 unsigned long uresult;
529
530 index = PyNumber_Index(obj);
531 if (index == NULL) {
532 PyErr_Format(PyExc_TypeError,
533 "gid should be integer, not %.200s",
534 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200535 return 0;
536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /*
539 * Handling gid_t is complicated for two reasons:
540 * * Although gid_t is (always?) unsigned, it still
541 * accepts -1.
542 * * We don't know its size in advance--it may be
543 * bigger than an int, or it may be smaller than
544 * a long.
545 *
546 * So a bit of defensive programming is in order.
547 * Start with interpreting the value passed
548 * in as a signed long and see if it works.
549 */
550
551 result = PyLong_AsLongAndOverflow(index, &overflow);
552
553 if (!overflow) {
554 gid = (gid_t)result;
555
556 if (result == -1) {
557 if (PyErr_Occurred())
558 goto fail;
559 /* It's a legitimate -1, we're done. */
560 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200561 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562
563 /* Any other negative number is disallowed. */
564 if (result < 0) {
565 goto underflow;
566 }
567
568 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570 (long)gid != result)
571 goto underflow;
572 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200573 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700574
575 if (overflow < 0)
576 goto underflow;
577
578 /*
579 * Okay, the value overflowed a signed long. If it
580 * fits in an *unsigned* long, it may still be okay,
581 * as gid_t may be unsigned long on this platform.
582 */
583 uresult = PyLong_AsUnsignedLong(index);
584 if (PyErr_Occurred()) {
585 if (PyErr_ExceptionMatches(PyExc_OverflowError))
586 goto overflow;
587 goto fail;
588 }
589
590 gid = (gid_t)uresult;
591
592 /*
593 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
594 * but this value would get interpreted as (gid_t)-1 by chown
595 * and its siblings. That's not what the user meant! So we
596 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100597 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700598 */
599 if (gid == (gid_t)-1)
600 goto overflow;
601
602 /* Ensure the value wasn't truncated. */
603 if (sizeof(gid_t) < sizeof(long) &&
604 (unsigned long)gid != uresult)
605 goto overflow;
606 /* fallthrough */
607
608success:
609 Py_DECREF(index);
610 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200611 return 1;
612
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615 "gid is less than minimum");
616 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is greater than maximum");
621 /* fallthrough */
622
623fail:
624 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200625 return 0;
626}
627#endif /* MS_WINDOWS */
628
629
Larry Hastings9cf065c2012-06-22 16:30:09 -0700630#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400631/*
632 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
633 * without the int cast, the value gets interpreted as uint (4291925331),
634 * which doesn't play nicely with all the initializer lines in this file that
635 * look like this:
636 * int dir_fd = DEFAULT_DIR_FD;
637 */
638#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700639#else
640#define DEFAULT_DIR_FD (-100)
641#endif
642
643static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200644_fd_converter(PyObject *o, int *p, const char *allowed)
645{
646 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647 long long_value;
648
649 PyObject *index = PyNumber_Index(o);
650 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200651 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652 "argument should be %s, not %.200s",
653 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700654 return 0;
655 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700656
657 long_value = PyLong_AsLongAndOverflow(index, &overflow);
658 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200659 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700661 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700662 return 0;
663 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200664 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700665 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667 return 0;
668 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700669
Larry Hastings9cf065c2012-06-22 16:30:09 -0700670 *p = (int)long_value;
671 return 1;
672}
673
674static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200675dir_fd_converter(PyObject *o, void *p)
676{
677 if (o == Py_None) {
678 *(int *)p = DEFAULT_DIR_FD;
679 return 1;
680 }
681 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682}
683
684
685
686/*
687 * A PyArg_ParseTuple "converter" function
688 * that handles filesystem paths in the manner
689 * preferred by the os module.
690 *
691 * path_converter accepts (Unicode) strings and their
692 * subclasses, and bytes and their subclasses. What
693 * it does with the argument depends on the platform:
694 *
695 * * On Windows, if we get a (Unicode) string we
696 * extract the wchar_t * and return it; if we get
697 * bytes we extract the char * and return that.
698 *
699 * * On all other platforms, strings are encoded
700 * to bytes using PyUnicode_FSConverter, then we
701 * extract the char * from the bytes object and
702 * return that.
703 *
704 * path_converter also optionally accepts signed
705 * integers (representing open file descriptors) instead
706 * of path strings.
707 *
708 * Input fields:
709 * path.nullable
710 * If nonzero, the path is permitted to be None.
711 * path.allow_fd
712 * If nonzero, the path is permitted to be a file handle
713 * (a signed int) instead of a string.
714 * path.function_name
715 * If non-NULL, path_converter will use that as the name
716 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700717 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700718 * path.argument_name
719 * If non-NULL, path_converter will use that as the name
720 * of the parameter in error messages.
721 * (If path.argument_name is NULL it uses "path".)
722 *
723 * Output fields:
724 * path.wide
725 * Points to the path if it was expressed as Unicode
726 * and was not encoded. (Only used on Windows.)
727 * path.narrow
728 * Points to the path if it was expressed as bytes,
729 * or it was Unicode and was encoded to bytes.
730 * path.fd
731 * Contains a file descriptor if path.accept_fd was true
732 * and the caller provided a signed integer instead of any
733 * sort of string.
734 *
735 * WARNING: if your "path" parameter is optional, and is
736 * unspecified, path_converter will never get called.
737 * So if you set allow_fd, you *MUST* initialize path.fd = -1
738 * yourself!
739 * path.length
740 * The length of the path in characters, if specified as
741 * a string.
742 * path.object
743 * The original object passed in.
744 * path.cleanup
745 * For internal use only. May point to a temporary object.
746 * (Pay no attention to the man behind the curtain.)
747 *
748 * At most one of path.wide or path.narrow will be non-NULL.
749 * If path was None and path.nullable was set,
750 * or if path was an integer and path.allow_fd was set,
751 * both path.wide and path.narrow will be NULL
752 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200753 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700754 * path_converter takes care to not write to the path_t
755 * unless it's successful. However it must reset the
756 * "cleanup" field each time it's called.
757 *
758 * Use as follows:
759 * path_t path;
760 * memset(&path, 0, sizeof(path));
761 * PyArg_ParseTuple(args, "O&", path_converter, &path);
762 * // ... use values from path ...
763 * path_cleanup(&path);
764 *
765 * (Note that if PyArg_Parse fails you don't need to call
766 * path_cleanup(). However it is safe to do so.)
767 */
768typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100769 const char *function_name;
770 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700771 int nullable;
772 int allow_fd;
773 wchar_t *wide;
774 char *narrow;
775 int fd;
776 Py_ssize_t length;
777 PyObject *object;
778 PyObject *cleanup;
779} path_t;
780
Larry Hastings31826802013-10-19 00:09:25 -0700781#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
782 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
783
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784static void
785path_cleanup(path_t *path) {
786 if (path->cleanup) {
787 Py_DECREF(path->cleanup);
788 path->cleanup = NULL;
789 }
790}
791
792static int
793path_converter(PyObject *o, void *p) {
794 path_t *path = (path_t *)p;
795 PyObject *unicode, *bytes;
796 Py_ssize_t length;
797 char *narrow;
798
799#define FORMAT_EXCEPTION(exc, fmt) \
800 PyErr_Format(exc, "%s%s" fmt, \
801 path->function_name ? path->function_name : "", \
802 path->function_name ? ": " : "", \
803 path->argument_name ? path->argument_name : "path")
804
805 /* Py_CLEANUP_SUPPORTED support */
806 if (o == NULL) {
807 path_cleanup(path);
808 return 1;
809 }
810
811 /* ensure it's always safe to call path_cleanup() */
812 path->cleanup = NULL;
813
814 if (o == Py_None) {
815 if (!path->nullable) {
816 FORMAT_EXCEPTION(PyExc_TypeError,
817 "can't specify None for %s argument");
818 return 0;
819 }
820 path->wide = NULL;
821 path->narrow = NULL;
822 path->length = 0;
823 path->object = o;
824 path->fd = -1;
825 return 1;
826 }
827
828 unicode = PyUnicode_FromObject(o);
829 if (unicode) {
830#ifdef MS_WINDOWS
831 wchar_t *wide;
832 length = PyUnicode_GET_SIZE(unicode);
833 if (length > 32767) {
834 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
835 Py_DECREF(unicode);
836 return 0;
837 }
838
839 wide = PyUnicode_AsUnicode(unicode);
840 if (!wide) {
841 Py_DECREF(unicode);
842 return 0;
843 }
844
845 path->wide = wide;
846 path->narrow = NULL;
847 path->length = length;
848 path->object = o;
849 path->fd = -1;
850 path->cleanup = unicode;
851 return Py_CLEANUP_SUPPORTED;
852#else
853 int converted = PyUnicode_FSConverter(unicode, &bytes);
854 Py_DECREF(unicode);
855 if (!converted)
856 bytes = NULL;
857#endif
858 }
859 else {
860 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200861 if (PyObject_CheckBuffer(o))
862 bytes = PyBytes_FromObject(o);
863 else
864 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700865 if (!bytes) {
866 PyErr_Clear();
867 if (path->allow_fd) {
868 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200869 int result = _fd_converter(o, &fd,
870 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 if (result) {
872 path->wide = NULL;
873 path->narrow = NULL;
874 path->length = 0;
875 path->object = o;
876 path->fd = fd;
877 return result;
878 }
879 }
880 }
881 }
882
883 if (!bytes) {
884 if (!PyErr_Occurred())
885 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
886 return 0;
887 }
888
889#ifdef MS_WINDOWS
890 if (win32_warn_bytes_api()) {
891 Py_DECREF(bytes);
892 return 0;
893 }
894#endif
895
896 length = PyBytes_GET_SIZE(bytes);
897#ifdef MS_WINDOWS
898 if (length > MAX_PATH) {
899 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
900 Py_DECREF(bytes);
901 return 0;
902 }
903#endif
904
905 narrow = PyBytes_AS_STRING(bytes);
906 if (length != strlen(narrow)) {
907 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
908 Py_DECREF(bytes);
909 return 0;
910 }
911
912 path->wide = NULL;
913 path->narrow = narrow;
914 path->length = length;
915 path->object = o;
916 path->fd = -1;
917 path->cleanup = bytes;
918 return Py_CLEANUP_SUPPORTED;
919}
920
921static void
922argument_unavailable_error(char *function_name, char *argument_name) {
923 PyErr_Format(PyExc_NotImplementedError,
924 "%s%s%s unavailable on this platform",
925 (function_name != NULL) ? function_name : "",
926 (function_name != NULL) ? ": ": "",
927 argument_name);
928}
929
930static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200931dir_fd_unavailable(PyObject *o, void *p)
932{
933 int dir_fd;
934 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200936 if (dir_fd != DEFAULT_DIR_FD) {
937 argument_unavailable_error(NULL, "dir_fd");
938 return 0;
939 }
940 *(int *)p = dir_fd;
941 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942}
943
944static int
945fd_specified(char *function_name, int fd) {
946 if (fd == -1)
947 return 0;
948
949 argument_unavailable_error(function_name, "fd");
950 return 1;
951}
952
953static int
954follow_symlinks_specified(char *function_name, int follow_symlinks) {
955 if (follow_symlinks)
956 return 0;
957
958 argument_unavailable_error(function_name, "follow_symlinks");
959 return 1;
960}
961
962static int
963path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
964 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
965 PyErr_Format(PyExc_ValueError,
966 "%s: can't specify dir_fd without matching path",
967 function_name);
968 return 1;
969 }
970 return 0;
971}
972
973static int
974dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
975 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
976 PyErr_Format(PyExc_ValueError,
977 "%s: can't specify both dir_fd and fd",
978 function_name);
979 return 1;
980 }
981 return 0;
982}
983
984static int
985fd_and_follow_symlinks_invalid(char *function_name, int fd,
986 int follow_symlinks) {
987 if ((fd > 0) && (!follow_symlinks)) {
988 PyErr_Format(PyExc_ValueError,
989 "%s: cannot use fd and follow_symlinks together",
990 function_name);
991 return 1;
992 }
993 return 0;
994}
995
996static int
997dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
998 int follow_symlinks) {
999 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1000 PyErr_Format(PyExc_ValueError,
1001 "%s: cannot use dir_fd and follow_symlinks together",
1002 function_name);
1003 return 1;
1004 }
1005 return 0;
1006}
1007
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001008/* A helper used by a number of POSIX-only functions */
1009#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001010static int
1011_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001012{
1013#if !defined(HAVE_LARGEFILE_SUPPORT)
1014 *((off_t*)addr) = PyLong_AsLong(arg);
1015#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001016 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001017#endif
1018 if (PyErr_Occurred())
1019 return 0;
1020 return 1;
1021}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001022#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001023
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001024#if defined _MSC_VER && _MSC_VER >= 1400
1025/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001026 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001027 * Normally, an invalid fd is likely to be a C program error and therefore
1028 * an assertion can be useful, but it does contradict the POSIX standard
1029 * which for write(2) states:
1030 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1031 * "[EBADF] The fildes argument is not a valid file descriptor open for
1032 * writing."
1033 * Furthermore, python allows the user to enter any old integer
1034 * as a fd and should merely raise a python exception on error.
1035 * The Microsoft CRT doesn't provide an official way to check for the
1036 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001038 * internal structures involved.
1039 * The structures below must be updated for each version of visual studio
1040 * according to the file internal.h in the CRT source, until MS comes
1041 * up with a less hacky way to do this.
1042 * (all of this is to avoid globally modifying the CRT behaviour using
1043 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1044 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001045/* The actual size of the structure is determined at runtime.
1046 * Only the first items must be present.
1047 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001048typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001049 intptr_t osfhnd;
1050 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001051} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001052
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001053extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001054#define IOINFO_L2E 5
1055#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1056#define IOINFO_ARRAYS 64
1057#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1058#define FOPEN 0x01
1059#define _NO_CONSOLE_FILENO (intptr_t)-2
1060
1061/* This function emulates what the windows CRT does to validate file handles */
1062int
1063_PyVerify_fd(int fd)
1064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 const int i1 = fd >> IOINFO_L2E;
1066 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001067
Antoine Pitrou22e41552010-08-15 18:07:50 +00001068 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001069
Victor Stinner8c62be82010-05-06 00:08:46 +00001070 /* Determine the actual size of the ioinfo structure,
1071 * as used by the CRT loaded in memory
1072 */
1073 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1074 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1075 }
1076 if (sizeof_ioinfo == 0) {
1077 /* This should not happen... */
1078 goto fail;
1079 }
1080
1081 /* See that it isn't a special CLEAR fileno */
1082 if (fd != _NO_CONSOLE_FILENO) {
1083 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1084 * we check pointer validity and other info
1085 */
1086 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1087 /* finally, check that the file is open */
1088 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1089 if (info->osfile & FOPEN) {
1090 return 1;
1091 }
1092 }
1093 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001094 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 errno = EBADF;
1096 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001097}
1098
1099/* the special case of checking dup2. The target fd must be in a sensible range */
1100static int
1101_PyVerify_fd_dup2(int fd1, int fd2)
1102{
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 if (!_PyVerify_fd(fd1))
1104 return 0;
1105 if (fd2 == _NO_CONSOLE_FILENO)
1106 return 0;
1107 if ((unsigned)fd2 < _NHANDLE_)
1108 return 1;
1109 else
1110 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001111}
1112#else
1113/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1114#define _PyVerify_fd_dup2(A, B) (1)
1115#endif
1116
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001117#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001118/* The following structure was copied from
1119 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1120 include doesn't seem to be present in the Windows SDK (at least as included
1121 with Visual Studio Express). */
1122typedef struct _REPARSE_DATA_BUFFER {
1123 ULONG ReparseTag;
1124 USHORT ReparseDataLength;
1125 USHORT Reserved;
1126 union {
1127 struct {
1128 USHORT SubstituteNameOffset;
1129 USHORT SubstituteNameLength;
1130 USHORT PrintNameOffset;
1131 USHORT PrintNameLength;
1132 ULONG Flags;
1133 WCHAR PathBuffer[1];
1134 } SymbolicLinkReparseBuffer;
1135
1136 struct {
1137 USHORT SubstituteNameOffset;
1138 USHORT SubstituteNameLength;
1139 USHORT PrintNameOffset;
1140 USHORT PrintNameLength;
1141 WCHAR PathBuffer[1];
1142 } MountPointReparseBuffer;
1143
1144 struct {
1145 UCHAR DataBuffer[1];
1146 } GenericReparseBuffer;
1147 };
1148} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1149
1150#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1151 GenericReparseBuffer)
1152#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1153
1154static int
Brian Curtind25aef52011-06-13 15:16:04 -05001155win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001156{
1157 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1158 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1159 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001160
1161 if (0 == DeviceIoControl(
1162 reparse_point_handle,
1163 FSCTL_GET_REPARSE_POINT,
1164 NULL, 0, /* in buffer */
1165 target_buffer, sizeof(target_buffer),
1166 &n_bytes_returned,
1167 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001168 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169
1170 if (reparse_tag)
1171 *reparse_tag = rdb->ReparseTag;
1172
Brian Curtind25aef52011-06-13 15:16:04 -05001173 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001174}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001175
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001176#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001179#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001180/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001181** environ directly, we must obtain it with _NSGetEnviron(). See also
1182** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001183*/
1184#include <crt_externs.h>
1185static char **environ;
1186#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001188#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189
Barry Warsaw53699e91996-12-10 23:23:01 +00001190static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001191convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001192{
Victor Stinner8c62be82010-05-06 00:08:46 +00001193 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001194#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001196#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001198#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001199
Victor Stinner8c62be82010-05-06 00:08:46 +00001200 d = PyDict_New();
1201 if (d == NULL)
1202 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001203#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 if (environ == NULL)
1205 environ = *_NSGetEnviron();
1206#endif
1207#ifdef MS_WINDOWS
1208 /* _wenviron must be initialized in this way if the program is started
1209 through main() instead of wmain(). */
1210 _wgetenv(L"");
1211 if (_wenviron == NULL)
1212 return d;
1213 /* This part ignores errors */
1214 for (e = _wenviron; *e != NULL; e++) {
1215 PyObject *k;
1216 PyObject *v;
1217 wchar_t *p = wcschr(*e, L'=');
1218 if (p == NULL)
1219 continue;
1220 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1221 if (k == NULL) {
1222 PyErr_Clear();
1223 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001224 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1226 if (v == NULL) {
1227 PyErr_Clear();
1228 Py_DECREF(k);
1229 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001230 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 if (PyDict_GetItem(d, k) == NULL) {
1232 if (PyDict_SetItem(d, k, v) != 0)
1233 PyErr_Clear();
1234 }
1235 Py_DECREF(k);
1236 Py_DECREF(v);
1237 }
1238#else
1239 if (environ == NULL)
1240 return d;
1241 /* This part ignores errors */
1242 for (e = environ; *e != NULL; e++) {
1243 PyObject *k;
1244 PyObject *v;
1245 char *p = strchr(*e, '=');
1246 if (p == NULL)
1247 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001248 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 if (k == NULL) {
1250 PyErr_Clear();
1251 continue;
1252 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001253 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 if (v == NULL) {
1255 PyErr_Clear();
1256 Py_DECREF(k);
1257 continue;
1258 }
1259 if (PyDict_GetItem(d, k) == NULL) {
1260 if (PyDict_SetItem(d, k, v) != 0)
1261 PyErr_Clear();
1262 }
1263 Py_DECREF(k);
1264 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001265 }
1266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001267 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001268}
1269
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001270/* Set a POSIX-specific error from errno, and return NULL */
1271
Barry Warsawd58d7641998-07-23 16:14:40 +00001272static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001273posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001274{
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001276}
Mark Hammondef8b6542001-05-13 08:04:26 +00001277
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001278#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001279static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001280win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001281{
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 /* XXX We should pass the function name along in the future.
1283 (winreg.c also wants to pass the function name.)
1284 This would however require an additional param to the
1285 Windows error object, which is non-trivial.
1286 */
1287 errno = GetLastError();
1288 if (filename)
1289 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1290 else
1291 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001292}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001293
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001294static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001295win32_error_object(char* function, PyObject* filename)
1296{
1297 /* XXX - see win32_error for comments on 'function' */
1298 errno = GetLastError();
1299 if (filename)
1300 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001301 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001302 errno,
1303 filename);
1304 else
1305 return PyErr_SetFromWindowsErr(errno);
1306}
1307
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001308#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309
Larry Hastings9cf065c2012-06-22 16:30:09 -07001310static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001311path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001312{
1313#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001314 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1315 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001316#else
Victor Stinner292c8352012-10-30 02:17:38 +01001317 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001318#endif
1319}
1320
Larry Hastings31826802013-10-19 00:09:25 -07001321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322/* POSIX generic methods */
1323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001325posix_fildes(PyObject *fdobj, int (*func)(int))
1326{
Victor Stinner8c62be82010-05-06 00:08:46 +00001327 int fd;
1328 int res;
1329 fd = PyObject_AsFileDescriptor(fdobj);
1330 if (fd < 0)
1331 return NULL;
1332 if (!_PyVerify_fd(fd))
1333 return posix_error();
1334 Py_BEGIN_ALLOW_THREADS
1335 res = (*func)(fd);
1336 Py_END_ALLOW_THREADS
1337 if (res < 0)
1338 return posix_error();
1339 Py_INCREF(Py_None);
1340 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001341}
Guido van Rossum21142a01999-01-08 21:05:37 +00001342
1343static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001344posix_1str(const char *func_name, PyObject *args, char *format,
1345 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346{
Victor Stinner292c8352012-10-30 02:17:38 +01001347 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001349 memset(&path, 0, sizeof(path));
1350 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001352 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001355 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001357 if (res < 0) {
1358 path_error(&path);
1359 path_cleanup(&path);
1360 return NULL;
1361 }
1362 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 Py_INCREF(Py_None);
1364 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001367
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001368#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369/* This is a reimplementation of the C library's chdir function,
1370 but one that produces Win32 errors instead of DOS error codes.
1371 chdir is essentially a wrapper around SetCurrentDirectory; however,
1372 it also needs to set "magic" environment variables indicating
1373 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001374static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375win32_chdir(LPCSTR path)
1376{
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 char new_path[MAX_PATH+1];
1378 int result;
1379 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 if(!SetCurrentDirectoryA(path))
1382 return FALSE;
1383 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1384 if (!result)
1385 return FALSE;
1386 /* In the ANSI API, there should not be any paths longer
1387 than MAX_PATH. */
1388 assert(result <= MAX_PATH+1);
1389 if (strncmp(new_path, "\\\\", 2) == 0 ||
1390 strncmp(new_path, "//", 2) == 0)
1391 /* UNC path, nothing to do. */
1392 return TRUE;
1393 env[1] = new_path[0];
1394 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395}
1396
1397/* The Unicode version differs from the ANSI version
1398 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001399static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400win32_wchdir(LPCWSTR path)
1401{
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1403 int result;
1404 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 if(!SetCurrentDirectoryW(path))
1407 return FALSE;
1408 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1409 if (!result)
1410 return FALSE;
1411 if (result > MAX_PATH+1) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001412 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if (!new_path) {
1414 SetLastError(ERROR_OUTOFMEMORY);
1415 return FALSE;
1416 }
1417 result = GetCurrentDirectoryW(result, new_path);
1418 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001419 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 return FALSE;
1421 }
1422 }
1423 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1424 wcsncmp(new_path, L"//", 2) == 0)
1425 /* UNC path, nothing to do. */
1426 return TRUE;
1427 env[1] = new_path[0];
1428 result = SetEnvironmentVariableW(env, new_path);
1429 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001430 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001432}
1433#endif
1434
Martin v. Löwis14694662006-02-03 12:54:16 +00001435#ifdef MS_WINDOWS
1436/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1437 - time stamps are restricted to second resolution
1438 - file modification times suffer from forth-and-back conversions between
1439 UTC and local time
1440 Therefore, we implement our own stat, based on the Win32 API directly.
1441*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001442#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001443
1444struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001445 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001446 __int64 st_ino;
1447 unsigned short st_mode;
1448 int st_nlink;
1449 int st_uid;
1450 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001451 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001453 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001454 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001455 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001456 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001457 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001458 int st_ctime_nsec;
1459};
1460
1461static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1462
1463static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001464FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1467 /* Cannot simply cast and dereference in_ptr,
1468 since it might not be aligned properly */
1469 __int64 in;
1470 memcpy(&in, in_ptr, sizeof(in));
1471 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001472 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001473}
1474
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001476time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477{
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 /* XXX endianness */
1479 __int64 out;
1480 out = time_in + secs_between_epochs;
1481 out = out * 10000000 + nsec_in / 100;
1482 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001483}
1484
Martin v. Löwis14694662006-02-03 12:54:16 +00001485/* Below, we *know* that ugo+r is 0444 */
1486#if _S_IREAD != 0400
1487#error Unsupported C library
1488#endif
1489static int
1490attributes_to_mode(DWORD attr)
1491{
Victor Stinner8c62be82010-05-06 00:08:46 +00001492 int m = 0;
1493 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1494 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1495 else
1496 m |= _S_IFREG;
1497 if (attr & FILE_ATTRIBUTE_READONLY)
1498 m |= 0444;
1499 else
1500 m |= 0666;
1501 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001502}
1503
1504static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001505attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001506{
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 memset(result, 0, sizeof(*result));
1508 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1509 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001510 result->st_dev = info->dwVolumeSerialNumber;
1511 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001512 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1513 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1514 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001516 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1518 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001519 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001520 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001521 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001522 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001523
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001525}
1526
Guido van Rossumd8faa362007-04-27 19:54:29 +00001527static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001529{
Victor Stinner8c62be82010-05-06 00:08:46 +00001530 HANDLE hFindFile;
1531 WIN32_FIND_DATAA FileData;
1532 hFindFile = FindFirstFileA(pszFile, &FileData);
1533 if (hFindFile == INVALID_HANDLE_VALUE)
1534 return FALSE;
1535 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001537 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 info->dwFileAttributes = FileData.dwFileAttributes;
1539 info->ftCreationTime = FileData.ftCreationTime;
1540 info->ftLastAccessTime = FileData.ftLastAccessTime;
1541 info->ftLastWriteTime = FileData.ftLastWriteTime;
1542 info->nFileSizeHigh = FileData.nFileSizeHigh;
1543 info->nFileSizeLow = FileData.nFileSizeLow;
1544/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001545 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1546 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001548}
1549
1550static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001551attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552{
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 HANDLE hFindFile;
1554 WIN32_FIND_DATAW FileData;
1555 hFindFile = FindFirstFileW(pszFile, &FileData);
1556 if (hFindFile == INVALID_HANDLE_VALUE)
1557 return FALSE;
1558 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001559 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 info->dwFileAttributes = FileData.dwFileAttributes;
1562 info->ftCreationTime = FileData.ftCreationTime;
1563 info->ftLastAccessTime = FileData.ftLastAccessTime;
1564 info->ftLastWriteTime = FileData.ftLastWriteTime;
1565 info->nFileSizeHigh = FileData.nFileSizeHigh;
1566 info->nFileSizeLow = FileData.nFileSizeLow;
1567/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001568 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1569 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001571}
1572
Brian Curtind25aef52011-06-13 15:16:04 -05001573/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001574static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001575static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1576 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001577static int
Brian Curtind25aef52011-06-13 15:16:04 -05001578check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579{
Brian Curtind25aef52011-06-13 15:16:04 -05001580 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001581 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1582 DWORD);
1583
Brian Curtind25aef52011-06-13 15:16:04 -05001584 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001585 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001586 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001587 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001588 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1589 "GetFinalPathNameByHandleA");
1590 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1591 "GetFinalPathNameByHandleW");
1592 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1593 Py_GetFinalPathNameByHandleW;
1594 }
1595 return has_GetFinalPathNameByHandle;
1596}
1597
1598static BOOL
1599get_target_path(HANDLE hdl, wchar_t **target_path)
1600{
1601 int buf_size, result_length;
1602 wchar_t *buf;
1603
1604 /* We have a good handle to the target, use it to determine
1605 the target path name (then we'll call lstat on it). */
1606 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1607 VOLUME_NAME_DOS);
1608 if(!buf_size)
1609 return FALSE;
1610
Victor Stinnerb6404912013-07-07 16:21:41 +02001611 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001612 if (!buf) {
1613 SetLastError(ERROR_OUTOFMEMORY);
1614 return FALSE;
1615 }
1616
Brian Curtind25aef52011-06-13 15:16:04 -05001617 result_length = Py_GetFinalPathNameByHandleW(hdl,
1618 buf, buf_size, VOLUME_NAME_DOS);
1619
1620 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001621 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001622 return FALSE;
1623 }
1624
1625 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001626 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001627 return FALSE;
1628 }
1629
1630 buf[result_length] = 0;
1631
1632 *target_path = buf;
1633 return TRUE;
1634}
1635
1636static int
1637win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1638 BOOL traverse);
1639static int
1640win32_xstat_impl(const char *path, struct win32_stat *result,
1641 BOOL traverse)
1642{
Victor Stinner26de69d2011-06-17 15:15:38 +02001643 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001644 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001646 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001647 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 const char *dot;
1649
Brian Curtind25aef52011-06-13 15:16:04 -05001650 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001651 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1652 traverse reparse point. */
1653 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001654 }
1655
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656 hFile = CreateFileA(
1657 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001658 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 0, /* share mode */
1660 NULL, /* security attributes */
1661 OPEN_EXISTING,
1662 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001663 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1664 Because of this, calls like GetFinalPathNameByHandle will return
1665 the symlink path agin and not the actual final path. */
1666 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1667 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 NULL);
1669
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671 /* Either the target doesn't exist, or we don't have access to
1672 get a handle to it. If the former, we need to return an error.
1673 If the latter, we can use attributes_from_dir. */
1674 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 return -1;
1676 /* Could not get attributes on open file. Fall back to
1677 reading the directory. */
1678 if (!attributes_from_dir(path, &info, &reparse_tag))
1679 /* Very strange. This should not fail now */
1680 return -1;
1681 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1682 if (traverse) {
1683 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001684 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 } else {
1689 if (!GetFileInformationByHandle(hFile, &info)) {
1690 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001691 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 }
1693 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001694 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1695 return -1;
1696
1697 /* Close the outer open file handle now that we're about to
1698 reopen it with different flags. */
1699 if (!CloseHandle(hFile))
1700 return -1;
1701
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001703 /* In order to call GetFinalPathNameByHandle we need to open
1704 the file without the reparse handling flag set. */
1705 hFile2 = CreateFileA(
1706 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1707 NULL, OPEN_EXISTING,
1708 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1709 NULL);
1710 if (hFile2 == INVALID_HANDLE_VALUE)
1711 return -1;
1712
1713 if (!get_target_path(hFile2, &target_path))
1714 return -1;
1715
1716 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001717 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 return code;
1719 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001720 } else
1721 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724
1725 /* Set S_IEXEC if it is an .exe, .bat, ... */
1726 dot = strrchr(path, '.');
1727 if (dot) {
1728 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1729 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1730 result->st_mode |= 0111;
1731 }
1732 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001733}
1734
1735static int
Brian Curtind25aef52011-06-13 15:16:04 -05001736win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1737 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001738{
1739 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001740 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001741 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001742 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001743 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744 const wchar_t *dot;
1745
Brian Curtind25aef52011-06-13 15:16:04 -05001746 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001747 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1748 traverse reparse point. */
1749 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 }
1751
Brian Curtinf5e76d02010-11-24 13:14:05 +00001752 hFile = CreateFileW(
1753 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001754 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001755 0, /* share mode */
1756 NULL, /* security attributes */
1757 OPEN_EXISTING,
1758 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001759 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1760 Because of this, calls like GetFinalPathNameByHandle will return
1761 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001762 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001763 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001764 NULL);
1765
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001766 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767 /* Either the target doesn't exist, or we don't have access to
1768 get a handle to it. If the former, we need to return an error.
1769 If the latter, we can use attributes_from_dir. */
1770 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001771 return -1;
1772 /* Could not get attributes on open file. Fall back to
1773 reading the directory. */
1774 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1775 /* Very strange. This should not fail now */
1776 return -1;
1777 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1778 if (traverse) {
1779 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001780 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001781 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001782 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001783 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 } else {
1785 if (!GetFileInformationByHandle(hFile, &info)) {
1786 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001787 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 }
1789 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001790 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1791 return -1;
1792
1793 /* Close the outer open file handle now that we're about to
1794 reopen it with different flags. */
1795 if (!CloseHandle(hFile))
1796 return -1;
1797
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001798 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001799 /* In order to call GetFinalPathNameByHandle we need to open
1800 the file without the reparse handling flag set. */
1801 hFile2 = CreateFileW(
1802 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1803 NULL, OPEN_EXISTING,
1804 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1805 NULL);
1806 if (hFile2 == INVALID_HANDLE_VALUE)
1807 return -1;
1808
1809 if (!get_target_path(hFile2, &target_path))
1810 return -1;
1811
1812 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001813 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001814 return code;
1815 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001816 } else
1817 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001819 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001820
1821 /* Set S_IEXEC if it is an .exe, .bat, ... */
1822 dot = wcsrchr(path, '.');
1823 if (dot) {
1824 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1825 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1826 result->st_mode |= 0111;
1827 }
1828 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001829}
1830
1831static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001832win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001833{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001836 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001837 errno = 0;
1838 return code;
1839}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001840
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001841static int
1842win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1843{
1844 /* Protocol violation: we explicitly clear errno, instead of
1845 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001846 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001847 errno = 0;
1848 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001849}
Brian Curtind25aef52011-06-13 15:16:04 -05001850/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001851
1852 In Posix, stat automatically traverses symlinks and returns the stat
1853 structure for the target. In Windows, the equivalent GetFileAttributes by
1854 default does not traverse symlinks and instead returns attributes for
1855 the symlink.
1856
1857 Therefore, win32_lstat will get the attributes traditionally, and
1858 win32_stat will first explicitly resolve the symlink target and then will
1859 call win32_lstat on that result.
1860
Ezio Melotti4969f702011-03-15 05:59:46 +02001861 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001862
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001863static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001864win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001865{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001866 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001867}
1868
Victor Stinner8c62be82010-05-06 00:08:46 +00001869static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001870win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001871{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001873}
1874
1875static int
1876win32_stat(const char* path, struct win32_stat *result)
1877{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001879}
1880
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001881static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001882win32_stat_w(const wchar_t* path, struct win32_stat *result)
1883{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001884 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001885}
1886
1887static int
1888win32_fstat(int file_number, struct win32_stat *result)
1889{
Victor Stinner8c62be82010-05-06 00:08:46 +00001890 BY_HANDLE_FILE_INFORMATION info;
1891 HANDLE h;
1892 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001893
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001894 if (!_PyVerify_fd(file_number))
1895 h = INVALID_HANDLE_VALUE;
1896 else
1897 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001898
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 /* Protocol violation: we explicitly clear errno, instead of
1900 setting it to a POSIX error. Callers should use GetLastError. */
1901 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001902
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 if (h == INVALID_HANDLE_VALUE) {
1904 /* This is really a C library error (invalid file handle).
1905 We set the Win32 error to the closes one matching. */
1906 SetLastError(ERROR_INVALID_HANDLE);
1907 return -1;
1908 }
1909 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001910
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 type = GetFileType(h);
1912 if (type == FILE_TYPE_UNKNOWN) {
1913 DWORD error = GetLastError();
1914 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001915 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 }
1917 /* else: valid but unknown file */
1918 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001919
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 if (type != FILE_TYPE_DISK) {
1921 if (type == FILE_TYPE_CHAR)
1922 result->st_mode = _S_IFCHR;
1923 else if (type == FILE_TYPE_PIPE)
1924 result->st_mode = _S_IFIFO;
1925 return 0;
1926 }
1927
1928 if (!GetFileInformationByHandle(h, &info)) {
1929 return -1;
1930 }
1931
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001932 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1935 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001936}
1937
1938#endif /* MS_WINDOWS */
1939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001940PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001941"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001943 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1945\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001946Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1947or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001950
1951static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 {"st_mode", "protection bits"},
1953 {"st_ino", "inode"},
1954 {"st_dev", "device"},
1955 {"st_nlink", "number of hard links"},
1956 {"st_uid", "user ID of owner"},
1957 {"st_gid", "group ID of owner"},
1958 {"st_size", "total size, in bytes"},
1959 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1960 {NULL, "integer time of last access"},
1961 {NULL, "integer time of last modification"},
1962 {NULL, "integer time of last change"},
1963 {"st_atime", "time of last access"},
1964 {"st_mtime", "time of last modification"},
1965 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001966 {"st_atime_ns", "time of last access in nanoseconds"},
1967 {"st_mtime_ns", "time of last modification in nanoseconds"},
1968 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001971#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001972#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001975#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001978#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001980#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001981#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001983#endif
1984#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001986#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001990#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001991#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001993#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001994#endif
1995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001997#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1998#else
1999#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2000#endif
2001
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002002#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2004#else
2005#define ST_RDEV_IDX ST_BLOCKS_IDX
2006#endif
2007
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002008#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2009#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2010#else
2011#define ST_FLAGS_IDX ST_RDEV_IDX
2012#endif
2013
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002015#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002017#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#endif
2019
2020#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2021#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2022#else
2023#define ST_BIRTHTIME_IDX ST_GEN_IDX
2024#endif
2025
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002026static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 "stat_result", /* name */
2028 stat_result__doc__, /* doc */
2029 stat_result_fields,
2030 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002031};
2032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002034"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2035This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002036 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002037or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002040
2041static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 {"f_bsize", },
2043 {"f_frsize", },
2044 {"f_blocks", },
2045 {"f_bfree", },
2046 {"f_bavail", },
2047 {"f_files", },
2048 {"f_ffree", },
2049 {"f_favail", },
2050 {"f_flag", },
2051 {"f_namemax",},
2052 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002053};
2054
2055static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 "statvfs_result", /* name */
2057 statvfs_result__doc__, /* doc */
2058 statvfs_result_fields,
2059 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060};
2061
Ross Lagerwall7807c352011-03-17 20:20:30 +02002062#if defined(HAVE_WAITID) && !defined(__APPLE__)
2063PyDoc_STRVAR(waitid_result__doc__,
2064"waitid_result: Result from waitid.\n\n\
2065This object may be accessed either as a tuple of\n\
2066 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2067or via the attributes si_pid, si_uid, and so on.\n\
2068\n\
2069See os.waitid for more information.");
2070
2071static PyStructSequence_Field waitid_result_fields[] = {
2072 {"si_pid", },
2073 {"si_uid", },
2074 {"si_signo", },
2075 {"si_status", },
2076 {"si_code", },
2077 {0}
2078};
2079
2080static PyStructSequence_Desc waitid_result_desc = {
2081 "waitid_result", /* name */
2082 waitid_result__doc__, /* doc */
2083 waitid_result_fields,
2084 5
2085};
2086static PyTypeObject WaitidResultType;
2087#endif
2088
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002089static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090static PyTypeObject StatResultType;
2091static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002092#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002093static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002094#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002095static newfunc structseq_new;
2096
2097static PyObject *
2098statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2099{
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 PyStructSequence *result;
2101 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002102
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 result = (PyStructSequence*)structseq_new(type, args, kwds);
2104 if (!result)
2105 return NULL;
2106 /* If we have been initialized from a tuple,
2107 st_?time might be set to None. Initialize it
2108 from the int slots. */
2109 for (i = 7; i <= 9; i++) {
2110 if (result->ob_item[i+3] == Py_None) {
2111 Py_DECREF(Py_None);
2112 Py_INCREF(result->ob_item[i]);
2113 result->ob_item[i+3] = result->ob_item[i];
2114 }
2115 }
2116 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002117}
2118
2119
2120
2121/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002122static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002123
2124PyDoc_STRVAR(stat_float_times__doc__,
2125"stat_float_times([newval]) -> oldval\n\n\
2126Determine whether os.[lf]stat represents time stamps as float objects.\n\
2127If newval is True, future calls to stat() return floats, if it is False,\n\
2128future calls return ints. \n\
2129If newval is omitted, return the current setting.\n");
2130
2131static PyObject*
2132stat_float_times(PyObject* self, PyObject *args)
2133{
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 int newval = -1;
2135 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2136 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002137 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2138 "stat_float_times() is deprecated",
2139 1))
2140 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002141 if (newval == -1)
2142 /* Return old value */
2143 return PyBool_FromLong(_stat_float_times);
2144 _stat_float_times = newval;
2145 Py_INCREF(Py_None);
2146 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002147}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002148
Larry Hastings6fe20b32012-04-19 15:07:49 -07002149static PyObject *billion = NULL;
2150
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002151static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002152fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002153{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002154 PyObject *s = _PyLong_FromTime_t(sec);
2155 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2156 PyObject *s_in_ns = NULL;
2157 PyObject *ns_total = NULL;
2158 PyObject *float_s = NULL;
2159
2160 if (!(s && ns_fractional))
2161 goto exit;
2162
2163 s_in_ns = PyNumber_Multiply(s, billion);
2164 if (!s_in_ns)
2165 goto exit;
2166
2167 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2168 if (!ns_total)
2169 goto exit;
2170
Victor Stinner4195b5c2012-02-08 23:03:19 +01002171 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002172 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2173 if (!float_s)
2174 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002176 else {
2177 float_s = s;
2178 Py_INCREF(float_s);
2179 }
2180
2181 PyStructSequence_SET_ITEM(v, index, s);
2182 PyStructSequence_SET_ITEM(v, index+3, float_s);
2183 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2184 s = NULL;
2185 float_s = NULL;
2186 ns_total = NULL;
2187exit:
2188 Py_XDECREF(s);
2189 Py_XDECREF(ns_fractional);
2190 Py_XDECREF(s_in_ns);
2191 Py_XDECREF(ns_total);
2192 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002193}
2194
Tim Peters5aa91602002-01-30 05:46:57 +00002195/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002196 (used by posix_stat() and posix_fstat()) */
2197static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002198_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002199{
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 unsigned long ansec, mnsec, cnsec;
2201 PyObject *v = PyStructSequence_New(&StatResultType);
2202 if (v == NULL)
2203 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002204
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002206#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 1,
2208 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002209#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002211#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002212#ifdef MS_WINDOWS
2213 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2214#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 2,
2216 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002217#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002218 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002219#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002220 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002221#if defined(MS_WINDOWS)
2222 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2223 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2224#else
2225 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2226 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2227#endif
Fred Drake699f3522000-06-29 21:12:41 +00002228#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002229 PyStructSequence_SET_ITEM(v, 6,
2230 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002231#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002232 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002233#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002234
Martin v. Löwis14694662006-02-03 12:54:16 +00002235#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 ansec = st->st_atim.tv_nsec;
2237 mnsec = st->st_mtim.tv_nsec;
2238 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002239#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 ansec = st->st_atimespec.tv_nsec;
2241 mnsec = st->st_mtimespec.tv_nsec;
2242 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002243#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 ansec = st->st_atime_nsec;
2245 mnsec = st->st_mtime_nsec;
2246 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002249#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002250 fill_time(v, 7, st->st_atime, ansec);
2251 fill_time(v, 8, st->st_mtime, mnsec);
2252 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002253
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002254#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2256 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002257#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002258#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2260 PyLong_FromLong((long)st->st_blocks));
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002263 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2264 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002265#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2268 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002269#endif
2270#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002271 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 PyObject *val;
2273 unsigned long bsec,bnsec;
2274 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002276 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002277#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002278 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002280 if (_stat_float_times) {
2281 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2282 } else {
2283 val = PyLong_FromLong((long)bsec);
2284 }
2285 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2286 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002288#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002289#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2291 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002292#endif
Fred Drake699f3522000-06-29 21:12:41 +00002293
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 if (PyErr_Occurred()) {
2295 Py_DECREF(v);
2296 return NULL;
2297 }
Fred Drake699f3522000-06-29 21:12:41 +00002298
Victor Stinner8c62be82010-05-06 00:08:46 +00002299 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002300}
2301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302/* POSIX methods */
2303
Guido van Rossum94f6f721999-01-06 18:42:14 +00002304
2305static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306posix_do_stat(char *function_name, path_t *path,
2307 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002308{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002309 STRUCT_STAT st;
2310 int result;
2311
2312#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2313 if (follow_symlinks_specified(function_name, follow_symlinks))
2314 return NULL;
2315#endif
2316
2317 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2318 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2319 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2320 return NULL;
2321
2322 Py_BEGIN_ALLOW_THREADS
2323 if (path->fd != -1)
2324 result = FSTAT(path->fd, &st);
2325 else
2326#ifdef MS_WINDOWS
2327 if (path->wide) {
2328 if (follow_symlinks)
2329 result = win32_stat_w(path->wide, &st);
2330 else
2331 result = win32_lstat_w(path->wide, &st);
2332 }
2333 else
2334#endif
2335#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2336 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2337 result = LSTAT(path->narrow, &st);
2338 else
2339#endif
2340#ifdef HAVE_FSTATAT
2341 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2342 result = fstatat(dir_fd, path->narrow, &st,
2343 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2344 else
2345#endif
2346 result = STAT(path->narrow, &st);
2347 Py_END_ALLOW_THREADS
2348
Victor Stinner292c8352012-10-30 02:17:38 +01002349 if (result != 0) {
2350 return path_error(path);
2351 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002352
2353 return _pystat_fromstructstat(&st);
2354}
2355
Larry Hastings31826802013-10-19 00:09:25 -07002356#ifdef HAVE_FSTATAT
2357 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2358#else
2359 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2360#endif
2361
2362
2363/*[python]
2364
2365class path_t_converter(CConverter):
2366
2367 type = "path_t"
2368 impl_by_reference = True
2369 parse_by_reference = True
2370
2371 converter = 'path_converter'
2372
2373 def converter_init(self, *, allow_fd=False, nullable=False):
2374 def strify(value):
2375 return str(int(bool(value)))
2376
2377 # right now path_t doesn't support default values.
2378 # to support a default value, you'll need to override initialize().
2379
2380 assert self.default is unspecified
2381
2382 self.nullable = nullable
2383 self.allow_fd = allow_fd
2384
2385 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2386 self.function.name,
2387 strify(nullable),
2388 strify(allow_fd),
2389 )
2390
2391 def cleanup(self):
2392 return "path_cleanup(&" + self.name + ");\n"
2393
2394
2395class dir_fd_converter(CConverter):
2396 type = 'int'
2397 converter = 'OS_STAT_DIR_FD_CONVERTER'
2398
2399 def converter_init(self):
2400 if self.default in (unspecified, None):
2401 self.c_default = 'DEFAULT_DIR_FD'
2402
2403
2404[python]*/
2405/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
2406
2407/*[clinic]
2408module os
2409
2410os.stat -> object(doc_default='stat_result')
2411
2412 path : path_t(allow_fd=True)
2413 Path to be examined; can be string, bytes, or open-file-descriptor int.
2414
2415 *
2416
2417 dir_fd : dir_fd = None
2418 If not None, it should be a file descriptor open to a directory,
2419 and path should be a relative string; path will then be relative to
2420 that directory.
2421
2422 follow_symlinks: bool = True
2423 If False, and the last element of the path is a symbolic link,
2424 stat will examine the symbolic link itself instead of the file
2425 the link points to.
2426
2427Perform a stat system call on the given path.
2428
2429dir_fd and follow_symlinks may not be implemented
2430 on your platform. If they are unavailable, using them will raise a
2431 NotImplementedError.
2432
2433It's an error to use dir_fd or follow_symlinks when specifying path as
2434 an open file descriptor.
2435
2436[clinic]*/
2437
2438PyDoc_STRVAR(os_stat__doc__,
2439"Perform a stat system call on the given path.\n"
2440"\n"
2441"os.stat(path, *, dir_fd=None, follow_symlinks=True) -> stat_result\n"
2442" path\n"
2443" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2444" dir_fd\n"
2445" If not None, it should be a file descriptor open to a directory,\n"
2446" and path should be a relative string; path will then be relative to\n"
2447" that directory.\n"
2448" follow_symlinks\n"
2449" If False, and the last element of the path is a symbolic link,\n"
2450" stat will examine the symbolic link itself instead of the file\n"
2451" the link points to.\n"
2452"\n"
2453"dir_fd and follow_symlinks may not be implemented\n"
2454" on your platform. If they are unavailable, using them will raise a\n"
2455" NotImplementedError.\n"
2456"\n"
2457"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2458" an open file descriptor.");
2459
2460#define OS_STAT_METHODDEF \
2461 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462
2463static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002464os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks);
2465
2466static PyObject *
2467os_stat(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468{
Larry Hastings31826802013-10-19 00:09:25 -07002469 PyObject *return_value = NULL;
2470 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2471 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002472 int dir_fd = DEFAULT_DIR_FD;
2473 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002474
Larry Hastings31826802013-10-19 00:09:25 -07002475 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2476 "O&|$O&p:stat", _keywords,
2477 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2478 goto exit;
2479 return_value = os_stat_impl(self, &path, dir_fd, follow_symlinks);
2480
2481exit:
2482 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002483 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002484
Larry Hastings9cf065c2012-06-22 16:30:09 -07002485 return return_value;
2486}
2487
Larry Hastings31826802013-10-19 00:09:25 -07002488static PyObject *
2489os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks)
2490/*[clinic checksum: 9d9af08e8cfafd12f94e73ea3065eb3056f99515]*/
2491{
2492 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2493}
2494
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495PyDoc_STRVAR(posix_lstat__doc__,
2496"lstat(path, *, dir_fd=None) -> stat result\n\n\
2497Like stat(), but do not follow symbolic links.\n\
2498Equivalent to stat(path, follow_symlinks=False).");
2499
2500static PyObject *
2501posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2502{
2503 static char *keywords[] = {"path", "dir_fd", NULL};
2504 path_t path;
2505 int dir_fd = DEFAULT_DIR_FD;
2506 int follow_symlinks = 0;
2507 PyObject *return_value;
2508
2509 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002510 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2512 path_converter, &path,
2513#ifdef HAVE_FSTATAT
2514 dir_fd_converter, &dir_fd
2515#else
2516 dir_fd_unavailable, &dir_fd
2517#endif
2518 ))
2519 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002520 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 path_cleanup(&path);
2522 return return_value;
2523}
2524
Larry Hastings31826802013-10-19 00:09:25 -07002525
2526#ifdef HAVE_FACCESSAT
2527 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2528#else
2529 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2530#endif
2531/*[clinic]
2532os.access -> object(doc_default='True if granted, False otherwise')
2533
2534 path: path_t(allow_fd=True)
2535 Path to be tested; can be string, bytes, or open-file-descriptor int.
2536
2537 mode: int
2538 Operating-system mode bitfield. Can be F_OK to test existence,
2539 or the inclusive-OR of R_OK, W_OK, and X_OK.
2540
2541 *
2542
2543 dir_fd : dir_fd = None
2544 If not None, it should be a file descriptor open to a directory,
2545 and path should be relative; path will then be relative to that
2546 directory.
2547
2548 effective_ids: bool = False
2549 If True, access will use the effective uid/gid instead of
2550 the real uid/gid.
2551
2552 follow_symlinks: bool = True
2553 If False, and the last element of the path is a symbolic link,
2554 access will examine the symbolic link itself instead of the file
2555 the link points to.
2556
2557Use the real uid/gid to test for access to a path.
2558
2559{parameters}
2560dir_fd, effective_ids, and follow_symlinks may not be implemented
2561 on your platform. If they are unavailable, using them will raise a
2562 NotImplementedError.
2563
2564Note that most operations will use the effective uid/gid, therefore this
2565 routine can be used in a suid/sgid environment to test if the invoking user
2566 has the specified access to the path.
2567
2568[clinic]*/
2569
2570PyDoc_STRVAR(os_access__doc__,
2571"Use the real uid/gid to test for access to a path.\n"
2572"\n"
2573"os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) -> True if granted, False otherwise\n"
2574" path\n"
2575" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2576" mode\n"
2577" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2578" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2579" dir_fd\n"
2580" If not None, it should be a file descriptor open to a directory,\n"
2581" and path should be relative; path will then be relative to that\n"
2582" directory.\n"
2583" effective_ids\n"
2584" If True, access will use the effective uid/gid instead of\n"
2585" the real uid/gid.\n"
2586" follow_symlinks\n"
2587" If False, and the last element of the path is a symbolic link,\n"
2588" access will examine the symbolic link itself instead of the file\n"
2589" the link points to.\n"
2590"\n"
2591"{parameters}\n"
2592"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2593" on your platform. If they are unavailable, using them will raise a\n"
2594" NotImplementedError.\n"
2595"\n"
2596"Note that most operations will use the effective uid/gid, therefore this\n"
2597" routine can be used in a suid/sgid environment to test if the invoking user\n"
2598" has the specified access to the path.");
2599
2600#define OS_ACCESS_METHODDEF \
2601 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602
2603static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002604os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
2605
2606static PyObject *
2607os_access(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608{
Larry Hastings31826802013-10-19 00:09:25 -07002609 PyObject *return_value = NULL;
2610 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2611 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002612 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613 int dir_fd = DEFAULT_DIR_FD;
2614 int effective_ids = 0;
2615 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002616
2617 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2618 "O&i|$O&pp:access", _keywords,
2619 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2620 goto exit;
2621 return_value = os_access_impl(self, &path, mode, dir_fd, effective_ids, follow_symlinks);
2622
2623exit:
2624 /* Cleanup for path */
2625 path_cleanup(&path);
2626
2627 return return_value;
2628}
2629
2630static PyObject *
2631os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
2632/*[clinic checksum: 0147557eb43243df57ba616cc7c35f232c69bc6a]*/
2633{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002635
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002636#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002638#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642#ifndef HAVE_FACCESSAT
2643 if (follow_symlinks_specified("access", follow_symlinks))
2644 goto exit;
2645
2646 if (effective_ids) {
2647 argument_unavailable_error("access", "effective_ids");
2648 goto exit;
2649 }
2650#endif
2651
2652#ifdef MS_WINDOWS
2653 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002654 if (path->wide != NULL)
2655 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002657 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 Py_END_ALLOW_THREADS
2659
2660 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002661 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662 * * we didn't get a -1, and
2663 * * write access wasn't requested,
2664 * * or the file isn't read-only,
2665 * * or it's a directory.
2666 * (Directories cannot be read-only on Windows.)
2667 */
2668 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002669 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002670 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 !(attr & FILE_ATTRIBUTE_READONLY) ||
2672 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2673#else
2674
2675 Py_BEGIN_ALLOW_THREADS
2676#ifdef HAVE_FACCESSAT
2677 if ((dir_fd != DEFAULT_DIR_FD) ||
2678 effective_ids ||
2679 !follow_symlinks) {
2680 int flags = 0;
2681 if (!follow_symlinks)
2682 flags |= AT_SYMLINK_NOFOLLOW;
2683 if (effective_ids)
2684 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002685 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 }
2687 else
2688#endif
Larry Hastings31826802013-10-19 00:09:25 -07002689 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690 Py_END_ALLOW_THREADS
2691 return_value = PyBool_FromLong(!result);
2692#endif
2693
2694#ifndef HAVE_FACCESSAT
2695exit:
2696#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002698}
2699
Guido van Rossumd371ff11999-01-25 16:12:23 +00002700#ifndef F_OK
2701#define F_OK 0
2702#endif
2703#ifndef R_OK
2704#define R_OK 4
2705#endif
2706#ifndef W_OK
2707#define W_OK 2
2708#endif
2709#ifndef X_OK
2710#define X_OK 1
2711#endif
2712
Larry Hastings31826802013-10-19 00:09:25 -07002713
Guido van Rossumd371ff11999-01-25 16:12:23 +00002714#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002715
2716/*[clinic]
2717os.ttyname -> DecodeFSDefault
2718
2719 fd: int
2720 Integer file descriptor handle.
2721
2722 /
2723
2724Return the name of the terminal device connected to 'fd'.
2725[clinic]*/
2726
2727PyDoc_STRVAR(os_ttyname__doc__,
2728"Return the name of the terminal device connected to \'fd\'.\n"
2729"\n"
2730"os.ttyname(fd)\n"
2731" fd\n"
2732" Integer file descriptor handle.");
2733
2734#define OS_TTYNAME_METHODDEF \
2735 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2736
2737static char *
2738os_ttyname_impl(PyObject *self, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002739
2740static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002741os_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002742{
Larry Hastings31826802013-10-19 00:09:25 -07002743 PyObject *return_value = NULL;
2744 int fd;
2745 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002746
Larry Hastings31826802013-10-19 00:09:25 -07002747 if (!PyArg_ParseTuple(args,
2748 "i:ttyname",
2749 &fd))
2750 goto exit;
2751 _return_value = os_ttyname_impl(self, fd);
2752 if (_return_value == NULL)
2753 goto exit;
2754 return_value = PyUnicode_DecodeFSDefault(_return_value);
2755
2756exit:
2757 return return_value;
2758}
2759
2760static char *
2761os_ttyname_impl(PyObject *self, int fd)
2762/*[clinic checksum: ea680155d87bb733f542d67653eca732dd0981a8]*/
2763{
2764 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002765
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002766#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002767 /* file descriptor 0 only, the default input device (stdin) */
Larry Hastings31826802013-10-19 00:09:25 -07002768 if (fd == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 ret = ttyname();
2770 }
2771 else {
2772 ret = NULL;
2773 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002774#else
Larry Hastings31826802013-10-19 00:09:25 -07002775 ret = ttyname(fd);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002776#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002778 posix_error();
2779 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002780}
Larry Hastings31826802013-10-19 00:09:25 -07002781#else
2782#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002783#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002784
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002785#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002787"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002789
2790static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002791posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002792{
Victor Stinner8c62be82010-05-06 00:08:46 +00002793 char *ret;
2794 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002795
Greg Wardb48bc172000-03-01 21:51:56 +00002796#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002798#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002800#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 if (ret == NULL)
2802 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002803 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002804}
2805#endif
2806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002807PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002808"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809Change the current working directory to the specified path.\n\
2810\n\
2811path may always be specified as a string.\n\
2812On some platforms, path may also be specified as an open file descriptor.\n\
2813 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002814
Barry Warsaw53699e91996-12-10 23:23:01 +00002815static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 path_t path;
2819 int result;
2820 PyObject *return_value = NULL;
2821 static char *keywords[] = {"path", NULL};
2822
2823 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002824 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825#ifdef HAVE_FCHDIR
2826 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002827#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2829 path_converter, &path
2830 ))
2831 return NULL;
2832
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef MS_WINDOWS
2835 if (path.wide)
2836 result = win32_wchdir(path.wide);
2837 else
2838 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002839 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840#else
2841#ifdef HAVE_FCHDIR
2842 if (path.fd != -1)
2843 result = fchdir(path.fd);
2844 else
2845#endif
2846 result = chdir(path.narrow);
2847#endif
2848 Py_END_ALLOW_THREADS
2849
2850 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002851 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 goto exit;
2853 }
2854
2855 return_value = Py_None;
2856 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002857
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858exit:
2859 path_cleanup(&path);
2860 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002861}
2862
Fred Drake4d1e64b2002-04-15 19:40:07 +00002863#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002864PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865"fchdir(fd)\n\n\
2866Change to the directory of the given file descriptor. fd must be\n\
2867opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002868
2869static PyObject *
2870posix_fchdir(PyObject *self, PyObject *fdobj)
2871{
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002873}
2874#endif /* HAVE_FCHDIR */
2875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2879Change the access permissions of a file.\n\
2880\n\
2881path may always be specified as a string.\n\
2882On some platforms, path may also be specified as an open file descriptor.\n\
2883 If this functionality is unavailable, using it raises an exception.\n\
2884If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2885 and path should be relative; path will then be relative to that directory.\n\
2886If follow_symlinks is False, and the last element of the path is a symbolic\n\
2887 link, chmod will modify the symbolic link itself instead of the file the\n\
2888 link points to.\n\
2889It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2890 an open file descriptor.\n\
2891dir_fd and follow_symlinks may not be implemented on your platform.\n\
2892 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Barry Warsaw53699e91996-12-10 23:23:01 +00002894static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002896{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 path_t path;
2898 int mode;
2899 int dir_fd = DEFAULT_DIR_FD;
2900 int follow_symlinks = 1;
2901 int result;
2902 PyObject *return_value = NULL;
2903 static char *keywords[] = {"path", "mode", "dir_fd",
2904 "follow_symlinks", NULL};
2905
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002906#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002909
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910#ifdef HAVE_FCHMODAT
2911 int fchmodat_nofollow_unsupported = 0;
2912#endif
2913
2914 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002915 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916#ifdef HAVE_FCHMOD
2917 path.allow_fd = 1;
2918#endif
2919 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2920 path_converter, &path,
2921 &mode,
2922#ifdef HAVE_FCHMODAT
2923 dir_fd_converter, &dir_fd,
2924#else
2925 dir_fd_unavailable, &dir_fd,
2926#endif
2927 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929
2930#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2931 if (follow_symlinks_specified("chmod", follow_symlinks))
2932 goto exit;
2933#endif
2934
2935#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937 if (path.wide)
2938 attr = GetFileAttributesW(path.wide);
2939 else
2940 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002941 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942 result = 0;
2943 else {
2944 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002945 attr &= ~FILE_ATTRIBUTE_READONLY;
2946 else
2947 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948 if (path.wide)
2949 result = SetFileAttributesW(path.wide, attr);
2950 else
2951 result = SetFileAttributesA(path.narrow, attr);
2952 }
2953 Py_END_ALLOW_THREADS
2954
2955 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002956 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957 goto exit;
2958 }
2959#else /* MS_WINDOWS */
2960 Py_BEGIN_ALLOW_THREADS
2961#ifdef HAVE_FCHMOD
2962 if (path.fd != -1)
2963 result = fchmod(path.fd, mode);
2964 else
2965#endif
2966#ifdef HAVE_LCHMOD
2967 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2968 result = lchmod(path.narrow, mode);
2969 else
2970#endif
2971#ifdef HAVE_FCHMODAT
2972 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2973 /*
2974 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2975 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002976 * and then says it isn't implemented yet.
2977 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978 *
2979 * Once it is supported, os.chmod will automatically
2980 * support dir_fd and follow_symlinks=False. (Hopefully.)
2981 * Until then, we need to be careful what exception we raise.
2982 */
2983 result = fchmodat(dir_fd, path.narrow, mode,
2984 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2985 /*
2986 * But wait! We can't throw the exception without allowing threads,
2987 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2988 */
2989 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002990 result &&
2991 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2992 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 }
2994 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002995#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996 result = chmod(path.narrow, mode);
2997 Py_END_ALLOW_THREADS
2998
2999 if (result) {
3000#ifdef HAVE_FCHMODAT
3001 if (fchmodat_nofollow_unsupported) {
3002 if (dir_fd != DEFAULT_DIR_FD)
3003 dir_fd_and_follow_symlinks_invalid("chmod",
3004 dir_fd, follow_symlinks);
3005 else
3006 follow_symlinks_specified("chmod", follow_symlinks);
3007 }
3008 else
3009#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003010 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003011 goto exit;
3012 }
3013#endif
3014
3015 Py_INCREF(Py_None);
3016 return_value = Py_None;
3017exit:
3018 path_cleanup(&path);
3019 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003020}
3021
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022
Christian Heimes4e30a842007-11-30 22:12:06 +00003023#ifdef HAVE_FCHMOD
3024PyDoc_STRVAR(posix_fchmod__doc__,
3025"fchmod(fd, mode)\n\n\
3026Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003028
3029static PyObject *
3030posix_fchmod(PyObject *self, PyObject *args)
3031{
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 int fd, mode, res;
3033 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3034 return NULL;
3035 Py_BEGIN_ALLOW_THREADS
3036 res = fchmod(fd, mode);
3037 Py_END_ALLOW_THREADS
3038 if (res < 0)
3039 return posix_error();
3040 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003041}
3042#endif /* HAVE_FCHMOD */
3043
3044#ifdef HAVE_LCHMOD
3045PyDoc_STRVAR(posix_lchmod__doc__,
3046"lchmod(path, mode)\n\n\
3047Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003048affects the link itself rather than the target.\n\
3049Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003050
3051static PyObject *
3052posix_lchmod(PyObject *self, PyObject *args)
3053{
Victor Stinner292c8352012-10-30 02:17:38 +01003054 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 int i;
3056 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003057 memset(&path, 0, sizeof(path));
3058 path.function_name = "lchmod";
3059 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3060 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003062 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003063 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003065 if (res < 0) {
3066 path_error(&path);
3067 path_cleanup(&path);
3068 return NULL;
3069 }
3070 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003071 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003072}
3073#endif /* HAVE_LCHMOD */
3074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
Thomas Wouterscf297e42007-02-23 15:07:44 +00003076#ifdef HAVE_CHFLAGS
3077PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078"chflags(path, flags, *, follow_symlinks=True)\n\n\
3079Set file flags.\n\
3080\n\
3081If follow_symlinks is False, and the last element of the path is a symbolic\n\
3082 link, chflags will change flags on the symbolic link itself instead of the\n\
3083 file the link points to.\n\
3084follow_symlinks may not be implemented on your platform. If it is\n\
3085unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003086
3087static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003089{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 int follow_symlinks = 1;
3093 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003094 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3096
3097 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003098 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003099 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3100 path_converter, &path,
3101 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003102 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103
3104#ifndef HAVE_LCHFLAGS
3105 if (follow_symlinks_specified("chflags", follow_symlinks))
3106 goto exit;
3107#endif
3108
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110#ifdef HAVE_LCHFLAGS
3111 if (!follow_symlinks)
3112 result = lchflags(path.narrow, flags);
3113 else
3114#endif
3115 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117
3118 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003119 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120 goto exit;
3121 }
3122
3123 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003125
3126exit:
3127 path_cleanup(&path);
3128 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003129}
3130#endif /* HAVE_CHFLAGS */
3131
3132#ifdef HAVE_LCHFLAGS
3133PyDoc_STRVAR(posix_lchflags__doc__,
3134"lchflags(path, flags)\n\n\
3135Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136This function will not follow symbolic links.\n\
3137Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003138
3139static PyObject *
3140posix_lchflags(PyObject *self, PyObject *args)
3141{
Victor Stinner292c8352012-10-30 02:17:38 +01003142 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 unsigned long flags;
3144 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003145 memset(&path, 0, sizeof(path));
3146 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003148 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003150 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003151 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003153 if (res < 0) {
3154 path_error(&path);
3155 path_cleanup(&path);
3156 return NULL;
3157 }
3158 path_cleanup(&path);
3159 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003160}
3161#endif /* HAVE_LCHFLAGS */
3162
Martin v. Löwis244edc82001-10-04 22:44:26 +00003163#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003164PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003165"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003166Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003167
3168static PyObject *
3169posix_chroot(PyObject *self, PyObject *args)
3170{
Victor Stinner292c8352012-10-30 02:17:38 +01003171 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003172}
3173#endif
3174
Guido van Rossum21142a01999-01-08 21:05:37 +00003175#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003179
3180static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003181posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003182{
Stefan Krah0e803b32010-11-26 16:16:47 +00003183 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003184}
3185#endif /* HAVE_FSYNC */
3186
Ross Lagerwall7807c352011-03-17 20:20:30 +02003187#ifdef HAVE_SYNC
3188PyDoc_STRVAR(posix_sync__doc__,
3189"sync()\n\n\
3190Force write of everything to disk.");
3191
3192static PyObject *
3193posix_sync(PyObject *self, PyObject *noargs)
3194{
3195 Py_BEGIN_ALLOW_THREADS
3196 sync();
3197 Py_END_ALLOW_THREADS
3198 Py_RETURN_NONE;
3199}
3200#endif
3201
Guido van Rossum21142a01999-01-08 21:05:37 +00003202#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003203
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003204#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003205extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3206#endif
3207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003210force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003211 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003212
3213static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003214posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003215{
Stefan Krah0e803b32010-11-26 16:16:47 +00003216 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003217}
3218#endif /* HAVE_FDATASYNC */
3219
3220
Fredrik Lundh10723342000-07-10 16:38:09 +00003221#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003222PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3224Change the owner and group id of path to the numeric uid and gid.\n\
3225\n\
3226path may always be specified as a string.\n\
3227On some platforms, path may also be specified as an open file descriptor.\n\
3228 If this functionality is unavailable, using it raises an exception.\n\
3229If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3230 and path should be relative; path will then be relative to that directory.\n\
3231If follow_symlinks is False, and the last element of the path is a symbolic\n\
3232 link, chown will modify the symbolic link itself instead of the file the\n\
3233 link points to.\n\
3234It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3235 an open file descriptor.\n\
3236dir_fd and follow_symlinks may not be implemented on your platform.\n\
3237 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
Barry Warsaw53699e91996-12-10 23:23:01 +00003239static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003241{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243 uid_t uid;
3244 gid_t gid;
3245 int dir_fd = DEFAULT_DIR_FD;
3246 int follow_symlinks = 1;
3247 int result;
3248 PyObject *return_value = NULL;
3249 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3250 "follow_symlinks", NULL};
3251
3252 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003253 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254#ifdef HAVE_FCHOWN
3255 path.allow_fd = 1;
3256#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003257 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003259 _Py_Uid_Converter, &uid,
3260 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261#ifdef HAVE_FCHOWNAT
3262 dir_fd_converter, &dir_fd,
3263#else
3264 dir_fd_unavailable, &dir_fd,
3265#endif
3266 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268
3269#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3270 if (follow_symlinks_specified("chown", follow_symlinks))
3271 goto exit;
3272#endif
3273 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3274 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3275 goto exit;
3276
3277#ifdef __APPLE__
3278 /*
3279 * This is for Mac OS X 10.3, which doesn't have lchown.
3280 * (But we still have an lchown symbol because of weak-linking.)
3281 * It doesn't have fchownat either. So there's no possibility
3282 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003283 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003284 if ((!follow_symlinks) && (lchown == NULL)) {
3285 follow_symlinks_specified("chown", follow_symlinks);
3286 goto exit;
3287 }
3288#endif
3289
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291#ifdef HAVE_FCHOWN
3292 if (path.fd != -1)
3293 result = fchown(path.fd, uid, gid);
3294 else
3295#endif
3296#ifdef HAVE_LCHOWN
3297 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3298 result = lchown(path.narrow, uid, gid);
3299 else
3300#endif
3301#ifdef HAVE_FCHOWNAT
3302 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3303 result = fchownat(dir_fd, path.narrow, uid, gid,
3304 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3305 else
3306#endif
3307 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003309
3310 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003311 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312 goto exit;
3313 }
3314
3315 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317
3318exit:
3319 path_cleanup(&path);
3320 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003321}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003322#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003323
Christian Heimes4e30a842007-11-30 22:12:06 +00003324#ifdef HAVE_FCHOWN
3325PyDoc_STRVAR(posix_fchown__doc__,
3326"fchown(fd, uid, gid)\n\n\
3327Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003329
3330static PyObject *
3331posix_fchown(PyObject *self, PyObject *args)
3332{
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003334 uid_t uid;
3335 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003337 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3338 _Py_Uid_Converter, &uid,
3339 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return NULL;
3341 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003342 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 Py_END_ALLOW_THREADS
3344 if (res < 0)
3345 return posix_error();
3346 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003347}
3348#endif /* HAVE_FCHOWN */
3349
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003350#ifdef HAVE_LCHOWN
3351PyDoc_STRVAR(posix_lchown__doc__,
3352"lchown(path, uid, gid)\n\n\
3353Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354This function will not follow symbolic links.\n\
3355Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003356
3357static PyObject *
3358posix_lchown(PyObject *self, PyObject *args)
3359{
Victor Stinner292c8352012-10-30 02:17:38 +01003360 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003361 uid_t uid;
3362 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003364 memset(&path, 0, sizeof(path));
3365 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003366 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003367 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003368 _Py_Uid_Converter, &uid,
3369 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003372 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003374 if (res < 0) {
3375 path_error(&path);
3376 path_cleanup(&path);
3377 return NULL;
3378 }
3379 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 Py_INCREF(Py_None);
3381 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003382}
3383#endif /* HAVE_LCHOWN */
3384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003385
Barry Warsaw53699e91996-12-10 23:23:01 +00003386static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003387posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003388{
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 char buf[1026];
3390 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003391
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003392#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003393 if (!use_bytes) {
3394 wchar_t wbuf[1026];
3395 wchar_t *wbuf2 = wbuf;
3396 PyObject *resobj;
3397 DWORD len;
3398 Py_BEGIN_ALLOW_THREADS
3399 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3400 /* If the buffer is large enough, len does not include the
3401 terminating \0. If the buffer is too small, len includes
3402 the space needed for the terminator. */
3403 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003404 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 if (wbuf2)
3406 len = GetCurrentDirectoryW(len, wbuf2);
3407 }
3408 Py_END_ALLOW_THREADS
3409 if (!wbuf2) {
3410 PyErr_NoMemory();
3411 return NULL;
3412 }
3413 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003414 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003415 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003416 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 }
3418 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003419 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003420 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 return resobj;
3422 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003423
3424 if (win32_warn_bytes_api())
3425 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003426#endif
3427
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 Py_END_ALLOW_THREADS
3431 if (res == NULL)
3432 return posix_error();
3433 if (use_bytes)
3434 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003435 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003436}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003437
3438PyDoc_STRVAR(posix_getcwd__doc__,
3439"getcwd() -> path\n\n\
3440Return a unicode string representing the current working directory.");
3441
3442static PyObject *
3443posix_getcwd_unicode(PyObject *self)
3444{
3445 return posix_getcwd(0);
3446}
3447
3448PyDoc_STRVAR(posix_getcwdb__doc__,
3449"getcwdb() -> path\n\n\
3450Return a bytes string representing the current working directory.");
3451
3452static PyObject *
3453posix_getcwd_bytes(PyObject *self)
3454{
3455 return posix_getcwd(1);
3456}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003457
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3459#define HAVE_LINK 1
3460#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003461
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003463PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3465Create a hard link to a file.\n\
3466\n\
3467If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3468 descriptor open to a directory, and the respective path string (src or dst)\n\
3469 should be relative; the path will then be relative to that directory.\n\
3470If follow_symlinks is False, and the last element of src is a symbolic\n\
3471 link, link will create a link to the symbolic link itself instead of the\n\
3472 file the link points to.\n\
3473src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3474 platform. If they are unavailable, using them will raise a\n\
3475 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Barry Warsaw53699e91996-12-10 23:23:01 +00003477static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003479{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 path_t src, dst;
3481 int src_dir_fd = DEFAULT_DIR_FD;
3482 int dst_dir_fd = DEFAULT_DIR_FD;
3483 int follow_symlinks = 1;
3484 PyObject *return_value = NULL;
3485 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3486 "follow_symlinks", NULL};
3487#ifdef MS_WINDOWS
3488 BOOL result;
3489#else
3490 int result;
3491#endif
3492
3493 memset(&src, 0, sizeof(src));
3494 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003495 src.function_name = "link";
3496 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3498 path_converter, &src,
3499 path_converter, &dst,
3500 dir_fd_converter, &src_dir_fd,
3501 dir_fd_converter, &dst_dir_fd,
3502 &follow_symlinks))
3503 return NULL;
3504
3505#ifndef HAVE_LINKAT
3506 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3507 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3508 goto exit;
3509 }
3510#endif
3511
3512 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3513 PyErr_SetString(PyExc_NotImplementedError,
3514 "link: src and dst must be the same type");
3515 goto exit;
3516 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003517
Brian Curtin1b9df392010-11-24 20:24:31 +00003518#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_BEGIN_ALLOW_THREADS
3520 if (src.wide)
3521 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3522 else
3523 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3524 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003525
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003527 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003529 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530#else
3531 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003532#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3534 (dst_dir_fd != DEFAULT_DIR_FD) ||
3535 (!follow_symlinks))
3536 result = linkat(src_dir_fd, src.narrow,
3537 dst_dir_fd, dst.narrow,
3538 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3539 else
3540#endif
3541 result = link(src.narrow, dst.narrow);
3542 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003543
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003545 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003547 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548#endif
3549
3550 return_value = Py_None;
3551 Py_INCREF(Py_None);
3552
3553exit:
3554 path_cleanup(&src);
3555 path_cleanup(&dst);
3556 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003557}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558#endif
3559
Brian Curtin1b9df392010-11-24 20:24:31 +00003560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003562PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003563"listdir(path='.') -> list_of_filenames\n\n\
3564Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003565The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566entries '.' and '..' even if they are present in the directory.\n\
3567\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003568path can be specified as either str or bytes. If path is bytes,\n\
3569 the filenames returned will also be bytes; in all other circumstances\n\
3570 the filenames returned will be str.\n\
3571On some platforms, path may also be specified as an open file descriptor;\n\
3572 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003574
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003575#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003576static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003577_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 PyObject *v;
3581 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3582 BOOL result;
3583 WIN32_FIND_DATA FileData;
3584 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3585 char *bufptr = namebuf;
3586 /* only claim to have space for MAX_PATH */
3587 Py_ssize_t len = sizeof(namebuf)-5;
3588 PyObject *po = NULL;
3589 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003594
Gregory P. Smith40a21602013-03-20 20:52:50 -07003595 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003596 po_wchars = L".";
3597 len = 1;
3598 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003599 po_wchars = path->wide;
3600 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003601 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003603 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 if (!wnamebuf) {
3605 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003608 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003611 if (wch != SEP && wch != ALTSEP && wch != L':')
3612 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 wcscpy(wnamebuf + len, L"*.*");
3614 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 if ((list = PyList_New(0)) == NULL) {
3616 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003618 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003620 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 if (hFindFile == INVALID_HANDLE_VALUE) {
3622 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 if (error == ERROR_FILE_NOT_FOUND)
3624 goto exit;
3625 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 }
3629 do {
3630 /* Skip over . and .. */
3631 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3632 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 v = PyUnicode_FromWideChar(wFileData.cFileName,
3634 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 Py_DECREF(list);
3637 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 break;
3639 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 Py_DECREF(list);
3643 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 break;
3645 }
3646 Py_DECREF(v);
3647 }
3648 Py_BEGIN_ALLOW_THREADS
3649 result = FindNextFileW(hFindFile, &wFileData);
3650 Py_END_ALLOW_THREADS
3651 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3652 it got to the end of the directory. */
3653 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003655 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 }
3658 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003659
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003662 strcpy(namebuf, path->narrow);
3663 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 if (len > 0) {
3665 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003666 if (ch != '\\' && ch != '/' && ch != ':')
3667 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 strcpy(namebuf + len, "*.*");
3669 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003670
Larry Hastings9cf065c2012-06-22 16:30:09 -07003671 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003673
Antoine Pitroub73caab2010-08-09 23:39:31 +00003674 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003676 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (hFindFile == INVALID_HANDLE_VALUE) {
3678 int error = GetLastError();
3679 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 goto exit;
3681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 do {
3686 /* Skip over . and .. */
3687 if (strcmp(FileData.cFileName, ".") != 0 &&
3688 strcmp(FileData.cFileName, "..") != 0) {
3689 v = PyBytes_FromString(FileData.cFileName);
3690 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 Py_DECREF(list);
3692 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 break;
3694 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 Py_DECREF(list);
3698 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 break;
3700 }
3701 Py_DECREF(v);
3702 }
3703 Py_BEGIN_ALLOW_THREADS
3704 result = FindNextFile(hFindFile, &FileData);
3705 Py_END_ALLOW_THREADS
3706 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3707 it got to the end of the directory. */
3708 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003710 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 }
3713 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003714
Larry Hastings9cf065c2012-06-22 16:30:09 -07003715exit:
3716 if (hFindFile != INVALID_HANDLE_VALUE) {
3717 if (FindClose(hFindFile) == FALSE) {
3718 if (list != NULL) {
3719 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003720 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 }
3722 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003724 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003725
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003727} /* end of _listdir_windows_no_opendir */
3728
3729#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3730
3731static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003732_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003733{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003734 PyObject *v;
3735 DIR *dirp = NULL;
3736 struct dirent *ep;
3737 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003738#ifdef HAVE_FDOPENDIR
3739 int fd = -1;
3740#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003741
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003744 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003746 fd = _Py_dup(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 if (fd == -1) {
3748 list = posix_error();
3749 goto exit;
3750 }
3751
Larry Hastingsfdaea062012-06-25 04:42:23 -07003752 return_str = 1;
3753
Larry Hastings9cf065c2012-06-22 16:30:09 -07003754 Py_BEGIN_ALLOW_THREADS
3755 dirp = fdopendir(fd);
3756 Py_END_ALLOW_THREADS
3757 }
3758 else
3759#endif
3760 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003761 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003762 if (path->narrow) {
3763 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003764 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003765 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003766 }
3767 else {
3768 name = ".";
3769 return_str = 1;
3770 }
3771
Larry Hastings9cf065c2012-06-22 16:30:09 -07003772 Py_BEGIN_ALLOW_THREADS
3773 dirp = opendir(name);
3774 Py_END_ALLOW_THREADS
3775 }
3776
3777 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003778 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003779#ifdef HAVE_FDOPENDIR
3780 if (fd != -1) {
3781 Py_BEGIN_ALLOW_THREADS
3782 close(fd);
3783 Py_END_ALLOW_THREADS
3784 }
3785#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003786 goto exit;
3787 }
3788 if ((list = PyList_New(0)) == NULL) {
3789 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 }
3791 for (;;) {
3792 errno = 0;
3793 Py_BEGIN_ALLOW_THREADS
3794 ep = readdir(dirp);
3795 Py_END_ALLOW_THREADS
3796 if (ep == NULL) {
3797 if (errno == 0) {
3798 break;
3799 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003801 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003803 }
3804 }
3805 if (ep->d_name[0] == '.' &&
3806 (NAMLEN(ep) == 1 ||
3807 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3808 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003809 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003810 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3811 else
3812 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003814 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 break;
3816 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003817 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003819 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 break;
3821 }
3822 Py_DECREF(v);
3823 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003824
Larry Hastings9cf065c2012-06-22 16:30:09 -07003825exit:
3826 if (dirp != NULL) {
3827 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003828#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829 if (fd > -1)
3830 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003831#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 closedir(dirp);
3833 Py_END_ALLOW_THREADS
3834 }
3835
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003837} /* end of _posix_listdir */
3838#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003839
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003840static PyObject *
3841posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3842{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003843 path_t path;
3844 PyObject *list = NULL;
3845 static char *keywords[] = {"path", NULL};
3846 PyObject *return_value;
3847
3848 memset(&path, 0, sizeof(path));
3849 path.function_name = "listdir";
3850 path.nullable = 1;
3851#ifdef HAVE_FDOPENDIR
3852 path.allow_fd = 1;
3853 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003854#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003855
3856 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3857 path_converter, &path)) {
3858 return NULL;
3859 }
3860
3861#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3862 return_value = _listdir_windows_no_opendir(&path, list);
3863#else
3864 return_value = _posix_listdir(&path, list);
3865#endif
3866 path_cleanup(&path);
3867 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003868}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003869
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003870#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003871/* A helper function for abspath on win32 */
3872static PyObject *
3873posix__getfullpathname(PyObject *self, PyObject *args)
3874{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003875 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 char outbuf[MAX_PATH*2];
3877 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003878 PyObject *po;
3879
3880 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3881 {
3882 wchar_t *wpath;
3883 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3884 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 DWORD result;
3886 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003887
3888 wpath = PyUnicode_AsUnicode(po);
3889 if (wpath == NULL)
3890 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003892 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003894 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003895 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (!woutbufp)
3897 return PyErr_NoMemory();
3898 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3899 }
3900 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003901 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003903 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003904 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003905 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 return v;
3907 }
3908 /* Drop the argument parsing error as narrow strings
3909 are also valid. */
3910 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003911
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003912 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3913 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003915 if (win32_warn_bytes_api())
3916 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003917 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 outbuf, &temp)) {
3919 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 return NULL;
3921 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3923 return PyUnicode_Decode(outbuf, strlen(outbuf),
3924 Py_FileSystemDefaultEncoding, NULL);
3925 }
3926 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003927} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003928
Brian Curtind25aef52011-06-13 15:16:04 -05003929
Brian Curtinf5e76d02010-11-24 13:14:05 +00003930
Brian Curtind40e6f72010-07-08 21:39:08 +00003931/* A helper function for samepath on windows */
3932static PyObject *
3933posix__getfinalpathname(PyObject *self, PyObject *args)
3934{
3935 HANDLE hFile;
3936 int buf_size;
3937 wchar_t *target_path;
3938 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003939 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003940 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003941
Victor Stinnereb5657a2011-09-30 01:44:27 +02003942 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003943 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003944 path = PyUnicode_AsUnicode(po);
3945 if (path == NULL)
3946 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003947
3948 if(!check_GetFinalPathNameByHandle()) {
3949 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3950 NotImplementedError. */
3951 return PyErr_Format(PyExc_NotImplementedError,
3952 "GetFinalPathNameByHandle not available on this platform");
3953 }
3954
3955 hFile = CreateFileW(
3956 path,
3957 0, /* desired access */
3958 0, /* share mode */
3959 NULL, /* security attributes */
3960 OPEN_EXISTING,
3961 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3962 FILE_FLAG_BACKUP_SEMANTICS,
3963 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003964
Victor Stinnereb5657a2011-09-30 01:44:27 +02003965 if(hFile == INVALID_HANDLE_VALUE)
3966 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003967
3968 /* We have a good handle to the target, use it to determine the
3969 target path name. */
3970 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3971
3972 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003973 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003974
Victor Stinnerb6404912013-07-07 16:21:41 +02003975 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003976 if(!target_path)
3977 return PyErr_NoMemory();
3978
3979 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3980 buf_size, VOLUME_NAME_DOS);
3981 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003982 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003983
3984 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003985 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003986
3987 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003988 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003989 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003990 return result;
3991
3992} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003993
Brian Curtin95d028f2011-06-09 09:10:38 -05003994PyDoc_STRVAR(posix__isdir__doc__,
3995"Return true if the pathname refers to an existing directory.");
3996
Brian Curtin9c669cc2011-06-08 18:17:18 -05003997static PyObject *
3998posix__isdir(PyObject *self, PyObject *args)
3999{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004000 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004001 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004002 DWORD attributes;
4003
4004 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004005 wchar_t *wpath = PyUnicode_AsUnicode(po);
4006 if (wpath == NULL)
4007 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004008
4009 attributes = GetFileAttributesW(wpath);
4010 if (attributes == INVALID_FILE_ATTRIBUTES)
4011 Py_RETURN_FALSE;
4012 goto check;
4013 }
4014 /* Drop the argument parsing error as narrow strings
4015 are also valid. */
4016 PyErr_Clear();
4017
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004018 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004019 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004020 if (win32_warn_bytes_api())
4021 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004022 attributes = GetFileAttributesA(path);
4023 if (attributes == INVALID_FILE_ATTRIBUTES)
4024 Py_RETURN_FALSE;
4025
4026check:
4027 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4028 Py_RETURN_TRUE;
4029 else
4030 Py_RETURN_FALSE;
4031}
Tim Golden6b528062013-08-01 12:44:00 +01004032
4033PyDoc_STRVAR(posix__getvolumepathname__doc__,
4034"Return volume mount point of the specified path.");
4035
4036/* A helper function for ismount on windows */
4037static PyObject *
4038posix__getvolumepathname(PyObject *self, PyObject *args)
4039{
4040 PyObject *po, *result;
4041 wchar_t *path, *mountpath=NULL;
4042 size_t bufsize;
4043 BOOL ret;
4044
4045 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4046 return NULL;
4047 path = PyUnicode_AsUnicode(po);
4048 if (path == NULL)
4049 return NULL;
4050
4051 /* Volume path should be shorter than entire path */
4052 bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
4053 mountpath = (wchar_t *)PyMem_Malloc(bufsize);
4054 if (mountpath == NULL)
4055 return PyErr_NoMemory();
4056
4057 Py_BEGIN_ALLOW_THREADS
4058 ret = GetVolumePathNameW(path, mountpath, bufsize);
4059 Py_END_ALLOW_THREADS
4060
4061 if (!ret) {
4062 result = win32_error_object("_getvolumepathname", po);
4063 goto exit;
4064 }
4065 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4066
4067exit:
4068 PyMem_Free(mountpath);
4069 return result;
4070}
4071/* end of posix__getvolumepathname */
4072
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004073#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4077Create a directory.\n\
4078\n\
4079If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4080 and path should be relative; path will then be relative to that directory.\n\
4081dir_fd may not be implemented on your platform.\n\
4082 If it is unavailable, using it will raise a NotImplementedError.\n\
4083\n\
4084The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Barry Warsaw53699e91996-12-10 23:23:01 +00004086static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004088{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004090 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 int dir_fd = DEFAULT_DIR_FD;
4092 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4093 PyObject *return_value = NULL;
4094 int result;
4095
4096 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004097 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4099 path_converter, &path, &mode,
4100#ifdef HAVE_MKDIRAT
4101 dir_fd_converter, &dir_fd
4102#else
4103 dir_fd_unavailable, &dir_fd
4104#endif
4105 ))
4106 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004107
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004108#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004110 if (path.wide)
4111 result = CreateDirectoryW(path.wide, NULL);
4112 else
4113 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004115
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004117 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 goto exit;
4119 }
4120#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004121 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122#if HAVE_MKDIRAT
4123 if (dir_fd != DEFAULT_DIR_FD)
4124 result = mkdirat(dir_fd, path.narrow, mode);
4125 else
4126#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004127#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004129#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004132 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004134 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 goto exit;
4136 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138 return_value = Py_None;
4139 Py_INCREF(Py_None);
4140exit:
4141 path_cleanup(&path);
4142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143}
4144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004146/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4147#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004148#include <sys/resource.h>
4149#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004150
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004151
4152#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004153PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004154"nice(inc) -> new_priority\n\n\
4155Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004156
Barry Warsaw53699e91996-12-10 23:23:01 +00004157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004158posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004159{
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004161
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4163 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004164
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 /* There are two flavours of 'nice': one that returns the new
4166 priority (as required by almost all standards out there) and the
4167 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4168 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 If we are of the nice family that returns the new priority, we
4171 need to clear errno before the call, and check if errno is filled
4172 before calling posix_error() on a returnvalue of -1, because the
4173 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004174
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 errno = 0;
4176 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004177#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 if (value == 0)
4179 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004180#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004181 if (value == -1 && errno != 0)
4182 /* either nice() or getpriority() returned an error */
4183 return posix_error();
4184 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004185}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004186#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004187
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004188
4189#ifdef HAVE_GETPRIORITY
4190PyDoc_STRVAR(posix_getpriority__doc__,
4191"getpriority(which, who) -> current_priority\n\n\
4192Get program scheduling priority.");
4193
4194static PyObject *
4195posix_getpriority(PyObject *self, PyObject *args)
4196{
4197 int which, who, retval;
4198
4199 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4200 return NULL;
4201 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004202 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004203 if (errno != 0)
4204 return posix_error();
4205 return PyLong_FromLong((long)retval);
4206}
4207#endif /* HAVE_GETPRIORITY */
4208
4209
4210#ifdef HAVE_SETPRIORITY
4211PyDoc_STRVAR(posix_setpriority__doc__,
4212"setpriority(which, who, prio) -> None\n\n\
4213Set program scheduling priority.");
4214
4215static PyObject *
4216posix_setpriority(PyObject *self, PyObject *args)
4217{
4218 int which, who, prio, retval;
4219
4220 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4221 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004222 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004223 if (retval == -1)
4224 return posix_error();
4225 Py_RETURN_NONE;
4226}
4227#endif /* HAVE_SETPRIORITY */
4228
4229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004232{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233 char *function_name = is_replace ? "replace" : "rename";
4234 path_t src;
4235 path_t dst;
4236 int src_dir_fd = DEFAULT_DIR_FD;
4237 int dst_dir_fd = DEFAULT_DIR_FD;
4238 int dir_fd_specified;
4239 PyObject *return_value = NULL;
4240 char format[24];
4241 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4242
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004243#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004245 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004246#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004247 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004248#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004249
4250 memset(&src, 0, sizeof(src));
4251 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004252 src.function_name = function_name;
4253 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 strcpy(format, "O&O&|$O&O&:");
4255 strcat(format, function_name);
4256 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4257 path_converter, &src,
4258 path_converter, &dst,
4259 dir_fd_converter, &src_dir_fd,
4260 dir_fd_converter, &dst_dir_fd))
4261 return NULL;
4262
4263 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4264 (dst_dir_fd != DEFAULT_DIR_FD);
4265#ifndef HAVE_RENAMEAT
4266 if (dir_fd_specified) {
4267 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4268 goto exit;
4269 }
4270#endif
4271
4272 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4273 PyErr_Format(PyExc_ValueError,
4274 "%s: src and dst must be the same type", function_name);
4275 goto exit;
4276 }
4277
4278#ifdef MS_WINDOWS
4279 Py_BEGIN_ALLOW_THREADS
4280 if (src.wide)
4281 result = MoveFileExW(src.wide, dst.wide, flags);
4282 else
4283 result = MoveFileExA(src.narrow, dst.narrow, flags);
4284 Py_END_ALLOW_THREADS
4285
4286 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004287 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288 goto exit;
4289 }
4290
4291#else
4292 Py_BEGIN_ALLOW_THREADS
4293#ifdef HAVE_RENAMEAT
4294 if (dir_fd_specified)
4295 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4296 else
4297#endif
4298 result = rename(src.narrow, dst.narrow);
4299 Py_END_ALLOW_THREADS
4300
4301 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004302 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303 goto exit;
4304 }
4305#endif
4306
4307 Py_INCREF(Py_None);
4308 return_value = Py_None;
4309exit:
4310 path_cleanup(&src);
4311 path_cleanup(&dst);
4312 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004313}
4314
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004315PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4317Rename a file or directory.\n\
4318\n\
4319If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4320 descriptor open to a directory, and the respective path string (src or dst)\n\
4321 should be relative; the path will then be relative to that directory.\n\
4322src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4323 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004324
4325static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004327{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004328 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004329}
4330
4331PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4333Rename a file or directory, overwriting the destination.\n\
4334\n\
4335If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4336 descriptor open to a directory, and the respective path string (src or dst)\n\
4337 should be relative; the path will then be relative to that directory.\n\
4338src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4339 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004340
4341static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004342posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004343{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004344 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004345}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004347PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004348"rmdir(path, *, dir_fd=None)\n\n\
4349Remove a directory.\n\
4350\n\
4351If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4352 and path should be relative; path will then be relative to that directory.\n\
4353dir_fd may not be implemented on your platform.\n\
4354 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004355
Barry Warsaw53699e91996-12-10 23:23:01 +00004356static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004357posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004358{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004359 path_t path;
4360 int dir_fd = DEFAULT_DIR_FD;
4361 static char *keywords[] = {"path", "dir_fd", NULL};
4362 int result;
4363 PyObject *return_value = NULL;
4364
4365 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004366 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004367 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4368 path_converter, &path,
4369#ifdef HAVE_UNLINKAT
4370 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004371#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004372 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004373#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004374 ))
4375 return NULL;
4376
4377 Py_BEGIN_ALLOW_THREADS
4378#ifdef MS_WINDOWS
4379 if (path.wide)
4380 result = RemoveDirectoryW(path.wide);
4381 else
4382 result = RemoveDirectoryA(path.narrow);
4383 result = !result; /* Windows, success=1, UNIX, success=0 */
4384#else
4385#ifdef HAVE_UNLINKAT
4386 if (dir_fd != DEFAULT_DIR_FD)
4387 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4388 else
4389#endif
4390 result = rmdir(path.narrow);
4391#endif
4392 Py_END_ALLOW_THREADS
4393
4394 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004395 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004396 goto exit;
4397 }
4398
4399 return_value = Py_None;
4400 Py_INCREF(Py_None);
4401
4402exit:
4403 path_cleanup(&path);
4404 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004405}
4406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004408#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004409PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004410"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004411Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Barry Warsaw53699e91996-12-10 23:23:01 +00004413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004414posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415{
Victor Stinner8c62be82010-05-06 00:08:46 +00004416 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004418 wchar_t *command;
4419 if (!PyArg_ParseTuple(args, "u:system", &command))
4420 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004421
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 Py_BEGIN_ALLOW_THREADS
4423 sts = _wsystem(command);
4424 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004425#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 PyObject *command_obj;
4427 char *command;
4428 if (!PyArg_ParseTuple(args, "O&:system",
4429 PyUnicode_FSConverter, &command_obj))
4430 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004431
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 command = PyBytes_AsString(command_obj);
4433 Py_BEGIN_ALLOW_THREADS
4434 sts = system(command);
4435 Py_END_ALLOW_THREADS
4436 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004437#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004439}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004440#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004444"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
Barry Warsaw53699e91996-12-10 23:23:01 +00004447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004448posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004449{
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 int i;
4451 if (!PyArg_ParseTuple(args, "i:umask", &i))
4452 return NULL;
4453 i = (int)umask(i);
4454 if (i < 0)
4455 return posix_error();
4456 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004457}
4458
Brian Curtind40e6f72010-07-08 21:39:08 +00004459#ifdef MS_WINDOWS
4460
4461/* override the default DeleteFileW behavior so that directory
4462symlinks can be removed with this function, the same as with
4463Unix symlinks */
4464BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4465{
4466 WIN32_FILE_ATTRIBUTE_DATA info;
4467 WIN32_FIND_DATAW find_data;
4468 HANDLE find_data_handle;
4469 int is_directory = 0;
4470 int is_link = 0;
4471
4472 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4473 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004474
Brian Curtind40e6f72010-07-08 21:39:08 +00004475 /* Get WIN32_FIND_DATA structure for the path to determine if
4476 it is a symlink */
4477 if(is_directory &&
4478 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4479 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4480
4481 if(find_data_handle != INVALID_HANDLE_VALUE) {
4482 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4483 FindClose(find_data_handle);
4484 }
4485 }
4486 }
4487
4488 if (is_directory && is_link)
4489 return RemoveDirectoryW(lpFileName);
4490
4491 return DeleteFileW(lpFileName);
4492}
4493#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004495PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004496"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497Remove a file (same as remove()).\n\
4498\n\
4499If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4500 and path should be relative; path will then be relative to that directory.\n\
4501dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004502 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004503
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004505"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506Remove a file (same as unlink()).\n\
4507\n\
4508If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4509 and path should be relative; path will then be relative to that directory.\n\
4510dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004511 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Barry Warsaw53699e91996-12-10 23:23:01 +00004513static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004515{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 path_t path;
4517 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004518 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519 int result;
4520 PyObject *return_value = NULL;
4521
4522 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004523 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525 path_converter, &path,
4526#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004527 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004528#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004529 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004530#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004531 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 return NULL;
4533
4534 Py_BEGIN_ALLOW_THREADS
4535#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004536 if (path.wide)
4537 result = Py_DeleteFileW(path.wide);
4538 else
4539 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 result = !result; /* Windows, success=1, UNIX, success=0 */
4541#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542#ifdef HAVE_UNLINKAT
4543 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004544 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545 else
4546#endif /* HAVE_UNLINKAT */
4547 result = unlink(path.narrow);
4548#endif
4549 Py_END_ALLOW_THREADS
4550
4551 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004552 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 goto exit;
4554 }
4555
4556 return_value = Py_None;
4557 Py_INCREF(Py_None);
4558
4559exit:
4560 path_cleanup(&path);
4561 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004562}
4563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004565PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004566"uname() -> uname_result\n\n\
4567Return an object identifying the current operating system.\n\
4568The object behaves like a named tuple with the following fields:\n\
4569 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Larry Hastings605a62d2012-06-24 04:33:36 -07004571static PyStructSequence_Field uname_result_fields[] = {
4572 {"sysname", "operating system name"},
4573 {"nodename", "name of machine on network (implementation-defined)"},
4574 {"release", "operating system release"},
4575 {"version", "operating system version"},
4576 {"machine", "hardware identifier"},
4577 {NULL}
4578};
4579
4580PyDoc_STRVAR(uname_result__doc__,
4581"uname_result: Result from os.uname().\n\n\
4582This object may be accessed either as a tuple of\n\
4583 (sysname, nodename, release, version, machine),\n\
4584or via the attributes sysname, nodename, release, version, and machine.\n\
4585\n\
4586See os.uname for more information.");
4587
4588static PyStructSequence_Desc uname_result_desc = {
4589 "uname_result", /* name */
4590 uname_result__doc__, /* doc */
4591 uname_result_fields,
4592 5
4593};
4594
4595static PyTypeObject UnameResultType;
4596
4597
4598#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004599static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004600posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004601{
Victor Stinner8c62be82010-05-06 00:08:46 +00004602 struct utsname u;
4603 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004604 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004605
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 Py_BEGIN_ALLOW_THREADS
4607 res = uname(&u);
4608 Py_END_ALLOW_THREADS
4609 if (res < 0)
4610 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004611
4612 value = PyStructSequence_New(&UnameResultType);
4613 if (value == NULL)
4614 return NULL;
4615
4616#define SET(i, field) \
4617 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004618 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004619 if (!o) { \
4620 Py_DECREF(value); \
4621 return NULL; \
4622 } \
4623 PyStructSequence_SET_ITEM(value, i, o); \
4624 } \
4625
4626 SET(0, u.sysname);
4627 SET(1, u.nodename);
4628 SET(2, u.release);
4629 SET(3, u.version);
4630 SET(4, u.machine);
4631
4632#undef SET
4633
4634 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004636#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004637
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004638
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639PyDoc_STRVAR(posix_utime__doc__,
4640"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4641Set the access and modified time of path.\n\
4642\n\
4643path may always be specified as a string.\n\
4644On some platforms, path may also be specified as an open file descriptor.\n\
4645 If this functionality is unavailable, using it raises an exception.\n\
4646\n\
4647If times is not None, it must be a tuple (atime, mtime);\n\
4648 atime and mtime should be expressed as float seconds since the epoch.\n\
4649If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4650 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4651 since the epoch.\n\
4652If both times and ns are None, utime uses the current time.\n\
4653Specifying tuples for both times and ns is an error.\n\
4654\n\
4655If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4656 and path should be relative; path will then be relative to that directory.\n\
4657If follow_symlinks is False, and the last element of the path is a symbolic\n\
4658 link, utime will modify the symbolic link itself instead of the file the\n\
4659 link points to.\n\
4660It is an error to use dir_fd or follow_symlinks when specifying path\n\
4661 as an open file descriptor.\n\
4662dir_fd and follow_symlinks may not be available on your platform.\n\
4663 If they are unavailable, using them will raise a NotImplementedError.");
4664
4665typedef struct {
4666 int now;
4667 time_t atime_s;
4668 long atime_ns;
4669 time_t mtime_s;
4670 long mtime_ns;
4671} utime_t;
4672
4673/*
4674 * these macros assume that "utime" is a pointer to a utime_t
4675 * they also intentionally leak the declaration of a pointer named "time"
4676 */
4677#define UTIME_TO_TIMESPEC \
4678 struct timespec ts[2]; \
4679 struct timespec *time; \
4680 if (utime->now) \
4681 time = NULL; \
4682 else { \
4683 ts[0].tv_sec = utime->atime_s; \
4684 ts[0].tv_nsec = utime->atime_ns; \
4685 ts[1].tv_sec = utime->mtime_s; \
4686 ts[1].tv_nsec = utime->mtime_ns; \
4687 time = ts; \
4688 } \
4689
4690#define UTIME_TO_TIMEVAL \
4691 struct timeval tv[2]; \
4692 struct timeval *time; \
4693 if (utime->now) \
4694 time = NULL; \
4695 else { \
4696 tv[0].tv_sec = utime->atime_s; \
4697 tv[0].tv_usec = utime->atime_ns / 1000; \
4698 tv[1].tv_sec = utime->mtime_s; \
4699 tv[1].tv_usec = utime->mtime_ns / 1000; \
4700 time = tv; \
4701 } \
4702
4703#define UTIME_TO_UTIMBUF \
4704 struct utimbuf u[2]; \
4705 struct utimbuf *time; \
4706 if (utime->now) \
4707 time = NULL; \
4708 else { \
4709 u.actime = utime->atime_s; \
4710 u.modtime = utime->mtime_s; \
4711 time = u; \
4712 }
4713
4714#define UTIME_TO_TIME_T \
4715 time_t timet[2]; \
4716 struct timet time; \
4717 if (utime->now) \
4718 time = NULL; \
4719 else { \
4720 timet[0] = utime->atime_s; \
4721 timet[1] = utime->mtime_s; \
4722 time = &timet; \
4723 } \
4724
4725
4726#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4727
4728#if UTIME_HAVE_DIR_FD
4729
4730static int
4731utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4732{
4733#ifdef HAVE_UTIMENSAT
4734 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4735 UTIME_TO_TIMESPEC;
4736 return utimensat(dir_fd, path, time, flags);
4737#elif defined(HAVE_FUTIMESAT)
4738 UTIME_TO_TIMEVAL;
4739 /*
4740 * follow_symlinks will never be false here;
4741 * we only allow !follow_symlinks and dir_fd together
4742 * if we have utimensat()
4743 */
4744 assert(follow_symlinks);
4745 return futimesat(dir_fd, path, time);
4746#endif
4747}
4748
4749#endif
4750
4751#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4752
4753#if UTIME_HAVE_FD
4754
4755static int
4756utime_fd(utime_t *utime, int fd)
4757{
4758#ifdef HAVE_FUTIMENS
4759 UTIME_TO_TIMESPEC;
4760 return futimens(fd, time);
4761#else
4762 UTIME_TO_TIMEVAL;
4763 return futimes(fd, time);
4764#endif
4765}
4766
4767#endif
4768
4769
4770#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4771 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4772
4773#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4774
4775static int
4776utime_nofollow_symlinks(utime_t *utime, char *path)
4777{
4778#ifdef HAVE_UTIMENSAT
4779 UTIME_TO_TIMESPEC;
4780 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4781#else
4782 UTIME_TO_TIMEVAL;
4783 return lutimes(path, time);
4784#endif
4785}
4786
4787#endif
4788
4789#ifndef MS_WINDOWS
4790
4791static int
4792utime_default(utime_t *utime, char *path)
4793{
4794#ifdef HAVE_UTIMENSAT
4795 UTIME_TO_TIMESPEC;
4796 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4797#elif defined(HAVE_UTIMES)
4798 UTIME_TO_TIMEVAL;
4799 return utimes(path, time);
4800#elif defined(HAVE_UTIME_H)
4801 UTIME_TO_UTIMBUF;
4802 return utime(path, time);
4803#else
4804 UTIME_TO_TIME_T;
4805 return utime(path, time);
4806#endif
4807}
4808
4809#endif
4810
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811static int
4812split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4813{
4814 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004815 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004816 divmod = PyNumber_Divmod(py_long, billion);
4817 if (!divmod)
4818 goto exit;
4819 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4820 if ((*s == -1) && PyErr_Occurred())
4821 goto exit;
4822 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004823 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004824 goto exit;
4825
4826 result = 1;
4827exit:
4828 Py_XDECREF(divmod);
4829 return result;
4830}
4831
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832static PyObject *
4833posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004834{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004836 PyObject *times = NULL;
4837 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 int dir_fd = DEFAULT_DIR_FD;
4839 int follow_symlinks = 1;
4840 char *keywords[] = {"path", "times", "ns", "dir_fd",
4841 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004842
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004844
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845#ifdef MS_WINDOWS
4846 HANDLE hFile;
4847 FILETIME atime, mtime;
4848#else
4849 int result;
4850#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004851
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004853
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004855 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004856 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857#if UTIME_HAVE_FD
4858 path.allow_fd = 1;
4859#endif
4860 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4861 "O&|O$OO&p:utime", keywords,
4862 path_converter, &path,
4863 &times, &ns,
4864#if UTIME_HAVE_DIR_FD
4865 dir_fd_converter, &dir_fd,
4866#else
4867 dir_fd_unavailable, &dir_fd,
4868#endif
4869 &follow_symlinks
4870 ))
4871 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872
Larry Hastings9cf065c2012-06-22 16:30:09 -07004873 if (times && (times != Py_None) && ns) {
4874 PyErr_SetString(PyExc_ValueError,
4875 "utime: you may specify either 'times'"
4876 " or 'ns' but not both");
4877 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004878 }
4879
4880 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004881 time_t a_sec, m_sec;
4882 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004883 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004884 PyErr_SetString(PyExc_TypeError,
4885 "utime: 'times' must be either"
4886 " a tuple of two ints or None");
4887 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004890 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004891 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004892 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004893 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004895 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004896 utime.atime_s = a_sec;
4897 utime.atime_ns = a_nsec;
4898 utime.mtime_s = m_sec;
4899 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004900 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004901 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004902 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903 PyErr_SetString(PyExc_TypeError,
4904 "utime: 'ns' must be a tuple of two ints");
4905 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004906 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004908 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004910 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 &utime.mtime_s, &utime.mtime_ns)) {
4912 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004913 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 }
4915 else {
4916 /* times and ns are both None/unspecified. use "now". */
4917 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004918 }
4919
Larry Hastings9cf065c2012-06-22 16:30:09 -07004920#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4921 if (follow_symlinks_specified("utime", follow_symlinks))
4922 goto exit;
4923#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004924
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4926 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4927 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4928 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004929
Larry Hastings9cf065c2012-06-22 16:30:09 -07004930#if !defined(HAVE_UTIMENSAT)
4931 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004932 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933 "utime: cannot use dir_fd and follow_symlinks "
4934 "together on this platform");
4935 goto exit;
4936 }
4937#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004938
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004939#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004940 Py_BEGIN_ALLOW_THREADS
4941 if (path.wide)
4942 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 NULL, OPEN_EXISTING,
4944 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004945 else
4946 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 NULL, OPEN_EXISTING,
4948 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 Py_END_ALLOW_THREADS
4950 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004951 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004953 }
4954
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 SYSTEMTIME now;
4957 GetSystemTime(&now);
4958 if (!SystemTimeToFileTime(&now, &mtime) ||
4959 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004960 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004962 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4966 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 }
4968 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4969 /* Avoid putting the file name into the error here,
4970 as that may confuse the user into believing that
4971 something is wrong with the file, when it also
4972 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004973 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004976#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004977 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004978
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4980 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4981 result = utime_nofollow_symlinks(&utime, path.narrow);
4982 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004983#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984
4985#if UTIME_HAVE_DIR_FD
4986 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4987 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4988 else
4989#endif
4990
4991#if UTIME_HAVE_FD
4992 if (path.fd != -1)
4993 result = utime_fd(&utime, path.fd);
4994 else
4995#endif
4996
4997 result = utime_default(&utime, path.narrow);
4998
4999 Py_END_ALLOW_THREADS
5000
5001 if (result < 0) {
5002 /* see previous comment about not putting filename in error here */
5003 return_value = posix_error();
5004 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005006
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005007#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005008
5009 Py_INCREF(Py_None);
5010 return_value = Py_None;
5011
5012exit:
5013 path_cleanup(&path);
5014#ifdef MS_WINDOWS
5015 if (hFile != INVALID_HANDLE_VALUE)
5016 CloseHandle(hFile);
5017#endif
5018 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005019}
5020
Guido van Rossum3b066191991-06-04 19:40:25 +00005021/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005022
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005023PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005024"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005025Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005026
Barry Warsaw53699e91996-12-10 23:23:01 +00005027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005028posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005029{
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 int sts;
5031 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5032 return NULL;
5033 _exit(sts);
5034 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005035}
5036
Martin v. Löwis114619e2002-10-07 06:44:21 +00005037#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5038static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005039free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005040{
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 Py_ssize_t i;
5042 for (i = 0; i < count; i++)
5043 PyMem_Free(array[i]);
5044 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005045}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005046
Antoine Pitrou69f71142009-05-24 21:25:49 +00005047static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005048int fsconvert_strdup(PyObject *o, char**out)
5049{
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 PyObject *bytes;
5051 Py_ssize_t size;
5052 if (!PyUnicode_FSConverter(o, &bytes))
5053 return 0;
5054 size = PyBytes_GET_SIZE(bytes);
5055 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005056 if (!*out) {
5057 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005059 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 memcpy(*out, PyBytes_AsString(bytes), size+1);
5061 Py_DECREF(bytes);
5062 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005063}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005064#endif
5065
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005067static char**
5068parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5069{
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 char **envlist;
5071 Py_ssize_t i, pos, envc;
5072 PyObject *keys=NULL, *vals=NULL;
5073 PyObject *key, *val, *key2, *val2;
5074 char *p, *k, *v;
5075 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005076
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 i = PyMapping_Size(env);
5078 if (i < 0)
5079 return NULL;
5080 envlist = PyMem_NEW(char *, i + 1);
5081 if (envlist == NULL) {
5082 PyErr_NoMemory();
5083 return NULL;
5084 }
5085 envc = 0;
5086 keys = PyMapping_Keys(env);
5087 vals = PyMapping_Values(env);
5088 if (!keys || !vals)
5089 goto error;
5090 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5091 PyErr_Format(PyExc_TypeError,
5092 "env.keys() or env.values() is not a list");
5093 goto error;
5094 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005095
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 for (pos = 0; pos < i; pos++) {
5097 key = PyList_GetItem(keys, pos);
5098 val = PyList_GetItem(vals, pos);
5099 if (!key || !val)
5100 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005101
Victor Stinner8c62be82010-05-06 00:08:46 +00005102 if (PyUnicode_FSConverter(key, &key2) == 0)
5103 goto error;
5104 if (PyUnicode_FSConverter(val, &val2) == 0) {
5105 Py_DECREF(key2);
5106 goto error;
5107 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 k = PyBytes_AsString(key2);
5110 v = PyBytes_AsString(val2);
5111 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005112
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 p = PyMem_NEW(char, len);
5114 if (p == NULL) {
5115 PyErr_NoMemory();
5116 Py_DECREF(key2);
5117 Py_DECREF(val2);
5118 goto error;
5119 }
5120 PyOS_snprintf(p, len, "%s=%s", k, v);
5121 envlist[envc++] = p;
5122 Py_DECREF(key2);
5123 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 }
5125 Py_DECREF(vals);
5126 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005127
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 envlist[envc] = 0;
5129 *envc_ptr = envc;
5130 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005131
5132error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 Py_XDECREF(keys);
5134 Py_XDECREF(vals);
5135 while (--envc >= 0)
5136 PyMem_DEL(envlist[envc]);
5137 PyMem_DEL(envlist);
5138 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005139}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005140
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141static char**
5142parse_arglist(PyObject* argv, Py_ssize_t *argc)
5143{
5144 int i;
5145 char **argvlist = PyMem_NEW(char *, *argc+1);
5146 if (argvlist == NULL) {
5147 PyErr_NoMemory();
5148 return NULL;
5149 }
5150 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005151 PyObject* item = PySequence_ITEM(argv, i);
5152 if (item == NULL)
5153 goto fail;
5154 if (!fsconvert_strdup(item, &argvlist[i])) {
5155 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156 goto fail;
5157 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005158 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 }
5160 argvlist[*argc] = NULL;
5161 return argvlist;
5162fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005163 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005164 free_string_array(argvlist, *argc);
5165 return NULL;
5166}
5167#endif
5168
5169#ifdef HAVE_EXECV
5170PyDoc_STRVAR(posix_execv__doc__,
5171"execv(path, args)\n\n\
5172Execute an executable path with arguments, replacing current process.\n\
5173\n\
5174 path: path of executable file\n\
5175 args: tuple or list of strings");
5176
5177static PyObject *
5178posix_execv(PyObject *self, PyObject *args)
5179{
5180 PyObject *opath;
5181 char *path;
5182 PyObject *argv;
5183 char **argvlist;
5184 Py_ssize_t argc;
5185
5186 /* execv has two arguments: (path, argv), where
5187 argv is a list or tuple of strings. */
5188
5189 if (!PyArg_ParseTuple(args, "O&O:execv",
5190 PyUnicode_FSConverter,
5191 &opath, &argv))
5192 return NULL;
5193 path = PyBytes_AsString(opath);
5194 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5195 PyErr_SetString(PyExc_TypeError,
5196 "execv() arg 2 must be a tuple or list");
5197 Py_DECREF(opath);
5198 return NULL;
5199 }
5200 argc = PySequence_Size(argv);
5201 if (argc < 1) {
5202 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5203 Py_DECREF(opath);
5204 return NULL;
5205 }
5206
5207 argvlist = parse_arglist(argv, &argc);
5208 if (argvlist == NULL) {
5209 Py_DECREF(opath);
5210 return NULL;
5211 }
5212
5213 execv(path, argvlist);
5214
5215 /* If we get here it's definitely an error */
5216
5217 free_string_array(argvlist, argc);
5218 Py_DECREF(opath);
5219 return posix_error();
5220}
5221
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005222PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005223"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005224Execute a path with arguments and environment, replacing current process.\n\
5225\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 path: path of executable file\n\
5227 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005228 env: dictionary of strings mapping to strings\n\
5229\n\
5230On some platforms, you may specify an open file descriptor for path;\n\
5231 execve will execute the program the file descriptor is open to.\n\
5232 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005233
Barry Warsaw53699e91996-12-10 23:23:01 +00005234static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005235posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005236{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005237 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005239 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005241 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005242 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005243
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 /* execve has three arguments: (path, argv, env), where
5245 argv is a list or tuple of strings and env is a dictionary
5246 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005247
Larry Hastings9cf065c2012-06-22 16:30:09 -07005248 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005249 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005250#ifdef HAVE_FEXECVE
5251 path.allow_fd = 1;
5252#endif
5253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5254 path_converter, &path,
5255 &argv, &env
5256 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005258
Ross Lagerwall7807c352011-03-17 20:20:30 +02005259 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005261 "execve: argv must be a tuple or list");
5262 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005264 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (!PyMapping_Check(env)) {
5266 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005267 "execve: environment must be a mapping object");
5268 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005270
Ross Lagerwall7807c352011-03-17 20:20:30 +02005271 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005273 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 envlist = parse_envlist(env, &envc);
5277 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005278 goto fail;
5279
Larry Hastings9cf065c2012-06-22 16:30:09 -07005280#ifdef HAVE_FEXECVE
5281 if (path.fd > -1)
5282 fexecve(path.fd, argvlist, envlist);
5283 else
5284#endif
5285 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005286
5287 /* If we get here it's definitely an error */
5288
Victor Stinner292c8352012-10-30 02:17:38 +01005289 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005290
5291 while (--envc >= 0)
5292 PyMem_DEL(envlist[envc]);
5293 PyMem_DEL(envlist);
5294 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005295 if (argvlist)
5296 free_string_array(argvlist, argc);
5297 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005298 return NULL;
5299}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005300#endif /* HAVE_EXECV */
5301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005302
Guido van Rossuma1065681999-01-25 23:20:23 +00005303#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005305"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005306Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005307\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 mode: mode of process creation\n\
5309 path: path of executable file\n\
5310 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005311
5312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005313posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005314{
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 PyObject *opath;
5316 char *path;
5317 PyObject *argv;
5318 char **argvlist;
5319 int mode, i;
5320 Py_ssize_t argc;
5321 Py_intptr_t spawnval;
5322 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005323
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 /* spawnv has three arguments: (mode, path, argv), where
5325 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005326
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5328 PyUnicode_FSConverter,
5329 &opath, &argv))
5330 return NULL;
5331 path = PyBytes_AsString(opath);
5332 if (PyList_Check(argv)) {
5333 argc = PyList_Size(argv);
5334 getitem = PyList_GetItem;
5335 }
5336 else if (PyTuple_Check(argv)) {
5337 argc = PyTuple_Size(argv);
5338 getitem = PyTuple_GetItem;
5339 }
5340 else {
5341 PyErr_SetString(PyExc_TypeError,
5342 "spawnv() arg 2 must be a tuple or list");
5343 Py_DECREF(opath);
5344 return NULL;
5345 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005346
Victor Stinner8c62be82010-05-06 00:08:46 +00005347 argvlist = PyMem_NEW(char *, argc+1);
5348 if (argvlist == NULL) {
5349 Py_DECREF(opath);
5350 return PyErr_NoMemory();
5351 }
5352 for (i = 0; i < argc; i++) {
5353 if (!fsconvert_strdup((*getitem)(argv, i),
5354 &argvlist[i])) {
5355 free_string_array(argvlist, i);
5356 PyErr_SetString(
5357 PyExc_TypeError,
5358 "spawnv() arg 2 must contain only strings");
5359 Py_DECREF(opath);
5360 return NULL;
5361 }
5362 }
5363 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005364
Victor Stinner8c62be82010-05-06 00:08:46 +00005365 if (mode == _OLD_P_OVERLAY)
5366 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005367
Victor Stinner8c62be82010-05-06 00:08:46 +00005368 Py_BEGIN_ALLOW_THREADS
5369 spawnval = _spawnv(mode, path, argvlist);
5370 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005371
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 free_string_array(argvlist, argc);
5373 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 if (spawnval == -1)
5376 return posix_error();
5377 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005378 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005379}
5380
5381
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005383"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005384Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005385\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005386 mode: mode of process creation\n\
5387 path: path of executable file\n\
5388 args: tuple or list of arguments\n\
5389 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005390
5391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005392posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005393{
Victor Stinner8c62be82010-05-06 00:08:46 +00005394 PyObject *opath;
5395 char *path;
5396 PyObject *argv, *env;
5397 char **argvlist;
5398 char **envlist;
5399 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005400 int mode;
5401 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 Py_intptr_t spawnval;
5403 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5404 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005405
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 /* spawnve has four arguments: (mode, path, argv, env), where
5407 argv is a list or tuple of strings and env is a dictionary
5408 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005409
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5411 PyUnicode_FSConverter,
5412 &opath, &argv, &env))
5413 return NULL;
5414 path = PyBytes_AsString(opath);
5415 if (PyList_Check(argv)) {
5416 argc = PyList_Size(argv);
5417 getitem = PyList_GetItem;
5418 }
5419 else if (PyTuple_Check(argv)) {
5420 argc = PyTuple_Size(argv);
5421 getitem = PyTuple_GetItem;
5422 }
5423 else {
5424 PyErr_SetString(PyExc_TypeError,
5425 "spawnve() arg 2 must be a tuple or list");
5426 goto fail_0;
5427 }
5428 if (!PyMapping_Check(env)) {
5429 PyErr_SetString(PyExc_TypeError,
5430 "spawnve() arg 3 must be a mapping object");
5431 goto fail_0;
5432 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005433
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 argvlist = PyMem_NEW(char *, argc+1);
5435 if (argvlist == NULL) {
5436 PyErr_NoMemory();
5437 goto fail_0;
5438 }
5439 for (i = 0; i < argc; i++) {
5440 if (!fsconvert_strdup((*getitem)(argv, i),
5441 &argvlist[i]))
5442 {
5443 lastarg = i;
5444 goto fail_1;
5445 }
5446 }
5447 lastarg = argc;
5448 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005449
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 envlist = parse_envlist(env, &envc);
5451 if (envlist == NULL)
5452 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005453
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 if (mode == _OLD_P_OVERLAY)
5455 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005456
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 Py_BEGIN_ALLOW_THREADS
5458 spawnval = _spawnve(mode, path, argvlist, envlist);
5459 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005460
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 if (spawnval == -1)
5462 (void) posix_error();
5463 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005464 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005465
Victor Stinner8c62be82010-05-06 00:08:46 +00005466 while (--envc >= 0)
5467 PyMem_DEL(envlist[envc]);
5468 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005469 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005470 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005471 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005472 Py_DECREF(opath);
5473 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005474}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005475
Guido van Rossuma1065681999-01-25 23:20:23 +00005476#endif /* HAVE_SPAWNV */
5477
5478
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005479#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005480PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005481"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005482Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5483\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005485
5486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005487posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005488{
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 pid_t pid;
5490 int result = 0;
5491 _PyImport_AcquireLock();
5492 pid = fork1();
5493 if (pid == 0) {
5494 /* child: this clobbers and resets the import lock. */
5495 PyOS_AfterFork();
5496 } else {
5497 /* parent: release the import lock. */
5498 result = _PyImport_ReleaseLock();
5499 }
5500 if (pid == -1)
5501 return posix_error();
5502 if (result < 0) {
5503 /* Don't clobber the OSError if the fork failed. */
5504 PyErr_SetString(PyExc_RuntimeError,
5505 "not holding the import lock");
5506 return NULL;
5507 }
5508 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005509}
5510#endif
5511
5512
Guido van Rossumad0ee831995-03-01 10:34:45 +00005513#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005515"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Barry Warsaw53699e91996-12-10 23:23:01 +00005519static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005520posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005521{
Victor Stinner8c62be82010-05-06 00:08:46 +00005522 pid_t pid;
5523 int result = 0;
5524 _PyImport_AcquireLock();
5525 pid = fork();
5526 if (pid == 0) {
5527 /* child: this clobbers and resets the import lock. */
5528 PyOS_AfterFork();
5529 } else {
5530 /* parent: release the import lock. */
5531 result = _PyImport_ReleaseLock();
5532 }
5533 if (pid == -1)
5534 return posix_error();
5535 if (result < 0) {
5536 /* Don't clobber the OSError if the fork failed. */
5537 PyErr_SetString(PyExc_RuntimeError,
5538 "not holding the import lock");
5539 return NULL;
5540 }
5541 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005542}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005543#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005544
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005545#ifdef HAVE_SCHED_H
5546
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005547#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5548
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005549PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5550"sched_get_priority_max(policy)\n\n\
5551Get the maximum scheduling priority for *policy*.");
5552
5553static PyObject *
5554posix_sched_get_priority_max(PyObject *self, PyObject *args)
5555{
5556 int policy, max;
5557
5558 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5559 return NULL;
5560 max = sched_get_priority_max(policy);
5561 if (max < 0)
5562 return posix_error();
5563 return PyLong_FromLong(max);
5564}
5565
5566PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5567"sched_get_priority_min(policy)\n\n\
5568Get the minimum scheduling priority for *policy*.");
5569
5570static PyObject *
5571posix_sched_get_priority_min(PyObject *self, PyObject *args)
5572{
5573 int policy, min;
5574
5575 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5576 return NULL;
5577 min = sched_get_priority_min(policy);
5578 if (min < 0)
5579 return posix_error();
5580 return PyLong_FromLong(min);
5581}
5582
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005583#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5584
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005585#ifdef HAVE_SCHED_SETSCHEDULER
5586
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005587PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5588"sched_getscheduler(pid)\n\n\
5589Get the scheduling policy for the process with a PID of *pid*.\n\
5590Passing a PID of 0 returns the scheduling policy for the calling process.");
5591
5592static PyObject *
5593posix_sched_getscheduler(PyObject *self, PyObject *args)
5594{
5595 pid_t pid;
5596 int policy;
5597
5598 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5599 return NULL;
5600 policy = sched_getscheduler(pid);
5601 if (policy < 0)
5602 return posix_error();
5603 return PyLong_FromLong(policy);
5604}
5605
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005606#endif
5607
5608#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5609
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005610static PyObject *
5611sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5612{
5613 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005614 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615
5616 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5617 return NULL;
5618 res = PyStructSequence_New(type);
5619 if (!res)
5620 return NULL;
5621 Py_INCREF(priority);
5622 PyStructSequence_SET_ITEM(res, 0, priority);
5623 return res;
5624}
5625
5626PyDoc_STRVAR(sched_param__doc__,
5627"sched_param(sched_priority): A scheduling parameter.\n\n\
5628Current has only one field: sched_priority");
5629
5630static PyStructSequence_Field sched_param_fields[] = {
5631 {"sched_priority", "the scheduling priority"},
5632 {0}
5633};
5634
5635static PyStructSequence_Desc sched_param_desc = {
5636 "sched_param", /* name */
5637 sched_param__doc__, /* doc */
5638 sched_param_fields,
5639 1
5640};
5641
5642static int
5643convert_sched_param(PyObject *param, struct sched_param *res)
5644{
5645 long priority;
5646
5647 if (Py_TYPE(param) != &SchedParamType) {
5648 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5649 return 0;
5650 }
5651 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5652 if (priority == -1 && PyErr_Occurred())
5653 return 0;
5654 if (priority > INT_MAX || priority < INT_MIN) {
5655 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5656 return 0;
5657 }
5658 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5659 return 1;
5660}
5661
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005662#endif
5663
5664#ifdef HAVE_SCHED_SETSCHEDULER
5665
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5667"sched_setscheduler(pid, policy, param)\n\n\
5668Set the scheduling policy, *policy*, for *pid*.\n\
5669If *pid* is 0, the calling process is changed.\n\
5670*param* is an instance of sched_param.");
5671
5672static PyObject *
5673posix_sched_setscheduler(PyObject *self, PyObject *args)
5674{
5675 pid_t pid;
5676 int policy;
5677 struct sched_param param;
5678
5679 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5680 &pid, &policy, &convert_sched_param, &param))
5681 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005682
5683 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005684 ** sched_setscheduler() returns 0 in Linux, but the previous
5685 ** scheduling policy under Solaris/Illumos, and others.
5686 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005687 */
5688 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005689 return posix_error();
5690 Py_RETURN_NONE;
5691}
5692
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005693#endif
5694
5695#ifdef HAVE_SCHED_SETPARAM
5696
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005697PyDoc_STRVAR(posix_sched_getparam__doc__,
5698"sched_getparam(pid) -> sched_param\n\n\
5699Returns scheduling parameters for the process with *pid* as an instance of the\n\
5700sched_param class. A PID of 0 means the calling process.");
5701
5702static PyObject *
5703posix_sched_getparam(PyObject *self, PyObject *args)
5704{
5705 pid_t pid;
5706 struct sched_param param;
5707 PyObject *res, *priority;
5708
5709 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5710 return NULL;
5711 if (sched_getparam(pid, &param))
5712 return posix_error();
5713 res = PyStructSequence_New(&SchedParamType);
5714 if (!res)
5715 return NULL;
5716 priority = PyLong_FromLong(param.sched_priority);
5717 if (!priority) {
5718 Py_DECREF(res);
5719 return NULL;
5720 }
5721 PyStructSequence_SET_ITEM(res, 0, priority);
5722 return res;
5723}
5724
5725PyDoc_STRVAR(posix_sched_setparam__doc__,
5726"sched_setparam(pid, param)\n\n\
5727Set scheduling parameters for a process with PID *pid*.\n\
5728A PID of 0 means the calling process.");
5729
5730static PyObject *
5731posix_sched_setparam(PyObject *self, PyObject *args)
5732{
5733 pid_t pid;
5734 struct sched_param param;
5735
5736 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5737 &pid, &convert_sched_param, &param))
5738 return NULL;
5739 if (sched_setparam(pid, &param))
5740 return posix_error();
5741 Py_RETURN_NONE;
5742}
5743
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005744#endif
5745
5746#ifdef HAVE_SCHED_RR_GET_INTERVAL
5747
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5749"sched_rr_get_interval(pid) -> float\n\n\
5750Return the round-robin quantum for the process with PID *pid* in seconds.");
5751
5752static PyObject *
5753posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5754{
5755 pid_t pid;
5756 struct timespec interval;
5757
5758 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5759 return NULL;
5760 if (sched_rr_get_interval(pid, &interval))
5761 return posix_error();
5762 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5763}
5764
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005765#endif
5766
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005767PyDoc_STRVAR(posix_sched_yield__doc__,
5768"sched_yield()\n\n\
5769Voluntarily relinquish the CPU.");
5770
5771static PyObject *
5772posix_sched_yield(PyObject *self, PyObject *noargs)
5773{
5774 if (sched_yield())
5775 return posix_error();
5776 Py_RETURN_NONE;
5777}
5778
Benjamin Peterson2740af82011-08-02 17:41:34 -05005779#ifdef HAVE_SCHED_SETAFFINITY
5780
Antoine Pitrou84869872012-08-04 16:16:35 +02005781/* The minimum number of CPUs allocated in a cpu_set_t */
5782static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005783
5784PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5785"sched_setaffinity(pid, cpu_set)\n\n\
5786Set the affinity of the process with PID *pid* to *cpu_set*.");
5787
5788static PyObject *
5789posix_sched_setaffinity(PyObject *self, PyObject *args)
5790{
5791 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005792 int ncpus;
5793 size_t setsize;
5794 cpu_set_t *mask = NULL;
5795 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005796
Antoine Pitrou84869872012-08-04 16:16:35 +02005797 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5798 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005800
5801 iterator = PyObject_GetIter(iterable);
5802 if (iterator == NULL)
5803 return NULL;
5804
5805 ncpus = NCPUS_START;
5806 setsize = CPU_ALLOC_SIZE(ncpus);
5807 mask = CPU_ALLOC(ncpus);
5808 if (mask == NULL) {
5809 PyErr_NoMemory();
5810 goto error;
5811 }
5812 CPU_ZERO_S(setsize, mask);
5813
5814 while ((item = PyIter_Next(iterator))) {
5815 long cpu;
5816 if (!PyLong_Check(item)) {
5817 PyErr_Format(PyExc_TypeError,
5818 "expected an iterator of ints, "
5819 "but iterator yielded %R",
5820 Py_TYPE(item));
5821 Py_DECREF(item);
5822 goto error;
5823 }
5824 cpu = PyLong_AsLong(item);
5825 Py_DECREF(item);
5826 if (cpu < 0) {
5827 if (!PyErr_Occurred())
5828 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5829 goto error;
5830 }
5831 if (cpu > INT_MAX - 1) {
5832 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5833 goto error;
5834 }
5835 if (cpu >= ncpus) {
5836 /* Grow CPU mask to fit the CPU number */
5837 int newncpus = ncpus;
5838 cpu_set_t *newmask;
5839 size_t newsetsize;
5840 while (newncpus <= cpu) {
5841 if (newncpus > INT_MAX / 2)
5842 newncpus = cpu + 1;
5843 else
5844 newncpus = newncpus * 2;
5845 }
5846 newmask = CPU_ALLOC(newncpus);
5847 if (newmask == NULL) {
5848 PyErr_NoMemory();
5849 goto error;
5850 }
5851 newsetsize = CPU_ALLOC_SIZE(newncpus);
5852 CPU_ZERO_S(newsetsize, newmask);
5853 memcpy(newmask, mask, setsize);
5854 CPU_FREE(mask);
5855 setsize = newsetsize;
5856 mask = newmask;
5857 ncpus = newncpus;
5858 }
5859 CPU_SET_S(cpu, setsize, mask);
5860 }
5861 Py_CLEAR(iterator);
5862
5863 if (sched_setaffinity(pid, setsize, mask)) {
5864 posix_error();
5865 goto error;
5866 }
5867 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005868 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005869
5870error:
5871 if (mask)
5872 CPU_FREE(mask);
5873 Py_XDECREF(iterator);
5874 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875}
5876
5877PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5878"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5879Return the affinity of the process with PID *pid*.\n\
5880The returned cpu_set will be of size *ncpus*.");
5881
5882static PyObject *
5883posix_sched_getaffinity(PyObject *self, PyObject *args)
5884{
5885 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005886 int cpu, ncpus, count;
5887 size_t setsize;
5888 cpu_set_t *mask = NULL;
5889 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005890
Antoine Pitrou84869872012-08-04 16:16:35 +02005891 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5892 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005893 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005894
5895 ncpus = NCPUS_START;
5896 while (1) {
5897 setsize = CPU_ALLOC_SIZE(ncpus);
5898 mask = CPU_ALLOC(ncpus);
5899 if (mask == NULL)
5900 return PyErr_NoMemory();
5901 if (sched_getaffinity(pid, setsize, mask) == 0)
5902 break;
5903 CPU_FREE(mask);
5904 if (errno != EINVAL)
5905 return posix_error();
5906 if (ncpus > INT_MAX / 2) {
5907 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5908 "a large enough CPU set");
5909 return NULL;
5910 }
5911 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005912 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005913
5914 res = PySet_New(NULL);
5915 if (res == NULL)
5916 goto error;
5917 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5918 if (CPU_ISSET_S(cpu, setsize, mask)) {
5919 PyObject *cpu_num = PyLong_FromLong(cpu);
5920 --count;
5921 if (cpu_num == NULL)
5922 goto error;
5923 if (PySet_Add(res, cpu_num)) {
5924 Py_DECREF(cpu_num);
5925 goto error;
5926 }
5927 Py_DECREF(cpu_num);
5928 }
5929 }
5930 CPU_FREE(mask);
5931 return res;
5932
5933error:
5934 if (mask)
5935 CPU_FREE(mask);
5936 Py_XDECREF(res);
5937 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005938}
5939
Benjamin Peterson2740af82011-08-02 17:41:34 -05005940#endif /* HAVE_SCHED_SETAFFINITY */
5941
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005942#endif /* HAVE_SCHED_H */
5943
Neal Norwitzb59798b2003-03-21 01:43:31 +00005944/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005945/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5946#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005947#define DEV_PTY_FILE "/dev/ptc"
5948#define HAVE_DEV_PTMX
5949#else
5950#define DEV_PTY_FILE "/dev/ptmx"
5951#endif
5952
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005953#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005954#ifdef HAVE_PTY_H
5955#include <pty.h>
5956#else
5957#ifdef HAVE_LIBUTIL_H
5958#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005959#else
5960#ifdef HAVE_UTIL_H
5961#include <util.h>
5962#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005963#endif /* HAVE_LIBUTIL_H */
5964#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005965#ifdef HAVE_STROPTS_H
5966#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005967#endif
5968#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005969
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005970#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005972"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005973Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005974
5975static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005976posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005977{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005978 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005979#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005981#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005982#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005984#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005986#endif
5987#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005988
Thomas Wouters70c21a12000-07-14 14:28:33 +00005989#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005991 goto posix_error;
5992
5993 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5994 goto error;
5995 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5996 goto error;
5997
Neal Norwitzb59798b2003-03-21 01:43:31 +00005998#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6000 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006001 goto posix_error;
6002 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6003 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006004
Victor Stinnerdaf45552013-08-28 00:53:59 +02006005 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006007 goto posix_error;
6008
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006009#else
Victor Stinnerdaf45552013-08-28 00:53:59 +02006010 master_fd = _Py_open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006012 goto posix_error;
6013
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 /* change permission of slave */
6017 if (grantpt(master_fd) < 0) {
6018 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006019 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006021
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 /* unlock slave */
6023 if (unlockpt(master_fd) < 0) {
6024 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006025 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006027
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006029
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 slave_name = ptsname(master_fd); /* get name of slave */
6031 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006032 goto posix_error;
6033
6034 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006036 goto posix_error;
Neal Norwitzb59798b2003-03-21 01:43:31 +00006037#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6039 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006040#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006042#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006043#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006044#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006045
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006047
Victor Stinnerdaf45552013-08-28 00:53:59 +02006048posix_error:
6049 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006050#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006051error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006052#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006053 if (master_fd != -1)
6054 close(master_fd);
6055 if (slave_fd != -1)
6056 close(slave_fd);
6057 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006058}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006059#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006060
6061#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006062PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006063"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006064Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6065Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006067
6068static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006069posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006070{
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 int master_fd = -1, result = 0;
6072 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006073
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 _PyImport_AcquireLock();
6075 pid = forkpty(&master_fd, NULL, NULL, NULL);
6076 if (pid == 0) {
6077 /* child: this clobbers and resets the import lock. */
6078 PyOS_AfterFork();
6079 } else {
6080 /* parent: release the import lock. */
6081 result = _PyImport_ReleaseLock();
6082 }
6083 if (pid == -1)
6084 return posix_error();
6085 if (result < 0) {
6086 /* Don't clobber the OSError if the fork failed. */
6087 PyErr_SetString(PyExc_RuntimeError,
6088 "not holding the import lock");
6089 return NULL;
6090 }
6091 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006092}
6093#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006094
Ross Lagerwall7807c352011-03-17 20:20:30 +02006095
Guido van Rossumad0ee831995-03-01 10:34:45 +00006096#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006100
Barry Warsaw53699e91996-12-10 23:23:01 +00006101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006102posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006103{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006104 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006105}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006106#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006107
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Guido van Rossumad0ee831995-03-01 10:34:45 +00006109#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006111"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006112Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006113
Barry Warsaw53699e91996-12-10 23:23:01 +00006114static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006115posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006116{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006117 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006118}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006119#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006121
Guido van Rossumad0ee831995-03-01 10:34:45 +00006122#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006128posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006129{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006130 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006131}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006132#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006136"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006137Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006138
Barry Warsaw53699e91996-12-10 23:23:01 +00006139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006140posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006141{
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006143}
6144
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145#ifdef HAVE_GETGROUPLIST
6146PyDoc_STRVAR(posix_getgrouplist__doc__,
6147"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6148Returns a list of groups to which a user belongs.\n\n\
6149 user: username to lookup\n\
6150 group: base group id of the user");
6151
6152static PyObject *
6153posix_getgrouplist(PyObject *self, PyObject *args)
6154{
6155#ifdef NGROUPS_MAX
6156#define MAX_GROUPS NGROUPS_MAX
6157#else
6158 /* defined to be 16 on Solaris7, so this should be a small number */
6159#define MAX_GROUPS 64
6160#endif
6161
6162 const char *user;
6163 int i, ngroups;
6164 PyObject *list;
6165#ifdef __APPLE__
6166 int *groups, basegid;
6167#else
6168 gid_t *groups, basegid;
6169#endif
6170 ngroups = MAX_GROUPS;
6171
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172#ifdef __APPLE__
6173 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006174 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006175#else
6176 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6177 _Py_Gid_Converter, &basegid))
6178 return NULL;
6179#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006180
6181#ifdef __APPLE__
6182 groups = PyMem_Malloc(ngroups * sizeof(int));
6183#else
6184 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6185#endif
6186 if (groups == NULL)
6187 return PyErr_NoMemory();
6188
6189 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6190 PyMem_Del(groups);
6191 return posix_error();
6192 }
6193
6194 list = PyList_New(ngroups);
6195 if (list == NULL) {
6196 PyMem_Del(groups);
6197 return NULL;
6198 }
6199
6200 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006201#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006202 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006203#else
6204 PyObject *o = _PyLong_FromGid(groups[i]);
6205#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006206 if (o == NULL) {
6207 Py_DECREF(list);
6208 PyMem_Del(groups);
6209 return NULL;
6210 }
6211 PyList_SET_ITEM(list, i, o);
6212 }
6213
6214 PyMem_Del(groups);
6215
6216 return list;
6217}
6218#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006219
Fred Drakec9680921999-12-13 16:37:25 +00006220#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006221PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006222"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006223Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006224
6225static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006226posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006227{
6228 PyObject *result = NULL;
6229
Fred Drakec9680921999-12-13 16:37:25 +00006230#ifdef NGROUPS_MAX
6231#define MAX_GROUPS NGROUPS_MAX
6232#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006233 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006234#define MAX_GROUPS 64
6235#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006237
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006238 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006239 * This is a helper variable to store the intermediate result when
6240 * that happens.
6241 *
6242 * To keep the code readable the OSX behaviour is unconditional,
6243 * according to the POSIX spec this should be safe on all unix-y
6244 * systems.
6245 */
6246 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006248
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006249#ifdef __APPLE__
6250 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6251 * there are more groups than can fit in grouplist. Therefore, on OS X
6252 * always first call getgroups with length 0 to get the actual number
6253 * of groups.
6254 */
6255 n = getgroups(0, NULL);
6256 if (n < 0) {
6257 return posix_error();
6258 } else if (n <= MAX_GROUPS) {
6259 /* groups will fit in existing array */
6260 alt_grouplist = grouplist;
6261 } else {
6262 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6263 if (alt_grouplist == NULL) {
6264 errno = EINVAL;
6265 return posix_error();
6266 }
6267 }
6268
6269 n = getgroups(n, alt_grouplist);
6270 if (n == -1) {
6271 if (alt_grouplist != grouplist) {
6272 PyMem_Free(alt_grouplist);
6273 }
6274 return posix_error();
6275 }
6276#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006278 if (n < 0) {
6279 if (errno == EINVAL) {
6280 n = getgroups(0, NULL);
6281 if (n == -1) {
6282 return posix_error();
6283 }
6284 if (n == 0) {
6285 /* Avoid malloc(0) */
6286 alt_grouplist = grouplist;
6287 } else {
6288 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6289 if (alt_grouplist == NULL) {
6290 errno = EINVAL;
6291 return posix_error();
6292 }
6293 n = getgroups(n, alt_grouplist);
6294 if (n == -1) {
6295 PyMem_Free(alt_grouplist);
6296 return posix_error();
6297 }
6298 }
6299 } else {
6300 return posix_error();
6301 }
6302 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006303#endif
6304
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006305 result = PyList_New(n);
6306 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 int i;
6308 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006309 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006311 Py_DECREF(result);
6312 result = NULL;
6313 break;
Fred Drakec9680921999-12-13 16:37:25 +00006314 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006316 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006317 }
6318
6319 if (alt_grouplist != grouplist) {
6320 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006322
Fred Drakec9680921999-12-13 16:37:25 +00006323 return result;
6324}
6325#endif
6326
Antoine Pitroub7572f02009-12-02 20:46:48 +00006327#ifdef HAVE_INITGROUPS
6328PyDoc_STRVAR(posix_initgroups__doc__,
6329"initgroups(username, gid) -> None\n\n\
6330Call the system initgroups() to initialize the group access list with all of\n\
6331the groups of which the specified username is a member, plus the specified\n\
6332group id.");
6333
6334static PyObject *
6335posix_initgroups(PyObject *self, PyObject *args)
6336{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006337 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006339 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006340#ifdef __APPLE__
6341 int gid;
6342#else
6343 gid_t gid;
6344#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006345
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006346#ifdef __APPLE__
6347 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6348 PyUnicode_FSConverter, &oname,
6349 &gid))
6350#else
6351 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6352 PyUnicode_FSConverter, &oname,
6353 _Py_Gid_Converter, &gid))
6354#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006356 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006357
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006358 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006359 Py_DECREF(oname);
6360 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006362
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 Py_INCREF(Py_None);
6364 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006365}
6366#endif
6367
Martin v. Löwis606edc12002-06-13 21:09:11 +00006368#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006369PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006370"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006371Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006372
6373static PyObject *
6374posix_getpgid(PyObject *self, PyObject *args)
6375{
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 pid_t pid, pgid;
6377 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6378 return NULL;
6379 pgid = getpgid(pid);
6380 if (pgid < 0)
6381 return posix_error();
6382 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006383}
6384#endif /* HAVE_GETPGID */
6385
6386
Guido van Rossumb6775db1994-08-01 11:34:53 +00006387#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006388PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006389"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006391
Barry Warsaw53699e91996-12-10 23:23:01 +00006392static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006393posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006394{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006395#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006397#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006399#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006400}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006403
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006405PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006406"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006407Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006408
Barry Warsaw53699e91996-12-10 23:23:01 +00006409static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006410posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006411{
Guido van Rossum64933891994-10-20 21:56:42 +00006412#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006414#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006416#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 return posix_error();
6418 Py_INCREF(Py_None);
6419 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006420}
6421
Guido van Rossumb6775db1994-08-01 11:34:53 +00006422#endif /* HAVE_SETPGRP */
6423
Guido van Rossumad0ee831995-03-01 10:34:45 +00006424#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006425
6426#ifdef MS_WINDOWS
6427#include <tlhelp32.h>
6428
6429static PyObject*
6430win32_getppid()
6431{
6432 HANDLE snapshot;
6433 pid_t mypid;
6434 PyObject* result = NULL;
6435 BOOL have_record;
6436 PROCESSENTRY32 pe;
6437
6438 mypid = getpid(); /* This function never fails */
6439
6440 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6441 if (snapshot == INVALID_HANDLE_VALUE)
6442 return PyErr_SetFromWindowsErr(GetLastError());
6443
6444 pe.dwSize = sizeof(pe);
6445 have_record = Process32First(snapshot, &pe);
6446 while (have_record) {
6447 if (mypid == (pid_t)pe.th32ProcessID) {
6448 /* We could cache the ulong value in a static variable. */
6449 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6450 break;
6451 }
6452
6453 have_record = Process32Next(snapshot, &pe);
6454 }
6455
6456 /* If our loop exits and our pid was not found (result will be NULL)
6457 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6458 * error anyway, so let's raise it. */
6459 if (!result)
6460 result = PyErr_SetFromWindowsErr(GetLastError());
6461
6462 CloseHandle(snapshot);
6463
6464 return result;
6465}
6466#endif /*MS_WINDOWS*/
6467
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006468PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006469"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006470Return the parent's process id. If the parent process has already exited,\n\
6471Windows machines will still return its id; others systems will return the id\n\
6472of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006473
Barry Warsaw53699e91996-12-10 23:23:01 +00006474static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006475posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006476{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006477#ifdef MS_WINDOWS
6478 return win32_getppid();
6479#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006481#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006482}
6483#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006485
Fred Drake12c6e2d1999-12-14 21:25:03 +00006486#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006487PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006488"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006489Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006490
6491static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006492posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006493{
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006495#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006496 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006497 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498
6499 if (GetUserNameW(user_name, &num_chars)) {
6500 /* num_chars is the number of unicode chars plus null terminator */
6501 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006502 }
6503 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006504 result = PyErr_SetFromWindowsErr(GetLastError());
6505#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 char *name;
6507 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006508
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 errno = 0;
6510 name = getlogin();
6511 if (name == NULL) {
6512 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006513 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006515 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 }
6517 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006518 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006520#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006521 return result;
6522}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006523#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006524
Guido van Rossumad0ee831995-03-01 10:34:45 +00006525#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006527"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006529
Barry Warsaw53699e91996-12-10 23:23:01 +00006530static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006531posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006532{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006533 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006534}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006535#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006537
Guido van Rossumad0ee831995-03-01 10:34:45 +00006538#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006540"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006541Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006542
Barry Warsaw53699e91996-12-10 23:23:01 +00006543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006544posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006545{
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 pid_t pid;
6547 int sig;
6548 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6549 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 if (kill(pid, sig) == -1)
6551 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 Py_INCREF(Py_None);
6553 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006554}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006555#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006556
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006557#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006558PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006559"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006561
6562static PyObject *
6563posix_killpg(PyObject *self, PyObject *args)
6564{
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 int sig;
6566 pid_t pgid;
6567 /* XXX some man pages make the `pgid` parameter an int, others
6568 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6569 take the same type. Moreover, pid_t is always at least as wide as
6570 int (else compilation of this module fails), which is safe. */
6571 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6572 return NULL;
6573 if (killpg(pgid, sig) == -1)
6574 return posix_error();
6575 Py_INCREF(Py_None);
6576 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006577}
6578#endif
6579
Brian Curtineb24d742010-04-12 17:16:38 +00006580#ifdef MS_WINDOWS
6581PyDoc_STRVAR(win32_kill__doc__,
6582"kill(pid, sig)\n\n\
6583Kill a process with a signal.");
6584
6585static PyObject *
6586win32_kill(PyObject *self, PyObject *args)
6587{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006588 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006589 pid_t pid;
6590 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006592
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006593 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006595
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 /* Console processes which share a common console can be sent CTRL+C or
6597 CTRL+BREAK events, provided they handle said events. */
6598 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006599 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 err = GetLastError();
6601 PyErr_SetFromWindowsErr(err);
6602 }
6603 else
6604 Py_RETURN_NONE;
6605 }
Brian Curtineb24d742010-04-12 17:16:38 +00006606
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6608 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006609 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 if (handle == NULL) {
6611 err = GetLastError();
6612 return PyErr_SetFromWindowsErr(err);
6613 }
Brian Curtineb24d742010-04-12 17:16:38 +00006614
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 if (TerminateProcess(handle, sig) == 0) {
6616 err = GetLastError();
6617 result = PyErr_SetFromWindowsErr(err);
6618 } else {
6619 Py_INCREF(Py_None);
6620 result = Py_None;
6621 }
Brian Curtineb24d742010-04-12 17:16:38 +00006622
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 CloseHandle(handle);
6624 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006625}
6626#endif /* MS_WINDOWS */
6627
Guido van Rossumc0125471996-06-28 18:55:32 +00006628#ifdef HAVE_PLOCK
6629
6630#ifdef HAVE_SYS_LOCK_H
6631#include <sys/lock.h>
6632#endif
6633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006634PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006635"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006637
Barry Warsaw53699e91996-12-10 23:23:01 +00006638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006639posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006640{
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 int op;
6642 if (!PyArg_ParseTuple(args, "i:plock", &op))
6643 return NULL;
6644 if (plock(op) == -1)
6645 return posix_error();
6646 Py_INCREF(Py_None);
6647 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006648}
6649#endif
6650
Guido van Rossumb6775db1994-08-01 11:34:53 +00006651#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006652PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006653"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006654Set the current process's user id.");
6655
Barry Warsaw53699e91996-12-10 23:23:01 +00006656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006657posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006658{
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006660 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 if (setuid(uid) < 0)
6663 return posix_error();
6664 Py_INCREF(Py_None);
6665 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006666}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006667#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006669
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006670#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006672"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673Set the current process's effective user id.");
6674
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006675static PyObject *
6676posix_seteuid (PyObject *self, PyObject *args)
6677{
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006679 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006681 if (seteuid(euid) < 0) {
6682 return posix_error();
6683 } else {
6684 Py_INCREF(Py_None);
6685 return Py_None;
6686 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006687}
6688#endif /* HAVE_SETEUID */
6689
6690#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006692"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693Set the current process's effective group id.");
6694
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006695static PyObject *
6696posix_setegid (PyObject *self, PyObject *args)
6697{
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006699 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 if (setegid(egid) < 0) {
6702 return posix_error();
6703 } else {
6704 Py_INCREF(Py_None);
6705 return Py_None;
6706 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006707}
6708#endif /* HAVE_SETEGID */
6709
6710#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006712"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006713Set the current process's real and effective user ids.");
6714
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006715static PyObject *
6716posix_setreuid (PyObject *self, PyObject *args)
6717{
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006719 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6720 _Py_Uid_Converter, &ruid,
6721 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 if (setreuid(ruid, euid) < 0) {
6724 return posix_error();
6725 } else {
6726 Py_INCREF(Py_None);
6727 return Py_None;
6728 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006729}
6730#endif /* HAVE_SETREUID */
6731
6732#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006733PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006734"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735Set the current process's real and effective group ids.");
6736
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006737static PyObject *
6738posix_setregid (PyObject *self, PyObject *args)
6739{
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006741 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6742 _Py_Gid_Converter, &rgid,
6743 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006744 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 if (setregid(rgid, egid) < 0) {
6746 return posix_error();
6747 } else {
6748 Py_INCREF(Py_None);
6749 return Py_None;
6750 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006751}
6752#endif /* HAVE_SETREGID */
6753
Guido van Rossumb6775db1994-08-01 11:34:53 +00006754#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006755PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006756"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006757Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006758
Barry Warsaw53699e91996-12-10 23:23:01 +00006759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006760posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006763 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 if (setgid(gid) < 0)
6766 return posix_error();
6767 Py_INCREF(Py_None);
6768 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006769}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006770#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006771
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006772#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006773PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006774"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006776
6777static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006778posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006779{
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 int i, len;
6781 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006782
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 if (!PySequence_Check(groups)) {
6784 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6785 return NULL;
6786 }
6787 len = PySequence_Size(groups);
6788 if (len > MAX_GROUPS) {
6789 PyErr_SetString(PyExc_ValueError, "too many groups");
6790 return NULL;
6791 }
6792 for(i = 0; i < len; i++) {
6793 PyObject *elem;
6794 elem = PySequence_GetItem(groups, i);
6795 if (!elem)
6796 return NULL;
6797 if (!PyLong_Check(elem)) {
6798 PyErr_SetString(PyExc_TypeError,
6799 "groups must be integers");
6800 Py_DECREF(elem);
6801 return NULL;
6802 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006803 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 Py_DECREF(elem);
6805 return NULL;
6806 }
6807 }
6808 Py_DECREF(elem);
6809 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006810
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 if (setgroups(len, grouplist) < 0)
6812 return posix_error();
6813 Py_INCREF(Py_None);
6814 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006815}
6816#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6819static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006820wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006821{
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 PyObject *result;
6823 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006824 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (pid == -1)
6827 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 if (struct_rusage == NULL) {
6830 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6831 if (m == NULL)
6832 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006833 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 Py_DECREF(m);
6835 if (struct_rusage == NULL)
6836 return NULL;
6837 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6840 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6841 if (!result)
6842 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
6844#ifndef doubletime
6845#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6846#endif
6847
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006849 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006851 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6854 SET_INT(result, 2, ru->ru_maxrss);
6855 SET_INT(result, 3, ru->ru_ixrss);
6856 SET_INT(result, 4, ru->ru_idrss);
6857 SET_INT(result, 5, ru->ru_isrss);
6858 SET_INT(result, 6, ru->ru_minflt);
6859 SET_INT(result, 7, ru->ru_majflt);
6860 SET_INT(result, 8, ru->ru_nswap);
6861 SET_INT(result, 9, ru->ru_inblock);
6862 SET_INT(result, 10, ru->ru_oublock);
6863 SET_INT(result, 11, ru->ru_msgsnd);
6864 SET_INT(result, 12, ru->ru_msgrcv);
6865 SET_INT(result, 13, ru->ru_nsignals);
6866 SET_INT(result, 14, ru->ru_nvcsw);
6867 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868#undef SET_INT
6869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 if (PyErr_Occurred()) {
6871 Py_DECREF(result);
6872 return NULL;
6873 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876}
6877#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6878
6879#ifdef HAVE_WAIT3
6880PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006881"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882Wait for completion of a child process.");
6883
6884static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006885posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886{
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 pid_t pid;
6888 int options;
6889 struct rusage ru;
6890 WAIT_TYPE status;
6891 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892
Victor Stinner4195b5c2012-02-08 23:03:19 +01006893 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006895
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 Py_BEGIN_ALLOW_THREADS
6897 pid = wait3(&status, options, &ru);
6898 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006899
Victor Stinner4195b5c2012-02-08 23:03:19 +01006900 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006901}
6902#endif /* HAVE_WAIT3 */
6903
6904#ifdef HAVE_WAIT4
6905PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907Wait for completion of a given child process.");
6908
6909static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006910posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911{
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 pid_t pid;
6913 int options;
6914 struct rusage ru;
6915 WAIT_TYPE status;
6916 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917
Victor Stinner4195b5c2012-02-08 23:03:19 +01006918 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 Py_BEGIN_ALLOW_THREADS
6922 pid = wait4(pid, &status, options, &ru);
6923 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924
Victor Stinner4195b5c2012-02-08 23:03:19 +01006925 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926}
6927#endif /* HAVE_WAIT4 */
6928
Ross Lagerwall7807c352011-03-17 20:20:30 +02006929#if defined(HAVE_WAITID) && !defined(__APPLE__)
6930PyDoc_STRVAR(posix_waitid__doc__,
6931"waitid(idtype, id, options) -> waitid_result\n\n\
6932Wait for the completion of one or more child processes.\n\n\
6933idtype can be P_PID, P_PGID or P_ALL.\n\
6934id specifies the pid to wait on.\n\
6935options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6936or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6937Returns either waitid_result or None if WNOHANG is specified and there are\n\
6938no children in a waitable state.");
6939
6940static PyObject *
6941posix_waitid(PyObject *self, PyObject *args)
6942{
6943 PyObject *result;
6944 idtype_t idtype;
6945 id_t id;
6946 int options, res;
6947 siginfo_t si;
6948 si.si_pid = 0;
6949 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6950 return NULL;
6951 Py_BEGIN_ALLOW_THREADS
6952 res = waitid(idtype, id, &si, options);
6953 Py_END_ALLOW_THREADS
6954 if (res == -1)
6955 return posix_error();
6956
6957 if (si.si_pid == 0)
6958 Py_RETURN_NONE;
6959
6960 result = PyStructSequence_New(&WaitidResultType);
6961 if (!result)
6962 return NULL;
6963
6964 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006965 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006966 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6967 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6968 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6969 if (PyErr_Occurred()) {
6970 Py_DECREF(result);
6971 return NULL;
6972 }
6973
6974 return result;
6975}
6976#endif
6977
Guido van Rossumb6775db1994-08-01 11:34:53 +00006978#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006979PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006980"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006981Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Barry Warsaw53699e91996-12-10 23:23:01 +00006983static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006984posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006985{
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 pid_t pid;
6987 int options;
6988 WAIT_TYPE status;
6989 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006990
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6992 return NULL;
6993 Py_BEGIN_ALLOW_THREADS
6994 pid = waitpid(pid, &status, options);
6995 Py_END_ALLOW_THREADS
6996 if (pid == -1)
6997 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006998
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007000}
7001
Tim Petersab034fa2002-02-01 11:27:43 +00007002#elif defined(HAVE_CWAIT)
7003
7004/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007005PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007006"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007007"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007008
7009static PyObject *
7010posix_waitpid(PyObject *self, PyObject *args)
7011{
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 Py_intptr_t pid;
7013 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007014
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007015 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 return NULL;
7017 Py_BEGIN_ALLOW_THREADS
7018 pid = _cwait(&status, pid, options);
7019 Py_END_ALLOW_THREADS
7020 if (pid == -1)
7021 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007022
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007024 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007025}
7026#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007027
Guido van Rossumad0ee831995-03-01 10:34:45 +00007028#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007030"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007031Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007032
Barry Warsaw53699e91996-12-10 23:23:01 +00007033static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007034posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007035{
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 pid_t pid;
7037 WAIT_TYPE status;
7038 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007039
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 Py_BEGIN_ALLOW_THREADS
7041 pid = wait(&status);
7042 Py_END_ALLOW_THREADS
7043 if (pid == -1)
7044 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007045
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007047}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007048#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007050
Larry Hastings9cf065c2012-06-22 16:30:09 -07007051#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7052PyDoc_STRVAR(readlink__doc__,
7053"readlink(path, *, dir_fd=None) -> path\n\n\
7054Return a string representing the path to which the symbolic link points.\n\
7055\n\
7056If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7057 and path should be relative; path will then be relative to that directory.\n\
7058dir_fd may not be implemented on your platform.\n\
7059 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007060#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Guido van Rossumb6775db1994-08-01 11:34:53 +00007062#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007063
Barry Warsaw53699e91996-12-10 23:23:01 +00007064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007067 path_t path;
7068 int dir_fd = DEFAULT_DIR_FD;
7069 char buffer[MAXPATHLEN];
7070 ssize_t length;
7071 PyObject *return_value = NULL;
7072 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007073
Larry Hastings9cf065c2012-06-22 16:30:09 -07007074 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007075 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007076 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7077 path_converter, &path,
7078#ifdef HAVE_READLINKAT
7079 dir_fd_converter, &dir_fd
7080#else
7081 dir_fd_unavailable, &dir_fd
7082#endif
7083 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007085
Victor Stinner8c62be82010-05-06 00:08:46 +00007086 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007087#ifdef HAVE_READLINKAT
7088 if (dir_fd != DEFAULT_DIR_FD)
7089 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007090 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007091#endif
7092 length = readlink(path.narrow, buffer, sizeof(buffer));
7093 Py_END_ALLOW_THREADS
7094
7095 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007096 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097 goto exit;
7098 }
7099
7100 if (PyUnicode_Check(path.object))
7101 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7102 else
7103 return_value = PyBytes_FromStringAndSize(buffer, length);
7104exit:
7105 path_cleanup(&path);
7106 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007107}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108
7109
Guido van Rossumb6775db1994-08-01 11:34:53 +00007110#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007112
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007114PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7116Create a symbolic link pointing to src named dst.\n\n\
7117target_is_directory is required on Windows if the target is to be\n\
7118 interpreted as a directory. (On Windows, symlink requires\n\
7119 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7120 target_is_directory is ignored on non-Windows platforms.\n\
7121\n\
7122If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7123 and path should be relative; path will then be relative to that directory.\n\
7124dir_fd may not be implemented on your platform.\n\
7125 If it is unavailable, using it will raise a NotImplementedError.");
7126
7127#if defined(MS_WINDOWS)
7128
7129/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7130static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7131static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007132
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007134check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135{
7136 HINSTANCE hKernel32;
7137 /* only recheck */
7138 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7139 return 1;
7140 hKernel32 = GetModuleHandleW(L"KERNEL32");
7141 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7142 "CreateSymbolicLinkW");
7143 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7144 "CreateSymbolicLinkA");
7145 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7146}
7147
Victor Stinner31b3b922013-06-05 01:49:17 +02007148/* Remove the last portion of the path */
7149static void
7150_dirnameW(WCHAR *path)
7151{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007152 WCHAR *ptr;
7153
7154 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007155 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007156 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007157 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007158 }
7159 *ptr = 0;
7160}
7161
Victor Stinner31b3b922013-06-05 01:49:17 +02007162/* Remove the last portion of the path */
7163static void
7164_dirnameA(char *path)
7165{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007166 char *ptr;
7167
7168 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007169 for(ptr = path + strlen(path); ptr != path; ptr--) {
7170 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007171 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007172 }
7173 *ptr = 0;
7174}
7175
Victor Stinner31b3b922013-06-05 01:49:17 +02007176/* Is this path absolute? */
7177static int
7178_is_absW(const WCHAR *path)
7179{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007180 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7181
7182}
7183
Victor Stinner31b3b922013-06-05 01:49:17 +02007184/* Is this path absolute? */
7185static int
7186_is_absA(const char *path)
7187{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007188 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7189
7190}
7191
Victor Stinner31b3b922013-06-05 01:49:17 +02007192/* join root and rest with a backslash */
7193static void
7194_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7195{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007196 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007197
Victor Stinner31b3b922013-06-05 01:49:17 +02007198 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007199 wcscpy(dest_path, rest);
7200 return;
7201 }
7202
7203 root_len = wcslen(root);
7204
7205 wcscpy(dest_path, root);
7206 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007207 dest_path[root_len] = L'\\';
7208 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007209 }
7210 wcscpy(dest_path+root_len, rest);
7211}
7212
Victor Stinner31b3b922013-06-05 01:49:17 +02007213/* join root and rest with a backslash */
7214static void
7215_joinA(char *dest_path, const char *root, const char *rest)
7216{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007217 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007218
Victor Stinner31b3b922013-06-05 01:49:17 +02007219 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007220 strcpy(dest_path, rest);
7221 return;
7222 }
7223
7224 root_len = strlen(root);
7225
7226 strcpy(dest_path, root);
7227 if(root_len) {
7228 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007229 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007230 }
7231 strcpy(dest_path+root_len, rest);
7232}
7233
Victor Stinner31b3b922013-06-05 01:49:17 +02007234/* Return True if the path at src relative to dest is a directory */
7235static int
7236_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007237{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007238 WIN32_FILE_ATTRIBUTE_DATA src_info;
7239 WCHAR dest_parent[MAX_PATH];
7240 WCHAR src_resolved[MAX_PATH] = L"";
7241
7242 /* dest_parent = os.path.dirname(dest) */
7243 wcscpy(dest_parent, dest);
7244 _dirnameW(dest_parent);
7245 /* src_resolved = os.path.join(dest_parent, src) */
7246 _joinW(src_resolved, dest_parent, src);
7247 return (
7248 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7249 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7250 );
7251}
7252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253/* Return True if the path at src relative to dest is a directory */
7254static int
7255_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007256{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007257 WIN32_FILE_ATTRIBUTE_DATA src_info;
7258 char dest_parent[MAX_PATH];
7259 char src_resolved[MAX_PATH] = "";
7260
7261 /* dest_parent = os.path.dirname(dest) */
7262 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007263 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007265 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007266 return (
7267 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7268 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7269 );
7270}
7271
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007273
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007274static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007276{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007277 path_t src;
7278 path_t dst;
7279 int dir_fd = DEFAULT_DIR_FD;
7280 int target_is_directory = 0;
7281 static char *keywords[] = {"src", "dst", "target_is_directory",
7282 "dir_fd", NULL};
7283 PyObject *return_value;
7284#ifdef MS_WINDOWS
7285 DWORD result;
7286#else
7287 int result;
7288#endif
7289
7290 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007291 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007292 src.argument_name = "src";
7293 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007294 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007295 dst.argument_name = "dst";
7296
7297#ifdef MS_WINDOWS
7298 if (!check_CreateSymbolicLink()) {
7299 PyErr_SetString(PyExc_NotImplementedError,
7300 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007301 return NULL;
7302 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007303 if (!win32_can_symlink) {
7304 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007305 return NULL;
7306 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007307#endif
7308
7309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7310 keywords,
7311 path_converter, &src,
7312 path_converter, &dst,
7313 &target_is_directory,
7314#ifdef HAVE_SYMLINKAT
7315 dir_fd_converter, &dir_fd
7316#else
7317 dir_fd_unavailable, &dir_fd
7318#endif
7319 ))
7320 return NULL;
7321
7322 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7323 PyErr_SetString(PyExc_ValueError,
7324 "symlink: src and dst must be the same type");
7325 return_value = NULL;
7326 goto exit;
7327 }
7328
7329#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330
Larry Hastings9cf065c2012-06-22 16:30:09 -07007331 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007332 if (dst.wide) {
7333 /* if src is a directory, ensure target_is_directory==1 */
7334 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007335 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7336 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 }
7338 else {
7339 /* if src is a directory, ensure target_is_directory==1 */
7340 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007341 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7342 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007344 Py_END_ALLOW_THREADS
7345
7346 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007347 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007348 goto exit;
7349 }
7350
7351#else
7352
7353 Py_BEGIN_ALLOW_THREADS
7354#if HAVE_SYMLINKAT
7355 if (dir_fd != DEFAULT_DIR_FD)
7356 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7357 else
7358#endif
7359 result = symlink(src.narrow, dst.narrow);
7360 Py_END_ALLOW_THREADS
7361
7362 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007363 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007364 goto exit;
7365 }
7366#endif
7367
7368 return_value = Py_None;
7369 Py_INCREF(Py_None);
7370 goto exit; /* silence "unused label" warning */
7371exit:
7372 path_cleanup(&src);
7373 path_cleanup(&dst);
7374 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007375}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007376
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007377#endif /* HAVE_SYMLINK */
7378
Larry Hastings9cf065c2012-06-22 16:30:09 -07007379
Brian Curtind40e6f72010-07-08 21:39:08 +00007380#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7381
Brian Curtind40e6f72010-07-08 21:39:08 +00007382static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007384{
7385 wchar_t *path;
7386 DWORD n_bytes_returned;
7387 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007388 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007389 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007390 HANDLE reparse_point_handle;
7391
7392 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7393 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7394 wchar_t *print_name;
7395
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 static char *keywords[] = {"path", "dir_fd", NULL};
7397
7398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7399 &po,
7400 dir_fd_unavailable, &dir_fd
7401 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007402 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403
Victor Stinnereb5657a2011-09-30 01:44:27 +02007404 path = PyUnicode_AsUnicode(po);
7405 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007406 return NULL;
7407
7408 /* First get a handle to the reparse point */
7409 Py_BEGIN_ALLOW_THREADS
7410 reparse_point_handle = CreateFileW(
7411 path,
7412 0,
7413 0,
7414 0,
7415 OPEN_EXISTING,
7416 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7417 0);
7418 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007419
Brian Curtind40e6f72010-07-08 21:39:08 +00007420 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007421 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007422
Brian Curtind40e6f72010-07-08 21:39:08 +00007423 Py_BEGIN_ALLOW_THREADS
7424 /* New call DeviceIoControl to read the reparse point */
7425 io_result = DeviceIoControl(
7426 reparse_point_handle,
7427 FSCTL_GET_REPARSE_POINT,
7428 0, 0, /* in buffer */
7429 target_buffer, sizeof(target_buffer),
7430 &n_bytes_returned,
7431 0 /* we're not using OVERLAPPED_IO */
7432 );
7433 CloseHandle(reparse_point_handle);
7434 Py_END_ALLOW_THREADS
7435
7436 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007437 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007438
7439 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7440 {
7441 PyErr_SetString(PyExc_ValueError,
7442 "not a symbolic link");
7443 return NULL;
7444 }
Brian Curtin74e45612010-07-09 15:58:59 +00007445 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7446 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7447
7448 result = PyUnicode_FromWideChar(print_name,
7449 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007450 return result;
7451}
7452
7453#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7454
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007455
Larry Hastings605a62d2012-06-24 04:33:36 -07007456static PyStructSequence_Field times_result_fields[] = {
7457 {"user", "user time"},
7458 {"system", "system time"},
7459 {"children_user", "user time of children"},
7460 {"children_system", "system time of children"},
7461 {"elapsed", "elapsed time since an arbitrary point in the past"},
7462 {NULL}
7463};
7464
7465PyDoc_STRVAR(times_result__doc__,
7466"times_result: Result from os.times().\n\n\
7467This object may be accessed either as a tuple of\n\
7468 (user, system, children_user, children_system, elapsed),\n\
7469or via the attributes user, system, children_user, children_system,\n\
7470and elapsed.\n\
7471\n\
7472See os.times for more information.");
7473
7474static PyStructSequence_Desc times_result_desc = {
7475 "times_result", /* name */
7476 times_result__doc__, /* doc */
7477 times_result_fields,
7478 5
7479};
7480
7481static PyTypeObject TimesResultType;
7482
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007483#ifdef MS_WINDOWS
7484#define HAVE_TIMES /* mandatory, for the method table */
7485#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007486
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007487#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007488
7489static PyObject *
7490build_times_result(double user, double system,
7491 double children_user, double children_system,
7492 double elapsed)
7493{
7494 PyObject *value = PyStructSequence_New(&TimesResultType);
7495 if (value == NULL)
7496 return NULL;
7497
7498#define SET(i, field) \
7499 { \
7500 PyObject *o = PyFloat_FromDouble(field); \
7501 if (!o) { \
7502 Py_DECREF(value); \
7503 return NULL; \
7504 } \
7505 PyStructSequence_SET_ITEM(value, i, o); \
7506 } \
7507
7508 SET(0, user);
7509 SET(1, system);
7510 SET(2, children_user);
7511 SET(3, children_system);
7512 SET(4, elapsed);
7513
7514#undef SET
7515
7516 return value;
7517}
7518
7519PyDoc_STRVAR(posix_times__doc__,
7520"times() -> times_result\n\n\
7521Return an object containing floating point numbers indicating process\n\
7522times. The object behaves like a named tuple with these fields:\n\
7523 (utime, stime, cutime, cstime, elapsed_time)");
7524
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007525#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007526static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007527posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007528{
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 FILETIME create, exit, kernel, user;
7530 HANDLE hProc;
7531 hProc = GetCurrentProcess();
7532 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7533 /* The fields of a FILETIME structure are the hi and lo part
7534 of a 64-bit value expressed in 100 nanosecond units.
7535 1e7 is one second in such units; 1e-7 the inverse.
7536 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7537 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007538 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 (double)(user.dwHighDateTime*429.4967296 +
7540 user.dwLowDateTime*1e-7),
7541 (double)(kernel.dwHighDateTime*429.4967296 +
7542 kernel.dwLowDateTime*1e-7),
7543 (double)0,
7544 (double)0,
7545 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007546}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007547#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007548#define NEED_TICKS_PER_SECOND
7549static long ticks_per_second = -1;
7550static PyObject *
7551posix_times(PyObject *self, PyObject *noargs)
7552{
7553 struct tms t;
7554 clock_t c;
7555 errno = 0;
7556 c = times(&t);
7557 if (c == (clock_t) -1)
7558 return posix_error();
7559 return build_times_result(
7560 (double)t.tms_utime / ticks_per_second,
7561 (double)t.tms_stime / ticks_per_second,
7562 (double)t.tms_cutime / ticks_per_second,
7563 (double)t.tms_cstime / ticks_per_second,
7564 (double)c / ticks_per_second);
7565}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007566#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007567
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007568#endif /* HAVE_TIMES */
7569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007570
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007571#ifdef HAVE_GETSID
7572PyDoc_STRVAR(posix_getsid__doc__,
7573"getsid(pid) -> sid\n\n\
7574Call the system call getsid().");
7575
7576static PyObject *
7577posix_getsid(PyObject *self, PyObject *args)
7578{
Victor Stinner8c62be82010-05-06 00:08:46 +00007579 pid_t pid;
7580 int sid;
7581 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7582 return NULL;
7583 sid = getsid(pid);
7584 if (sid < 0)
7585 return posix_error();
7586 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007587}
7588#endif /* HAVE_GETSID */
7589
7590
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007592PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007593"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007594Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007595
Barry Warsaw53699e91996-12-10 23:23:01 +00007596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007597posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 if (setsid() < 0)
7600 return posix_error();
7601 Py_INCREF(Py_None);
7602 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007605
Guido van Rossumb6775db1994-08-01 11:34:53 +00007606#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007608"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007609Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Barry Warsaw53699e91996-12-10 23:23:01 +00007611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007612posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007613{
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 pid_t pid;
7615 int pgrp;
7616 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7617 return NULL;
7618 if (setpgid(pid, pgrp) < 0)
7619 return posix_error();
7620 Py_INCREF(Py_None);
7621 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007622}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007627PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007628"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007629Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007630
Barry Warsaw53699e91996-12-10 23:23:01 +00007631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007632posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007633{
Victor Stinner8c62be82010-05-06 00:08:46 +00007634 int fd;
7635 pid_t pgid;
7636 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7637 return NULL;
7638 pgid = tcgetpgrp(fd);
7639 if (pgid < 0)
7640 return posix_error();
7641 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007642}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007643#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007644
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007645
Guido van Rossumb6775db1994-08-01 11:34:53 +00007646#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007647PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007648"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007649Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007650
Barry Warsaw53699e91996-12-10 23:23:01 +00007651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007652posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007653{
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 int fd;
7655 pid_t pgid;
7656 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7657 return NULL;
7658 if (tcsetpgrp(fd, pgid) < 0)
7659 return posix_error();
7660 Py_INCREF(Py_None);
7661 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007662}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007663#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007664
Guido van Rossum687dd131993-05-17 08:34:16 +00007665/* Functions acting on file descriptors */
7666
Victor Stinnerdaf45552013-08-28 00:53:59 +02007667#ifdef O_CLOEXEC
7668extern int _Py_open_cloexec_works;
7669#endif
7670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007671PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007672"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7673Open a file for low level IO. Returns a file handle (integer).\n\
7674\n\
7675If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7676 and path should be relative; path will then be relative to that directory.\n\
7677dir_fd may not be implemented on your platform.\n\
7678 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007679
Barry Warsaw53699e91996-12-10 23:23:01 +00007680static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007681posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007682{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007683 path_t path;
7684 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007686 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007688 PyObject *return_value = NULL;
7689 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007690#ifdef O_CLOEXEC
7691 int *atomic_flag_works = &_Py_open_cloexec_works;
7692#elif !defined(MS_WINDOWS)
7693 int *atomic_flag_works = NULL;
7694#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007695
Larry Hastings9cf065c2012-06-22 16:30:09 -07007696 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007697 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007698 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7699 path_converter, &path,
7700 &flags, &mode,
7701#ifdef HAVE_OPENAT
7702 dir_fd_converter, &dir_fd
7703#else
7704 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007705#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007706 ))
7707 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007708
Victor Stinnerdaf45552013-08-28 00:53:59 +02007709#ifdef MS_WINDOWS
7710 flags |= O_NOINHERIT;
7711#elif defined(O_CLOEXEC)
7712 flags |= O_CLOEXEC;
7713#endif
7714
Victor Stinner8c62be82010-05-06 00:08:46 +00007715 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007716#ifdef MS_WINDOWS
7717 if (path.wide)
7718 fd = _wopen(path.wide, flags, mode);
7719 else
7720#endif
7721#ifdef HAVE_OPENAT
7722 if (dir_fd != DEFAULT_DIR_FD)
7723 fd = openat(dir_fd, path.narrow, flags, mode);
7724 else
7725#endif
7726 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007728
Larry Hastings9cf065c2012-06-22 16:30:09 -07007729 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007730 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007731 goto exit;
7732 }
7733
Victor Stinnerdaf45552013-08-28 00:53:59 +02007734#ifndef MS_WINDOWS
7735 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7736 close(fd);
7737 goto exit;
7738 }
7739#endif
7740
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741 return_value = PyLong_FromLong((long)fd);
7742
7743exit:
7744 path_cleanup(&path);
7745 return return_value;
7746}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007747
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007748PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007749"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007750Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007751
Barry Warsaw53699e91996-12-10 23:23:01 +00007752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007753posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007754{
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 int fd, res;
7756 if (!PyArg_ParseTuple(args, "i:close", &fd))
7757 return NULL;
7758 if (!_PyVerify_fd(fd))
7759 return posix_error();
7760 Py_BEGIN_ALLOW_THREADS
7761 res = close(fd);
7762 Py_END_ALLOW_THREADS
7763 if (res < 0)
7764 return posix_error();
7765 Py_INCREF(Py_None);
7766 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007767}
7768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007769
Victor Stinner8c62be82010-05-06 00:08:46 +00007770PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007771"closerange(fd_low, fd_high)\n\n\
7772Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7773
7774static PyObject *
7775posix_closerange(PyObject *self, PyObject *args)
7776{
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 int fd_from, fd_to, i;
7778 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7779 return NULL;
7780 Py_BEGIN_ALLOW_THREADS
7781 for (i = fd_from; i < fd_to; i++)
7782 if (_PyVerify_fd(i))
7783 close(i);
7784 Py_END_ALLOW_THREADS
7785 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007786}
7787
7788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007789PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007790"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007791Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007792
Barry Warsaw53699e91996-12-10 23:23:01 +00007793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007794posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007795{
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007797
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7799 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007800
Victor Stinnerdaf45552013-08-28 00:53:59 +02007801 fd = _Py_dup(fd);
7802 if (fd == -1)
7803 return NULL;
7804
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007806}
7807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007808
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007810"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007811Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007812
Barry Warsaw53699e91996-12-10 23:23:01 +00007813static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007814posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007815{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007816 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7817 int fd, fd2;
7818 int inheritable = 1;
7819 int res;
7820#if defined(HAVE_DUP3) && \
7821 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7822 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7823 int dup3_works = -1;
7824#endif
7825
7826 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7827 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007829
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 if (!_PyVerify_fd_dup2(fd, fd2))
7831 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007832
7833#ifdef MS_WINDOWS
7834 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007836 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 if (res < 0)
7838 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007839
7840 /* Character files like console cannot be make non-inheritable */
7841 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7842 close(fd2);
7843 return NULL;
7844 }
7845
7846#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7847 Py_BEGIN_ALLOW_THREADS
7848 if (!inheritable)
7849 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7850 else
7851 res = dup2(fd, fd2);
7852 Py_END_ALLOW_THREADS
7853 if (res < 0)
7854 return posix_error();
7855
7856#else
7857
7858#ifdef HAVE_DUP3
7859 if (!inheritable && dup3_works != 0) {
7860 Py_BEGIN_ALLOW_THREADS
7861 res = dup3(fd, fd2, O_CLOEXEC);
7862 Py_END_ALLOW_THREADS
7863 if (res < 0) {
7864 if (dup3_works == -1)
7865 dup3_works = (errno != ENOSYS);
7866 if (dup3_works)
7867 return posix_error();
7868 }
7869 }
7870
7871 if (inheritable || dup3_works == 0)
7872 {
7873#endif
7874 Py_BEGIN_ALLOW_THREADS
7875 res = dup2(fd, fd2);
7876 Py_END_ALLOW_THREADS
7877 if (res < 0)
7878 return posix_error();
7879
7880 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7881 close(fd2);
7882 return NULL;
7883 }
7884#ifdef HAVE_DUP3
7885 }
7886#endif
7887
7888#endif
7889
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 Py_INCREF(Py_None);
7891 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007892}
7893
Ross Lagerwall7807c352011-03-17 20:20:30 +02007894#ifdef HAVE_LOCKF
7895PyDoc_STRVAR(posix_lockf__doc__,
7896"lockf(fd, cmd, len)\n\n\
7897Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7898fd is an open file descriptor.\n\
7899cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7900F_TEST.\n\
7901len specifies the section of the file to lock.");
7902
7903static PyObject *
7904posix_lockf(PyObject *self, PyObject *args)
7905{
7906 int fd, cmd, res;
7907 off_t len;
7908 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7909 &fd, &cmd, _parse_off_t, &len))
7910 return NULL;
7911
7912 Py_BEGIN_ALLOW_THREADS
7913 res = lockf(fd, cmd, len);
7914 Py_END_ALLOW_THREADS
7915
7916 if (res < 0)
7917 return posix_error();
7918
7919 Py_RETURN_NONE;
7920}
7921#endif
7922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007923
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007924PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007925"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007926Set the current position of a file descriptor.\n\
7927Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007928
Barry Warsaw53699e91996-12-10 23:23:01 +00007929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007930posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007931{
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007933#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007935#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007937#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007938 PyObject *posobj;
7939 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007941#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7943 switch (how) {
7944 case 0: how = SEEK_SET; break;
7945 case 1: how = SEEK_CUR; break;
7946 case 2: how = SEEK_END; break;
7947 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007948#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007949
Ross Lagerwall8e749672011-03-17 21:54:07 +02007950#if !defined(HAVE_LARGEFILE_SUPPORT)
7951 pos = PyLong_AsLong(posobj);
7952#else
7953 pos = PyLong_AsLongLong(posobj);
7954#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 if (PyErr_Occurred())
7956 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007957
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 if (!_PyVerify_fd(fd))
7959 return posix_error();
7960 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007963#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007965#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 Py_END_ALLOW_THREADS
7967 if (res < 0)
7968 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007969
7970#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007972#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007974#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007975}
7976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007977
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007978PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007979"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007980Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007981
Barry Warsaw53699e91996-12-10 23:23:01 +00007982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007983posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007984{
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 int fd, size;
7986 Py_ssize_t n;
7987 PyObject *buffer;
7988 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7989 return NULL;
7990 if (size < 0) {
7991 errno = EINVAL;
7992 return posix_error();
7993 }
7994 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7995 if (buffer == NULL)
7996 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007997 if (!_PyVerify_fd(fd)) {
7998 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008000 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 Py_BEGIN_ALLOW_THREADS
8002 n = read(fd, PyBytes_AS_STRING(buffer), size);
8003 Py_END_ALLOW_THREADS
8004 if (n < 0) {
8005 Py_DECREF(buffer);
8006 return posix_error();
8007 }
8008 if (n != size)
8009 _PyBytes_Resize(&buffer, n);
8010 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008011}
8012
Ross Lagerwall7807c352011-03-17 20:20:30 +02008013#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8014 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008015static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008016iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8017{
8018 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008019 Py_ssize_t blen, total = 0;
8020
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 *iov = PyMem_New(struct iovec, cnt);
8022 if (*iov == NULL) {
8023 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008024 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008026
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008027 *buf = PyMem_New(Py_buffer, cnt);
8028 if (*buf == NULL) {
8029 PyMem_Del(*iov);
8030 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008031 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 }
8033
8034 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008035 PyObject *item = PySequence_GetItem(seq, i);
8036 if (item == NULL)
8037 goto fail;
8038 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8039 Py_DECREF(item);
8040 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008042 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008044 blen = (*buf)[i].len;
8045 (*iov)[i].iov_len = blen;
8046 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008048 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008049
8050fail:
8051 PyMem_Del(*iov);
8052 for (j = 0; j < i; j++) {
8053 PyBuffer_Release(&(*buf)[j]);
8054 }
8055 PyMem_Del(*buf);
8056 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057}
8058
8059static void
8060iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8061{
8062 int i;
8063 PyMem_Del(iov);
8064 for (i = 0; i < cnt; i++) {
8065 PyBuffer_Release(&buf[i]);
8066 }
8067 PyMem_Del(buf);
8068}
8069#endif
8070
Ross Lagerwall7807c352011-03-17 20:20:30 +02008071#ifdef HAVE_READV
8072PyDoc_STRVAR(posix_readv__doc__,
8073"readv(fd, buffers) -> bytesread\n\n\
8074Read from a file descriptor into a number of writable buffers. buffers\n\
8075is an arbitrary sequence of writable buffers.\n\
8076Returns the total number of bytes read.");
8077
8078static PyObject *
8079posix_readv(PyObject *self, PyObject *args)
8080{
8081 int fd, cnt;
8082 Py_ssize_t n;
8083 PyObject *seq;
8084 struct iovec *iov;
8085 Py_buffer *buf;
8086
8087 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8088 return NULL;
8089 if (!PySequence_Check(seq)) {
8090 PyErr_SetString(PyExc_TypeError,
8091 "readv() arg 2 must be a sequence");
8092 return NULL;
8093 }
8094 cnt = PySequence_Size(seq);
8095
8096 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8097 return NULL;
8098
8099 Py_BEGIN_ALLOW_THREADS
8100 n = readv(fd, iov, cnt);
8101 Py_END_ALLOW_THREADS
8102
8103 iov_cleanup(iov, buf, cnt);
8104 return PyLong_FromSsize_t(n);
8105}
8106#endif
8107
8108#ifdef HAVE_PREAD
8109PyDoc_STRVAR(posix_pread__doc__,
8110"pread(fd, buffersize, offset) -> string\n\n\
8111Read from a file descriptor, fd, at a position of offset. It will read up\n\
8112to buffersize number of bytes. The file offset remains unchanged.");
8113
8114static PyObject *
8115posix_pread(PyObject *self, PyObject *args)
8116{
8117 int fd, size;
8118 off_t offset;
8119 Py_ssize_t n;
8120 PyObject *buffer;
8121 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8122 return NULL;
8123
8124 if (size < 0) {
8125 errno = EINVAL;
8126 return posix_error();
8127 }
8128 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8129 if (buffer == NULL)
8130 return NULL;
8131 if (!_PyVerify_fd(fd)) {
8132 Py_DECREF(buffer);
8133 return posix_error();
8134 }
8135 Py_BEGIN_ALLOW_THREADS
8136 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8137 Py_END_ALLOW_THREADS
8138 if (n < 0) {
8139 Py_DECREF(buffer);
8140 return posix_error();
8141 }
8142 if (n != size)
8143 _PyBytes_Resize(&buffer, n);
8144 return buffer;
8145}
8146#endif
8147
8148PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008149"write(fd, data) -> byteswritten\n\n\
8150Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151
8152static PyObject *
8153posix_write(PyObject *self, PyObject *args)
8154{
8155 Py_buffer pbuf;
8156 int fd;
8157 Py_ssize_t size, len;
8158
8159 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8160 return NULL;
8161 if (!_PyVerify_fd(fd)) {
8162 PyBuffer_Release(&pbuf);
8163 return posix_error();
8164 }
8165 len = pbuf.len;
8166 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008167#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 if (len > INT_MAX)
8169 len = INT_MAX;
8170 size = write(fd, pbuf.buf, (int)len);
8171#else
8172 size = write(fd, pbuf.buf, len);
8173#endif
8174 Py_END_ALLOW_THREADS
8175 PyBuffer_Release(&pbuf);
8176 if (size < 0)
8177 return posix_error();
8178 return PyLong_FromSsize_t(size);
8179}
8180
8181#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008182PyDoc_STRVAR(posix_sendfile__doc__,
8183"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8184sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8185 -> byteswritten\n\
8186Copy nbytes bytes from file descriptor in to file descriptor out.");
8187
8188static PyObject *
8189posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8190{
8191 int in, out;
8192 Py_ssize_t ret;
8193 off_t offset;
8194
8195#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8196#ifndef __APPLE__
8197 Py_ssize_t len;
8198#endif
8199 PyObject *headers = NULL, *trailers = NULL;
8200 Py_buffer *hbuf, *tbuf;
8201 off_t sbytes;
8202 struct sf_hdtr sf;
8203 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008204 static char *keywords[] = {"out", "in",
8205 "offset", "count",
8206 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008208 sf.headers = NULL;
8209 sf.trailers = NULL;
8210
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008211#ifdef __APPLE__
8212 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008213 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008214#else
8215 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008216 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008217#endif
8218 &headers, &trailers, &flags))
8219 return NULL;
8220 if (headers != NULL) {
8221 if (!PySequence_Check(headers)) {
8222 PyErr_SetString(PyExc_TypeError,
8223 "sendfile() headers must be a sequence or None");
8224 return NULL;
8225 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008226 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008227 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008228 if (sf.hdr_cnt > 0 &&
8229 !(i = iov_setup(&(sf.headers), &hbuf,
8230 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008232#ifdef __APPLE__
8233 sbytes += i;
8234#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008235 }
8236 }
8237 if (trailers != NULL) {
8238 if (!PySequence_Check(trailers)) {
8239 PyErr_SetString(PyExc_TypeError,
8240 "sendfile() trailers must be a sequence or None");
8241 return NULL;
8242 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008243 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008244 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008245 if (sf.trl_cnt > 0 &&
8246 !(i = iov_setup(&(sf.trailers), &tbuf,
8247 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008249#ifdef __APPLE__
8250 sbytes += i;
8251#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008252 }
8253 }
8254
8255 Py_BEGIN_ALLOW_THREADS
8256#ifdef __APPLE__
8257 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8258#else
8259 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8260#endif
8261 Py_END_ALLOW_THREADS
8262
8263 if (sf.headers != NULL)
8264 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8265 if (sf.trailers != NULL)
8266 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8267
8268 if (ret < 0) {
8269 if ((errno == EAGAIN) || (errno == EBUSY)) {
8270 if (sbytes != 0) {
8271 // some data has been sent
8272 goto done;
8273 }
8274 else {
8275 // no data has been sent; upper application is supposed
8276 // to retry on EAGAIN or EBUSY
8277 return posix_error();
8278 }
8279 }
8280 return posix_error();
8281 }
8282 goto done;
8283
8284done:
8285 #if !defined(HAVE_LARGEFILE_SUPPORT)
8286 return Py_BuildValue("l", sbytes);
8287 #else
8288 return Py_BuildValue("L", sbytes);
8289 #endif
8290
8291#else
8292 Py_ssize_t count;
8293 PyObject *offobj;
8294 static char *keywords[] = {"out", "in",
8295 "offset", "count", NULL};
8296 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8297 keywords, &out, &in, &offobj, &count))
8298 return NULL;
8299#ifdef linux
8300 if (offobj == Py_None) {
8301 Py_BEGIN_ALLOW_THREADS
8302 ret = sendfile(out, in, NULL, count);
8303 Py_END_ALLOW_THREADS
8304 if (ret < 0)
8305 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008306 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 }
8308#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008309 if (!_parse_off_t(offobj, &offset))
8310 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 Py_BEGIN_ALLOW_THREADS
8312 ret = sendfile(out, in, &offset, count);
8313 Py_END_ALLOW_THREADS
8314 if (ret < 0)
8315 return posix_error();
8316 return Py_BuildValue("n", ret);
8317#endif
8318}
8319#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008321PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008322"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008323Like stat(), but for an open file descriptor.\n\
8324Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008325
Barry Warsaw53699e91996-12-10 23:23:01 +00008326static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008327posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008328{
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 int fd;
8330 STRUCT_STAT st;
8331 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008332 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008334#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 /* on OpenVMS we must ensure that all bytes are written to the file */
8336 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008337#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 Py_BEGIN_ALLOW_THREADS
8339 res = FSTAT(fd, &st);
8340 Py_END_ALLOW_THREADS
8341 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008342#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008343 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008344#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008346#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 }
Tim Peters5aa91602002-01-30 05:46:57 +00008348
Victor Stinner4195b5c2012-02-08 23:03:19 +01008349 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008350}
8351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008352PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008353"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008354Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008355connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008356
8357static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008358posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008359{
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 int fd;
8361 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8362 return NULL;
8363 if (!_PyVerify_fd(fd))
8364 return PyBool_FromLong(0);
8365 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008366}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008367
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008368#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008369PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008370"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008371Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008372
Barry Warsaw53699e91996-12-10 23:23:01 +00008373static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008374posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008375{
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008377#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008379 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008381#else
8382 int res;
8383#endif
8384
8385#ifdef MS_WINDOWS
8386 attr.nLength = sizeof(attr);
8387 attr.lpSecurityDescriptor = NULL;
8388 attr.bInheritHandle = FALSE;
8389
8390 Py_BEGIN_ALLOW_THREADS
8391 ok = CreatePipe(&read, &write, &attr, 0);
8392 if (ok) {
8393 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8394 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8395 if (fds[0] == -1 || fds[1] == -1) {
8396 CloseHandle(read);
8397 CloseHandle(write);
8398 ok = 0;
8399 }
8400 }
8401 Py_END_ALLOW_THREADS
8402
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008404 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008405#else
8406
8407#ifdef HAVE_PIPE2
8408 Py_BEGIN_ALLOW_THREADS
8409 res = pipe2(fds, O_CLOEXEC);
8410 Py_END_ALLOW_THREADS
8411
8412 if (res != 0 && errno == ENOSYS)
8413 {
8414#endif
8415 Py_BEGIN_ALLOW_THREADS
8416 res = pipe(fds);
8417 Py_END_ALLOW_THREADS
8418
8419 if (res == 0) {
8420 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8421 close(fds[0]);
8422 close(fds[1]);
8423 return NULL;
8424 }
8425 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8426 close(fds[0]);
8427 close(fds[1]);
8428 return NULL;
8429 }
8430 }
8431#ifdef HAVE_PIPE2
8432 }
8433#endif
8434
8435 if (res != 0)
8436 return PyErr_SetFromErrno(PyExc_OSError);
8437#endif /* !MS_WINDOWS */
8438 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008439}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008440#endif /* HAVE_PIPE */
8441
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008442#ifdef HAVE_PIPE2
8443PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008444"pipe2(flags) -> (read_end, write_end)\n\n\
8445Create a pipe with flags set atomically.\n\
8446flags can be constructed by ORing together one or more of these values:\n\
8447O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008448");
8449
8450static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008451posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008452{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008453 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008454 int fds[2];
8455 int res;
8456
Serhiy Storchaka78980432013-01-15 01:12:17 +02008457 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008458 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008459 return NULL;
8460
8461 res = pipe2(fds, flags);
8462 if (res != 0)
8463 return posix_error();
8464 return Py_BuildValue("(ii)", fds[0], fds[1]);
8465}
8466#endif /* HAVE_PIPE2 */
8467
Ross Lagerwall7807c352011-03-17 20:20:30 +02008468#ifdef HAVE_WRITEV
8469PyDoc_STRVAR(posix_writev__doc__,
8470"writev(fd, buffers) -> byteswritten\n\n\
8471Write the contents of buffers to a file descriptor, where buffers is an\n\
8472arbitrary sequence of buffers.\n\
8473Returns the total bytes written.");
8474
8475static PyObject *
8476posix_writev(PyObject *self, PyObject *args)
8477{
8478 int fd, cnt;
8479 Py_ssize_t res;
8480 PyObject *seq;
8481 struct iovec *iov;
8482 Py_buffer *buf;
8483 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8484 return NULL;
8485 if (!PySequence_Check(seq)) {
8486 PyErr_SetString(PyExc_TypeError,
8487 "writev() arg 2 must be a sequence");
8488 return NULL;
8489 }
8490 cnt = PySequence_Size(seq);
8491
8492 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8493 return NULL;
8494 }
8495
8496 Py_BEGIN_ALLOW_THREADS
8497 res = writev(fd, iov, cnt);
8498 Py_END_ALLOW_THREADS
8499
8500 iov_cleanup(iov, buf, cnt);
8501 return PyLong_FromSsize_t(res);
8502}
8503#endif
8504
8505#ifdef HAVE_PWRITE
8506PyDoc_STRVAR(posix_pwrite__doc__,
8507"pwrite(fd, string, offset) -> byteswritten\n\n\
8508Write string to a file descriptor, fd, from offset, leaving the file\n\
8509offset unchanged.");
8510
8511static PyObject *
8512posix_pwrite(PyObject *self, PyObject *args)
8513{
8514 Py_buffer pbuf;
8515 int fd;
8516 off_t offset;
8517 Py_ssize_t size;
8518
8519 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8520 return NULL;
8521
8522 if (!_PyVerify_fd(fd)) {
8523 PyBuffer_Release(&pbuf);
8524 return posix_error();
8525 }
8526 Py_BEGIN_ALLOW_THREADS
8527 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8528 Py_END_ALLOW_THREADS
8529 PyBuffer_Release(&pbuf);
8530 if (size < 0)
8531 return posix_error();
8532 return PyLong_FromSsize_t(size);
8533}
8534#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008535
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008536#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008537PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008538"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8539Create a FIFO (a POSIX named pipe).\n\
8540\n\
8541If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8542 and path should be relative; path will then be relative to that directory.\n\
8543dir_fd may not be implemented on your platform.\n\
8544 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008545
Barry Warsaw53699e91996-12-10 23:23:01 +00008546static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008547posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008548{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008549 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008551 int dir_fd = DEFAULT_DIR_FD;
8552 int result;
8553 PyObject *return_value = NULL;
8554 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8555
8556 memset(&path, 0, sizeof(path));
8557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8558 path_converter, &path,
8559 &mode,
8560#ifdef HAVE_MKFIFOAT
8561 dir_fd_converter, &dir_fd
8562#else
8563 dir_fd_unavailable, &dir_fd
8564#endif
8565 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008567
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008569#ifdef HAVE_MKFIFOAT
8570 if (dir_fd != DEFAULT_DIR_FD)
8571 result = mkfifoat(dir_fd, path.narrow, mode);
8572 else
8573#endif
8574 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008576
8577 if (result < 0) {
8578 return_value = posix_error();
8579 goto exit;
8580 }
8581
8582 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008584
8585exit:
8586 path_cleanup(&path);
8587 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008588}
8589#endif
8590
Neal Norwitz11690112002-07-30 01:08:28 +00008591#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008592PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008593"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008594Create a filesystem node (file, device special file or named pipe)\n\
8595named filename. mode specifies both the permissions to use and the\n\
8596type of node to be created, being combined (bitwise OR) with one of\n\
8597S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008598device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008599os.makedev()), otherwise it is ignored.\n\
8600\n\
8601If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8602 and path should be relative; path will then be relative to that directory.\n\
8603dir_fd may not be implemented on your platform.\n\
8604 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008605
8606
8607static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008608posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008609{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008610 path_t path;
8611 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008612 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008613 int dir_fd = DEFAULT_DIR_FD;
8614 int result;
8615 PyObject *return_value = NULL;
8616 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8617
8618 memset(&path, 0, sizeof(path));
8619 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8620 path_converter, &path,
8621 &mode, &device,
8622#ifdef HAVE_MKNODAT
8623 dir_fd_converter, &dir_fd
8624#else
8625 dir_fd_unavailable, &dir_fd
8626#endif
8627 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008629
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008631#ifdef HAVE_MKNODAT
8632 if (dir_fd != DEFAULT_DIR_FD)
8633 result = mknodat(dir_fd, path.narrow, mode, device);
8634 else
8635#endif
8636 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008638
8639 if (result < 0) {
8640 return_value = posix_error();
8641 goto exit;
8642 }
8643
8644 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008645 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008646
Larry Hastings9cf065c2012-06-22 16:30:09 -07008647exit:
8648 path_cleanup(&path);
8649 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008650}
8651#endif
8652
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008653#ifdef HAVE_DEVICE_MACROS
8654PyDoc_STRVAR(posix_major__doc__,
8655"major(device) -> major number\n\
8656Extracts a device major number from a raw device number.");
8657
8658static PyObject *
8659posix_major(PyObject *self, PyObject *args)
8660{
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 int device;
8662 if (!PyArg_ParseTuple(args, "i:major", &device))
8663 return NULL;
8664 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008665}
8666
8667PyDoc_STRVAR(posix_minor__doc__,
8668"minor(device) -> minor number\n\
8669Extracts a device minor number from a raw device number.");
8670
8671static PyObject *
8672posix_minor(PyObject *self, PyObject *args)
8673{
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 int device;
8675 if (!PyArg_ParseTuple(args, "i:minor", &device))
8676 return NULL;
8677 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008678}
8679
8680PyDoc_STRVAR(posix_makedev__doc__,
8681"makedev(major, minor) -> device number\n\
8682Composes a raw device number from the major and minor device numbers.");
8683
8684static PyObject *
8685posix_makedev(PyObject *self, PyObject *args)
8686{
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 int major, minor;
8688 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8689 return NULL;
8690 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008691}
8692#endif /* device macros */
8693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008694
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008695#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008696PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008697"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008698Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008699
Barry Warsaw53699e91996-12-10 23:23:01 +00008700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008701posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008702{
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 int fd;
8704 off_t length;
8705 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008706
Ross Lagerwall7807c352011-03-17 20:20:30 +02008707 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008709
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 Py_BEGIN_ALLOW_THREADS
8711 res = ftruncate(fd, length);
8712 Py_END_ALLOW_THREADS
8713 if (res < 0)
8714 return posix_error();
8715 Py_INCREF(Py_None);
8716 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008717}
8718#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008719
Ross Lagerwall7807c352011-03-17 20:20:30 +02008720#ifdef HAVE_TRUNCATE
8721PyDoc_STRVAR(posix_truncate__doc__,
8722"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008723Truncate the file given by path to length bytes.\n\
8724On some platforms, path may also be specified as an open file descriptor.\n\
8725 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008726
8727static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008728posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729{
Georg Brandl306336b2012-06-24 12:55:33 +02008730 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731 off_t length;
8732 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008733 PyObject *result = NULL;
8734 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008735
Georg Brandl306336b2012-06-24 12:55:33 +02008736 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008737 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008738#ifdef HAVE_FTRUNCATE
8739 path.allow_fd = 1;
8740#endif
8741 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8742 path_converter, &path,
8743 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008744 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008745
8746 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008747#ifdef HAVE_FTRUNCATE
8748 if (path.fd != -1)
8749 res = ftruncate(path.fd, length);
8750 else
8751#endif
8752 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008753 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008754 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008755 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008756 else {
8757 Py_INCREF(Py_None);
8758 result = Py_None;
8759 }
8760 path_cleanup(&path);
8761 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008762}
8763#endif
8764
8765#ifdef HAVE_POSIX_FALLOCATE
8766PyDoc_STRVAR(posix_posix_fallocate__doc__,
8767"posix_fallocate(fd, offset, len)\n\n\
8768Ensures that enough disk space is allocated for the file specified by fd\n\
8769starting from offset and continuing for len bytes.");
8770
8771static PyObject *
8772posix_posix_fallocate(PyObject *self, PyObject *args)
8773{
8774 off_t len, offset;
8775 int res, fd;
8776
8777 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8778 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8779 return NULL;
8780
8781 Py_BEGIN_ALLOW_THREADS
8782 res = posix_fallocate(fd, offset, len);
8783 Py_END_ALLOW_THREADS
8784 if (res != 0) {
8785 errno = res;
8786 return posix_error();
8787 }
8788 Py_RETURN_NONE;
8789}
8790#endif
8791
8792#ifdef HAVE_POSIX_FADVISE
8793PyDoc_STRVAR(posix_posix_fadvise__doc__,
8794"posix_fadvise(fd, offset, len, advice)\n\n\
8795Announces an intention to access data in a specific pattern thus allowing\n\
8796the kernel to make optimizations.\n\
8797The advice applies to the region of the file specified by fd starting at\n\
8798offset and continuing for len bytes.\n\
8799advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8800POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8801POSIX_FADV_DONTNEED.");
8802
8803static PyObject *
8804posix_posix_fadvise(PyObject *self, PyObject *args)
8805{
8806 off_t len, offset;
8807 int res, fd, advice;
8808
8809 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8810 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8811 return NULL;
8812
8813 Py_BEGIN_ALLOW_THREADS
8814 res = posix_fadvise(fd, offset, len, advice);
8815 Py_END_ALLOW_THREADS
8816 if (res != 0) {
8817 errno = res;
8818 return posix_error();
8819 }
8820 Py_RETURN_NONE;
8821}
8822#endif
8823
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008824#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008825PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008826"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008827Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008828
Fred Drake762e2061999-08-26 17:23:54 +00008829/* Save putenv() parameters as values here, so we can collect them when they
8830 * get re-set with another call for the same key. */
8831static PyObject *posix_putenv_garbage;
8832
Tim Peters5aa91602002-01-30 05:46:57 +00008833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008834posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008835{
Victor Stinner84ae1182010-05-06 22:05:07 +00008836 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008837#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008838 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008839 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008840
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008842 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008843 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008845
Victor Stinner65170952011-11-22 22:16:17 +01008846 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008847 if (newstr == NULL) {
8848 PyErr_NoMemory();
8849 goto error;
8850 }
Victor Stinner65170952011-11-22 22:16:17 +01008851 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8852 PyErr_Format(PyExc_ValueError,
8853 "the environment variable is longer than %u characters",
8854 _MAX_ENV);
8855 goto error;
8856 }
8857
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008859 if (newenv == NULL)
8860 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008863 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008865#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008866 PyObject *os1, *os2;
8867 char *s1, *s2;
8868 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008869
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008870 if (!PyArg_ParseTuple(args,
8871 "O&O&:putenv",
8872 PyUnicode_FSConverter, &os1,
8873 PyUnicode_FSConverter, &os2))
8874 return NULL;
8875 s1 = PyBytes_AsString(os1);
8876 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008877
Victor Stinner65170952011-11-22 22:16:17 +01008878 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008879 if (newstr == NULL) {
8880 PyErr_NoMemory();
8881 goto error;
8882 }
8883
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008887 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008889#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008890
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 /* Install the first arg and newstr in posix_putenv_garbage;
8892 * this will cause previous value to be collected. This has to
8893 * happen after the real putenv() call because the old value
8894 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008895 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 /* really not much we can do; just leak */
8897 PyErr_Clear();
8898 }
8899 else {
8900 Py_DECREF(newstr);
8901 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008902
Martin v. Löwis011e8422009-05-05 04:43:17 +00008903#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 Py_DECREF(os1);
8905 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008906#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008907 Py_RETURN_NONE;
8908
8909error:
8910#ifndef MS_WINDOWS
8911 Py_DECREF(os1);
8912 Py_DECREF(os2);
8913#endif
8914 Py_XDECREF(newstr);
8915 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008916}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008917#endif /* putenv */
8918
Guido van Rossumc524d952001-10-19 01:31:59 +00008919#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008920PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008921"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008922Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008923
8924static PyObject *
8925posix_unsetenv(PyObject *self, PyObject *args)
8926{
Victor Stinner65170952011-11-22 22:16:17 +01008927 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008928#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008929 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008930#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008931
8932 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008933
Victor Stinner65170952011-11-22 22:16:17 +01008934 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008935 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008936
Victor Stinner984890f2011-11-24 13:53:38 +01008937#ifdef HAVE_BROKEN_UNSETENV
8938 unsetenv(PyBytes_AS_STRING(name));
8939#else
Victor Stinner65170952011-11-22 22:16:17 +01008940 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008941 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008942 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008943 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008944 }
Victor Stinner984890f2011-11-24 13:53:38 +01008945#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008946
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 /* Remove the key from posix_putenv_garbage;
8948 * this will cause it to be collected. This has to
8949 * happen after the real unsetenv() call because the
8950 * old value was still accessible until then.
8951 */
Victor Stinner65170952011-11-22 22:16:17 +01008952 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 /* really not much we can do; just leak */
8954 PyErr_Clear();
8955 }
Victor Stinner65170952011-11-22 22:16:17 +01008956 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008957 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008958}
8959#endif /* unsetenv */
8960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008961PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008962"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008963Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008964
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008966posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008967{
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 int code;
8969 char *message;
8970 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8971 return NULL;
8972 message = strerror(code);
8973 if (message == NULL) {
8974 PyErr_SetString(PyExc_ValueError,
8975 "strerror() argument out of range");
8976 return NULL;
8977 }
Victor Stinner1b579672011-12-17 05:47:23 +01008978 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008979}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008980
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008981
Guido van Rossumc9641791998-08-04 15:26:23 +00008982#ifdef HAVE_SYS_WAIT_H
8983
Fred Drake106c1a02002-04-23 15:58:02 +00008984#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008985PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008986"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008987Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008988
8989static PyObject *
8990posix_WCOREDUMP(PyObject *self, PyObject *args)
8991{
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 WAIT_TYPE status;
8993 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008994
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8996 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008997
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008999}
9000#endif /* WCOREDUMP */
9001
9002#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009003PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009004"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009005Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009006job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009007
9008static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009009posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009010{
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 WAIT_TYPE status;
9012 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009013
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9015 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009016
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009018}
9019#endif /* WIFCONTINUED */
9020
Guido van Rossumc9641791998-08-04 15:26:23 +00009021#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009022PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009023"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009024Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009025
9026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009027posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009028{
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 WAIT_TYPE status;
9030 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009031
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9033 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009034
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009036}
9037#endif /* WIFSTOPPED */
9038
9039#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009040PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009041"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009042Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009043
9044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009045posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009046{
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 WAIT_TYPE status;
9048 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009049
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9051 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009052
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009054}
9055#endif /* WIFSIGNALED */
9056
9057#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009058PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009059"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009060Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009061system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009062
9063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009064posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009065{
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 WAIT_TYPE status;
9067 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009068
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9070 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009071
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009073}
9074#endif /* WIFEXITED */
9075
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009076#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009077PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009078"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009079Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009080
9081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009082posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009083{
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 WAIT_TYPE status;
9085 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009086
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9088 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009089
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009091}
9092#endif /* WEXITSTATUS */
9093
9094#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009095PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009096"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009097Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009098value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009099
9100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009101posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009102{
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 WAIT_TYPE status;
9104 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009105
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9107 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009108
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009110}
9111#endif /* WTERMSIG */
9112
9113#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009114PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009115"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009116Return the signal that stopped the process that provided\n\
9117the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009118
9119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009120posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009121{
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 WAIT_TYPE status;
9123 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009124
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9126 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009127
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009129}
9130#endif /* WSTOPSIG */
9131
9132#endif /* HAVE_SYS_WAIT_H */
9133
9134
Thomas Wouters477c8d52006-05-27 19:21:47 +00009135#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009136#ifdef _SCO_DS
9137/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9138 needed definitions in sys/statvfs.h */
9139#define _SVID3
9140#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009141#include <sys/statvfs.h>
9142
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009143static PyObject*
9144_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9146 if (v == NULL)
9147 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009148
9149#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9151 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9152 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9156 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9157 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9158 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9159 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009160#else
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,
9164 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9165 PyStructSequence_SET_ITEM(v, 3,
9166 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9167 PyStructSequence_SET_ITEM(v, 4,
9168 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9169 PyStructSequence_SET_ITEM(v, 5,
9170 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9171 PyStructSequence_SET_ITEM(v, 6,
9172 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9173 PyStructSequence_SET_ITEM(v, 7,
9174 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9175 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9176 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009178 if (PyErr_Occurred()) {
9179 Py_DECREF(v);
9180 return NULL;
9181 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009184}
9185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009186PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009187"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009188Perform an fstatvfs system call on the given fd.\n\
9189Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009190
9191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009192posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009193{
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 int fd, res;
9195 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009196
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9198 return NULL;
9199 Py_BEGIN_ALLOW_THREADS
9200 res = fstatvfs(fd, &st);
9201 Py_END_ALLOW_THREADS
9202 if (res != 0)
9203 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009204
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009206}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009207#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009208
9209
Thomas Wouters477c8d52006-05-27 19:21:47 +00009210#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009211#include <sys/statvfs.h>
9212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009213PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009214"statvfs(path)\n\n\
9215Perform a statvfs system call on the given path.\n\
9216\n\
9217path may always be specified as a string.\n\
9218On some platforms, path may also be specified as an open file descriptor.\n\
9219 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009220
9221static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009222posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009223{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009224 static char *keywords[] = {"path", NULL};
9225 path_t path;
9226 int result;
9227 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009229
Larry Hastings9cf065c2012-06-22 16:30:09 -07009230 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009231 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009232#ifdef HAVE_FSTATVFS
9233 path.allow_fd = 1;
9234#endif
9235 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9236 path_converter, &path
9237 ))
9238 return NULL;
9239
9240 Py_BEGIN_ALLOW_THREADS
9241#ifdef HAVE_FSTATVFS
9242 if (path.fd != -1) {
9243#ifdef __APPLE__
9244 /* handle weak-linking on Mac OS X 10.3 */
9245 if (fstatvfs == NULL) {
9246 fd_specified("statvfs", path.fd);
9247 goto exit;
9248 }
9249#endif
9250 result = fstatvfs(path.fd, &st);
9251 }
9252 else
9253#endif
9254 result = statvfs(path.narrow, &st);
9255 Py_END_ALLOW_THREADS
9256
9257 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009258 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009259 goto exit;
9260 }
9261
9262 return_value = _pystatvfs_fromstructstatvfs(st);
9263
9264exit:
9265 path_cleanup(&path);
9266 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009267}
9268#endif /* HAVE_STATVFS */
9269
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009270#ifdef MS_WINDOWS
9271PyDoc_STRVAR(win32__getdiskusage__doc__,
9272"_getdiskusage(path) -> (total, free)\n\n\
9273Return disk usage statistics about the given path as (total, free) tuple.");
9274
9275static PyObject *
9276win32__getdiskusage(PyObject *self, PyObject *args)
9277{
9278 BOOL retval;
9279 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009280 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009281
Victor Stinner6139c1b2011-11-09 22:14:14 +01009282 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009283 return NULL;
9284
9285 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009286 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009287 Py_END_ALLOW_THREADS
9288 if (retval == 0)
9289 return PyErr_SetFromWindowsErr(0);
9290
9291 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9292}
9293#endif
9294
9295
Fred Drakec9680921999-12-13 16:37:25 +00009296/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9297 * It maps strings representing configuration variable names to
9298 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009299 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009300 * rarely-used constants. There are three separate tables that use
9301 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009302 *
9303 * This code is always included, even if none of the interfaces that
9304 * need it are included. The #if hackery needed to avoid it would be
9305 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009306 */
9307struct constdef {
9308 char *name;
9309 long value;
9310};
9311
Fred Drake12c6e2d1999-12-14 21:25:03 +00009312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009313conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009314 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009315{
Christian Heimes217cfd12007-12-02 14:31:20 +00009316 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009317 *valuep = PyLong_AS_LONG(arg);
9318 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009319 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009320 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009321 /* look up the value in the table using a binary search */
9322 size_t lo = 0;
9323 size_t mid;
9324 size_t hi = tablesize;
9325 int cmp;
9326 const char *confname;
9327 if (!PyUnicode_Check(arg)) {
9328 PyErr_SetString(PyExc_TypeError,
9329 "configuration names must be strings or integers");
9330 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009332 confname = _PyUnicode_AsString(arg);
9333 if (confname == NULL)
9334 return 0;
9335 while (lo < hi) {
9336 mid = (lo + hi) / 2;
9337 cmp = strcmp(confname, table[mid].name);
9338 if (cmp < 0)
9339 hi = mid;
9340 else if (cmp > 0)
9341 lo = mid + 1;
9342 else {
9343 *valuep = table[mid].value;
9344 return 1;
9345 }
9346 }
9347 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9348 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009350}
9351
9352
9353#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9354static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009355#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009357#endif
9358#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009360#endif
Fred Drakec9680921999-12-13 16:37:25 +00009361#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009406#ifdef _PC_ACL_ENABLED
9407 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9408#endif
9409#ifdef _PC_MIN_HOLE_SIZE
9410 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9411#endif
9412#ifdef _PC_ALLOC_SIZE_MIN
9413 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9414#endif
9415#ifdef _PC_REC_INCR_XFER_SIZE
9416 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9417#endif
9418#ifdef _PC_REC_MAX_XFER_SIZE
9419 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9420#endif
9421#ifdef _PC_REC_MIN_XFER_SIZE
9422 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9423#endif
9424#ifdef _PC_REC_XFER_ALIGN
9425 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9426#endif
9427#ifdef _PC_SYMLINK_MAX
9428 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9429#endif
9430#ifdef _PC_XATTR_ENABLED
9431 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9432#endif
9433#ifdef _PC_XATTR_EXISTS
9434 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9435#endif
9436#ifdef _PC_TIMESTAMP_RESOLUTION
9437 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9438#endif
Fred Drakec9680921999-12-13 16:37:25 +00009439};
9440
Fred Drakec9680921999-12-13 16:37:25 +00009441static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009442conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009443{
9444 return conv_confname(arg, valuep, posix_constants_pathconf,
9445 sizeof(posix_constants_pathconf)
9446 / sizeof(struct constdef));
9447}
9448#endif
9449
9450#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009451PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009452"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009453Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009454If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009455
9456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009457posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009458{
9459 PyObject *result = NULL;
9460 int name, fd;
9461
Fred Drake12c6e2d1999-12-14 21:25:03 +00009462 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9463 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009464 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009465
Stefan Krah0e803b32010-11-26 16:16:47 +00009466 errno = 0;
9467 limit = fpathconf(fd, name);
9468 if (limit == -1 && errno != 0)
9469 posix_error();
9470 else
9471 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009472 }
9473 return result;
9474}
9475#endif
9476
9477
9478#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009479PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009480"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009481Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009482If there is no limit, return -1.\n\
9483On some platforms, path may also be specified as an open file descriptor.\n\
9484 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009485
9486static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009487posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009488{
Georg Brandl306336b2012-06-24 12:55:33 +02009489 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009490 PyObject *result = NULL;
9491 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009492 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009493
Georg Brandl306336b2012-06-24 12:55:33 +02009494 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009495 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009496#ifdef HAVE_FPATHCONF
9497 path.allow_fd = 1;
9498#endif
9499 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9500 path_converter, &path,
9501 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009503
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009505#ifdef HAVE_FPATHCONF
9506 if (path.fd != -1)
9507 limit = fpathconf(path.fd, name);
9508 else
9509#endif
9510 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 if (limit == -1 && errno != 0) {
9512 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009513 /* could be a path or name problem */
9514 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009515 else
Victor Stinner292c8352012-10-30 02:17:38 +01009516 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 }
9518 else
9519 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009520 }
Georg Brandl306336b2012-06-24 12:55:33 +02009521 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009522 return result;
9523}
9524#endif
9525
9526#ifdef HAVE_CONFSTR
9527static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009528#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009531#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009533#endif
9534#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009536#endif
Fred Draked86ed291999-12-15 15:34:33 +00009537#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
9540#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009542#endif
9543#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009545#endif
9546#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009548#endif
Fred Drakec9680921999-12-13 16:37:25 +00009549#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
Fred Draked86ed291999-12-15 15:34:33 +00009573#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
Fred Drakec9680921999-12-13 16:37:25 +00009576#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
Fred Draked86ed291999-12-15 15:34:33 +00009579#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
9582#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
9585#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
9588#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009590#endif
Fred Drakec9680921999-12-13 16:37:25 +00009591#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
Fred Draked86ed291999-12-15 15:34:33 +00009639#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
9672#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
9675#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009677#endif
Fred Drakec9680921999-12-13 16:37:25 +00009678};
9679
9680static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009681conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009682{
9683 return conv_confname(arg, valuep, posix_constants_confstr,
9684 sizeof(posix_constants_confstr)
9685 / sizeof(struct constdef));
9686}
9687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009688PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009689"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009690Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009691
9692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009693posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009694{
9695 PyObject *result = NULL;
9696 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009697 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009698 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009699
Victor Stinnercb043522010-09-10 23:49:04 +00009700 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9701 return NULL;
9702
9703 errno = 0;
9704 len = confstr(name, buffer, sizeof(buffer));
9705 if (len == 0) {
9706 if (errno) {
9707 posix_error();
9708 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009709 }
9710 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009711 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009712 }
9713 }
Victor Stinnercb043522010-09-10 23:49:04 +00009714
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009715 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009716 char *buf = PyMem_Malloc(len);
9717 if (buf == NULL)
9718 return PyErr_NoMemory();
9719 confstr(name, buf, len);
9720 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9721 PyMem_Free(buf);
9722 }
9723 else
9724 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009725 return result;
9726}
9727#endif
9728
9729
9730#ifdef HAVE_SYSCONF
9731static struct constdef posix_constants_sysconf[] = {
9732#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
Fred Draked86ed291999-12-15 15:34:33 +00009762#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009764#endif
9765#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009767#endif
Fred Drakec9680921999-12-13 16:37:25 +00009768#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
Fred Drakec9680921999-12-13 16:37:25 +00009771#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
Fred Draked86ed291999-12-15 15:34:33 +00009786#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009788#endif
Fred Drakec9680921999-12-13 16:37:25 +00009789#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
Fred Draked86ed291999-12-15 15:34:33 +00009804#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009806#endif
Fred Drakec9680921999-12-13 16:37:25 +00009807#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
Fred Draked86ed291999-12-15 15:34:33 +00009876#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009878#endif
Fred Drakec9680921999-12-13 16:37:25 +00009879#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
Fred Draked86ed291999-12-15 15:34:33 +00009888#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009890#endif
Fred Drakec9680921999-12-13 16:37:25 +00009891#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
Fred Draked86ed291999-12-15 15:34:33 +00009894#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009896#endif
9897#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009899#endif
Fred Drakec9680921999-12-13 16:37:25 +00009900#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
Fred Draked86ed291999-12-15 15:34:33 +00009912#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
Fred Drakec9680921999-12-13 16:37:25 +00009915#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
Fred Draked86ed291999-12-15 15:34:33 +00009936#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
Fred Drakec9680921999-12-13 16:37:25 +00009939#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
Fred Draked86ed291999-12-15 15:34:33 +00009945#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009947#endif
Fred Drakec9680921999-12-13 16:37:25 +00009948#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
Fred Draked86ed291999-12-15 15:34:33 +00009975#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009977#endif
9978#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009980#endif
Fred Drakec9680921999-12-13 16:37:25 +00009981#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
Fred Draked86ed291999-12-15 15:34:33 +000010086#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010088#endif
Fred Drakec9680921999-12-13 16:37:25 +000010089#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224};
10225
10226static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010227conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010228{
10229 return conv_confname(arg, valuep, posix_constants_sysconf,
10230 sizeof(posix_constants_sysconf)
10231 / sizeof(struct constdef));
10232}
10233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010234PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010235"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010236Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010237
10238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010239posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010240{
10241 PyObject *result = NULL;
10242 int name;
10243
10244 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010245 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010246
10247 errno = 0;
10248 value = sysconf(name);
10249 if (value == -1 && errno != 0)
10250 posix_error();
10251 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010252 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010253 }
10254 return result;
10255}
10256#endif
10257
10258
Fred Drakebec628d1999-12-15 18:31:10 +000010259/* This code is used to ensure that the tables of configuration value names
10260 * are in sorted order as required by conv_confname(), and also to build the
10261 * the exported dictionaries that are used to publish information about the
10262 * names available on the host platform.
10263 *
10264 * Sorting the table at runtime ensures that the table is properly ordered
10265 * when used, even for platforms we're not able to test on. It also makes
10266 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010267 */
Fred Drakebec628d1999-12-15 18:31:10 +000010268
10269static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010270cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010271{
10272 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010274 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010276
10277 return strcmp(c1->name, c2->name);
10278}
10279
10280static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010281setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010283{
Fred Drakebec628d1999-12-15 18:31:10 +000010284 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010285 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010286
10287 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10288 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010289 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010291
Barry Warsaw3155db32000-04-13 15:20:40 +000010292 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 PyObject *o = PyLong_FromLong(table[i].value);
10294 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10295 Py_XDECREF(o);
10296 Py_DECREF(d);
10297 return -1;
10298 }
10299 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010300 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010301 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010302}
10303
Fred Drakebec628d1999-12-15 18:31:10 +000010304/* Return -1 on failure, 0 on success. */
10305static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010306setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010307{
10308#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010309 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010310 sizeof(posix_constants_pathconf)
10311 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010312 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010313 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010314#endif
10315#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010316 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010317 sizeof(posix_constants_confstr)
10318 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010319 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010320 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
10322#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010323 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010324 sizeof(posix_constants_sysconf)
10325 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010326 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010327 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010328#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010329 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010330}
Fred Draked86ed291999-12-15 15:34:33 +000010331
10332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010333PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010334"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010335Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010336in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010337
10338static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010339posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010340{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010341 abort();
10342 /*NOTREACHED*/
10343 Py_FatalError("abort() called from Python code didn't abort!");
10344 return NULL;
10345}
Fred Drakebec628d1999-12-15 18:31:10 +000010346
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010347#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010348PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010349"startfile(filepath [, operation]) - Start a file with its associated\n\
10350application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010351\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010352When \"operation\" is not specified or \"open\", this acts like\n\
10353double-clicking the file in Explorer, or giving the file name as an\n\
10354argument to the DOS \"start\" command: the file is opened with whatever\n\
10355application (if any) its extension is associated.\n\
10356When another \"operation\" is given, it specifies what should be done with\n\
10357the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010358\n\
10359startfile returns as soon as the associated application is launched.\n\
10360There is no option to wait for the application to close, and no way\n\
10361to retrieve the application's exit status.\n\
10362\n\
10363The filepath is relative to the current directory. If you want to use\n\
10364an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010365the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010366
10367static PyObject *
10368win32_startfile(PyObject *self, PyObject *args)
10369{
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 PyObject *ofilepath;
10371 char *filepath;
10372 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010373 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010375
Victor Stinnereb5657a2011-09-30 01:44:27 +020010376 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 if (!PyArg_ParseTuple(args, "U|s:startfile",
10378 &unipath, &operation)) {
10379 PyErr_Clear();
10380 goto normal;
10381 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010382
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010384 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010386 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 PyErr_Clear();
10388 operation = NULL;
10389 goto normal;
10390 }
10391 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010392
Victor Stinnereb5657a2011-09-30 01:44:27 +020010393 wpath = PyUnicode_AsUnicode(unipath);
10394 if (wpath == NULL)
10395 goto normal;
10396 if (uoperation) {
10397 woperation = PyUnicode_AsUnicode(uoperation);
10398 if (woperation == NULL)
10399 goto normal;
10400 }
10401 else
10402 woperation = NULL;
10403
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010405 rc = ShellExecuteW((HWND)0, woperation, wpath,
10406 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 Py_END_ALLOW_THREADS
10408
Victor Stinnereb5657a2011-09-30 01:44:27 +020010409 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010411 win32_error_object("startfile", unipath);
10412 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 }
10414 Py_INCREF(Py_None);
10415 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010416
10417normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10419 PyUnicode_FSConverter, &ofilepath,
10420 &operation))
10421 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010422 if (win32_warn_bytes_api()) {
10423 Py_DECREF(ofilepath);
10424 return NULL;
10425 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 filepath = PyBytes_AsString(ofilepath);
10427 Py_BEGIN_ALLOW_THREADS
10428 rc = ShellExecute((HWND)0, operation, filepath,
10429 NULL, NULL, SW_SHOWNORMAL);
10430 Py_END_ALLOW_THREADS
10431 if (rc <= (HINSTANCE)32) {
10432 PyObject *errval = win32_error("startfile", filepath);
10433 Py_DECREF(ofilepath);
10434 return errval;
10435 }
10436 Py_DECREF(ofilepath);
10437 Py_INCREF(Py_None);
10438 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010439}
10440#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010441
Martin v. Löwis438b5342002-12-27 10:16:42 +000010442#ifdef HAVE_GETLOADAVG
10443PyDoc_STRVAR(posix_getloadavg__doc__,
10444"getloadavg() -> (float, float, float)\n\n\
10445Return the number of processes in the system run queue averaged over\n\
10446the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10447was unobtainable");
10448
10449static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010450posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010451{
10452 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010453 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010454 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10455 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010456 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010457 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010458}
10459#endif
10460
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010461PyDoc_STRVAR(device_encoding__doc__,
10462"device_encoding(fd) -> str\n\n\
10463Return a string describing the encoding of the device\n\
10464if the output is a terminal; else return None.");
10465
10466static PyObject *
10467device_encoding(PyObject *self, PyObject *args)
10468{
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010470
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10472 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010473
10474 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010475}
10476
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010477#ifdef HAVE_SETRESUID
10478PyDoc_STRVAR(posix_setresuid__doc__,
10479"setresuid(ruid, euid, suid)\n\n\
10480Set the current process's real, effective, and saved user ids.");
10481
10482static PyObject*
10483posix_setresuid (PyObject *self, PyObject *args)
10484{
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010486 uid_t ruid, euid, suid;
10487 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10488 _Py_Uid_Converter, &ruid,
10489 _Py_Uid_Converter, &euid,
10490 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 return NULL;
10492 if (setresuid(ruid, euid, suid) < 0)
10493 return posix_error();
10494 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010495}
10496#endif
10497
10498#ifdef HAVE_SETRESGID
10499PyDoc_STRVAR(posix_setresgid__doc__,
10500"setresgid(rgid, egid, sgid)\n\n\
10501Set the current process's real, effective, and saved group ids.");
10502
10503static PyObject*
10504posix_setresgid (PyObject *self, PyObject *args)
10505{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010506 gid_t rgid, egid, sgid;
10507 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10508 _Py_Gid_Converter, &rgid,
10509 _Py_Gid_Converter, &egid,
10510 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 return NULL;
10512 if (setresgid(rgid, egid, sgid) < 0)
10513 return posix_error();
10514 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515}
10516#endif
10517
10518#ifdef HAVE_GETRESUID
10519PyDoc_STRVAR(posix_getresuid__doc__,
10520"getresuid() -> (ruid, euid, suid)\n\n\
10521Get tuple of the current process's real, effective, and saved user ids.");
10522
10523static PyObject*
10524posix_getresuid (PyObject *self, PyObject *noargs)
10525{
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 if (getresuid(&ruid, &euid, &suid) < 0)
10528 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010529 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10530 _PyLong_FromUid(euid),
10531 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010532}
10533#endif
10534
10535#ifdef HAVE_GETRESGID
10536PyDoc_STRVAR(posix_getresgid__doc__,
10537"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010538Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010539
10540static PyObject*
10541posix_getresgid (PyObject *self, PyObject *noargs)
10542{
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 if (getresgid(&rgid, &egid, &sgid) < 0)
10545 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010546 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10547 _PyLong_FromGid(egid),
10548 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010549}
10550#endif
10551
Benjamin Peterson9428d532011-09-14 11:45:52 -040010552#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010553
Benjamin Peterson799bd802011-08-31 22:15:17 -040010554PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010555"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10556Return the value of extended attribute attribute on path.\n\
10557\n\
10558path may be either a string or an open file descriptor.\n\
10559If follow_symlinks is False, and the last element of the path is a symbolic\n\
10560 link, getxattr will examine the symbolic link itself instead of the file\n\
10561 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010562
10563static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010565{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010566 path_t path;
10567 path_t attribute;
10568 int follow_symlinks = 1;
10569 PyObject *buffer = NULL;
10570 int i;
10571 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 memset(&path, 0, sizeof(path));
10574 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010575 path.function_name = "getxattr";
10576 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010577 path.allow_fd = 1;
10578 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10579 path_converter, &path,
10580 path_converter, &attribute,
10581 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10585 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010586
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 for (i = 0; ; i++) {
10588 void *ptr;
10589 ssize_t result;
10590 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10591 Py_ssize_t buffer_size = buffer_sizes[i];
10592 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010593 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010594 goto exit;
10595 }
10596 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10597 if (!buffer)
10598 goto exit;
10599 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010600
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 Py_BEGIN_ALLOW_THREADS;
10602 if (path.fd >= 0)
10603 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10604 else if (follow_symlinks)
10605 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10606 else
10607 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10608 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 if (result < 0) {
10611 Py_DECREF(buffer);
10612 buffer = NULL;
10613 if (errno == ERANGE)
10614 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010615 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 goto exit;
10617 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010618
Larry Hastings9cf065c2012-06-22 16:30:09 -070010619 if (result != buffer_size) {
10620 /* Can only shrink. */
10621 _PyBytes_Resize(&buffer, result);
10622 }
10623 break;
10624 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010625
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626exit:
10627 path_cleanup(&path);
10628 path_cleanup(&attribute);
10629 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630}
10631
10632PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10634Set extended attribute attribute on path to value.\n\
10635path may be either a string or an open file descriptor.\n\
10636If follow_symlinks is False, and the last element of the path is a symbolic\n\
10637 link, setxattr will modify the symbolic link itself instead of the file\n\
10638 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639
10640static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010641posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010642{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010643 path_t path;
10644 path_t attribute;
10645 Py_buffer value;
10646 int flags = 0;
10647 int follow_symlinks = 1;
10648 int result;
10649 PyObject *return_value = NULL;
10650 static char *keywords[] = {"path", "attribute", "value",
10651 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652
Larry Hastings9cf065c2012-06-22 16:30:09 -070010653 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010654 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010655 path.allow_fd = 1;
10656 memset(&attribute, 0, sizeof(attribute));
10657 memset(&value, 0, sizeof(value));
10658 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10659 keywords,
10660 path_converter, &path,
10661 path_converter, &attribute,
10662 &value, &flags,
10663 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010664 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665
10666 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10667 goto exit;
10668
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 if (path.fd > -1)
10671 result = fsetxattr(path.fd, attribute.narrow,
10672 value.buf, value.len, flags);
10673 else if (follow_symlinks)
10674 result = setxattr(path.narrow, attribute.narrow,
10675 value.buf, value.len, flags);
10676 else
10677 result = lsetxattr(path.narrow, attribute.narrow,
10678 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010679 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680
Larry Hastings9cf065c2012-06-22 16:30:09 -070010681 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010682 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010683 goto exit;
10684 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010685
Larry Hastings9cf065c2012-06-22 16:30:09 -070010686 return_value = Py_None;
10687 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010688
Larry Hastings9cf065c2012-06-22 16:30:09 -070010689exit:
10690 path_cleanup(&path);
10691 path_cleanup(&attribute);
10692 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010693
Larry Hastings9cf065c2012-06-22 16:30:09 -070010694 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695}
10696
10697PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010698"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10699Remove extended attribute attribute on path.\n\
10700path may be either a string or an open file descriptor.\n\
10701If follow_symlinks is False, and the last element of the path is a symbolic\n\
10702 link, removexattr will modify the symbolic link itself instead of the file\n\
10703 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
10705static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010707{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010708 path_t path;
10709 path_t attribute;
10710 int follow_symlinks = 1;
10711 int result;
10712 PyObject *return_value = NULL;
10713 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010714
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010716 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010718 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719 path.allow_fd = 1;
10720 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10721 keywords,
10722 path_converter, &path,
10723 path_converter, &attribute,
10724 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726
10727 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10728 goto exit;
10729
Benjamin Peterson799bd802011-08-31 22:15:17 -040010730 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010731 if (path.fd > -1)
10732 result = fremovexattr(path.fd, attribute.narrow);
10733 else if (follow_symlinks)
10734 result = removexattr(path.narrow, attribute.narrow);
10735 else
10736 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010738
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010740 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743
Larry Hastings9cf065c2012-06-22 16:30:09 -070010744 return_value = Py_None;
10745 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747exit:
10748 path_cleanup(&path);
10749 path_cleanup(&attribute);
10750
10751 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752}
10753
10754PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755"listxattr(path='.', *, follow_symlinks=True)\n\n\
10756Return a list of extended attributes on path.\n\
10757\n\
10758path may be either None, a string, or an open file descriptor.\n\
10759if path is None, listxattr will examine the current directory.\n\
10760If follow_symlinks is False, and the last element of the path is a symbolic\n\
10761 link, listxattr will examine the symbolic link itself instead of the file\n\
10762 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010763
10764static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 path_t path;
10768 int follow_symlinks = 1;
10769 Py_ssize_t i;
10770 PyObject *result = NULL;
10771 char *buffer = NULL;
10772 char *name;
10773 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010774
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010776 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 path.allow_fd = 1;
10778 path.fd = -1;
10779 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10780 path_converter, &path,
10781 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783
Larry Hastings9cf065c2012-06-22 16:30:09 -070010784 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10785 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010786
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787 name = path.narrow ? path.narrow : ".";
10788 for (i = 0; ; i++) {
10789 char *start, *trace, *end;
10790 ssize_t length;
10791 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10792 Py_ssize_t buffer_size = buffer_sizes[i];
10793 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010794 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010795 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 break;
10797 }
10798 buffer = PyMem_MALLOC(buffer_size);
10799 if (!buffer) {
10800 PyErr_NoMemory();
10801 break;
10802 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 Py_BEGIN_ALLOW_THREADS;
10805 if (path.fd > -1)
10806 length = flistxattr(path.fd, buffer, buffer_size);
10807 else if (follow_symlinks)
10808 length = listxattr(name, buffer, buffer_size);
10809 else
10810 length = llistxattr(name, buffer, buffer_size);
10811 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010812
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010814 if (errno == ERANGE) {
10815 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010816 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010818 }
Victor Stinner292c8352012-10-30 02:17:38 +010010819 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 break;
10821 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010822
Larry Hastings9cf065c2012-06-22 16:30:09 -070010823 result = PyList_New(0);
10824 if (!result) {
10825 goto exit;
10826 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010827
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 end = buffer + length;
10829 for (trace = start = buffer; trace != end; trace++) {
10830 if (!*trace) {
10831 int error;
10832 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10833 trace - start);
10834 if (!attribute) {
10835 Py_DECREF(result);
10836 result = NULL;
10837 goto exit;
10838 }
10839 error = PyList_Append(result, attribute);
10840 Py_DECREF(attribute);
10841 if (error) {
10842 Py_DECREF(result);
10843 result = NULL;
10844 goto exit;
10845 }
10846 start = trace + 1;
10847 }
10848 }
10849 break;
10850 }
10851exit:
10852 path_cleanup(&path);
10853 if (buffer)
10854 PyMem_FREE(buffer);
10855 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010856}
10857
Benjamin Peterson9428d532011-09-14 11:45:52 -040010858#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010860
Georg Brandl2fb477c2012-02-21 00:33:36 +010010861PyDoc_STRVAR(posix_urandom__doc__,
10862"urandom(n) -> str\n\n\
10863Return n random bytes suitable for cryptographic use.");
10864
10865static PyObject *
10866posix_urandom(PyObject *self, PyObject *args)
10867{
10868 Py_ssize_t size;
10869 PyObject *result;
10870 int ret;
10871
10872 /* Read arguments */
10873 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10874 return NULL;
10875 if (size < 0)
10876 return PyErr_Format(PyExc_ValueError,
10877 "negative argument not allowed");
10878 result = PyBytes_FromStringAndSize(NULL, size);
10879 if (result == NULL)
10880 return NULL;
10881
10882 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10883 PyBytes_GET_SIZE(result));
10884 if (ret == -1) {
10885 Py_DECREF(result);
10886 return NULL;
10887 }
10888 return result;
10889}
10890
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010891/* Terminal size querying */
10892
10893static PyTypeObject TerminalSizeType;
10894
10895PyDoc_STRVAR(TerminalSize_docstring,
10896 "A tuple of (columns, lines) for holding terminal window size");
10897
10898static PyStructSequence_Field TerminalSize_fields[] = {
10899 {"columns", "width of the terminal window in characters"},
10900 {"lines", "height of the terminal window in characters"},
10901 {NULL, NULL}
10902};
10903
10904static PyStructSequence_Desc TerminalSize_desc = {
10905 "os.terminal_size",
10906 TerminalSize_docstring,
10907 TerminalSize_fields,
10908 2,
10909};
10910
10911#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10912PyDoc_STRVAR(termsize__doc__,
10913 "Return the size of the terminal window as (columns, lines).\n" \
10914 "\n" \
10915 "The optional argument fd (default standard output) specifies\n" \
10916 "which file descriptor should be queried.\n" \
10917 "\n" \
10918 "If the file descriptor is not connected to a terminal, an OSError\n" \
10919 "is thrown.\n" \
10920 "\n" \
10921 "This function will only be defined if an implementation is\n" \
10922 "available for this system.\n" \
10923 "\n" \
10924 "shutil.get_terminal_size is the high-level function which should \n" \
10925 "normally be used, os.get_terminal_size is the low-level implementation.");
10926
10927static PyObject*
10928get_terminal_size(PyObject *self, PyObject *args)
10929{
10930 int columns, lines;
10931 PyObject *termsize;
10932
10933 int fd = fileno(stdout);
10934 /* Under some conditions stdout may not be connected and
10935 * fileno(stdout) may point to an invalid file descriptor. For example
10936 * GUI apps don't have valid standard streams by default.
10937 *
10938 * If this happens, and the optional fd argument is not present,
10939 * the ioctl below will fail returning EBADF. This is what we want.
10940 */
10941
10942 if (!PyArg_ParseTuple(args, "|i", &fd))
10943 return NULL;
10944
10945#ifdef TERMSIZE_USE_IOCTL
10946 {
10947 struct winsize w;
10948 if (ioctl(fd, TIOCGWINSZ, &w))
10949 return PyErr_SetFromErrno(PyExc_OSError);
10950 columns = w.ws_col;
10951 lines = w.ws_row;
10952 }
10953#endif /* TERMSIZE_USE_IOCTL */
10954
10955#ifdef TERMSIZE_USE_CONIO
10956 {
10957 DWORD nhandle;
10958 HANDLE handle;
10959 CONSOLE_SCREEN_BUFFER_INFO csbi;
10960 switch (fd) {
10961 case 0: nhandle = STD_INPUT_HANDLE;
10962 break;
10963 case 1: nhandle = STD_OUTPUT_HANDLE;
10964 break;
10965 case 2: nhandle = STD_ERROR_HANDLE;
10966 break;
10967 default:
10968 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10969 }
10970 handle = GetStdHandle(nhandle);
10971 if (handle == NULL)
10972 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10973 if (handle == INVALID_HANDLE_VALUE)
10974 return PyErr_SetFromWindowsErr(0);
10975
10976 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10977 return PyErr_SetFromWindowsErr(0);
10978
10979 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10980 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10981 }
10982#endif /* TERMSIZE_USE_CONIO */
10983
10984 termsize = PyStructSequence_New(&TerminalSizeType);
10985 if (termsize == NULL)
10986 return NULL;
10987 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10988 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10989 if (PyErr_Occurred()) {
10990 Py_DECREF(termsize);
10991 return NULL;
10992 }
10993 return termsize;
10994}
10995#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10996
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010997PyDoc_STRVAR(posix_cpu_count__doc__,
10998"cpu_count() -> integer\n\n\
10999Return the number of CPUs in the system, or None if this value cannot be\n\
11000established.");
11001
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011002static PyObject *
11003posix_cpu_count(PyObject *self)
11004{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011005 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011006#ifdef MS_WINDOWS
11007 SYSTEM_INFO sysinfo;
11008 GetSystemInfo(&sysinfo);
11009 ncpu = sysinfo.dwNumberOfProcessors;
11010#elif defined(__hpux)
11011 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11012#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11013 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011014#elif defined(__DragonFly__) || \
11015 defined(__OpenBSD__) || \
11016 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011017 defined(__NetBSD__) || \
11018 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011019 int mib[2];
11020 size_t len = sizeof(ncpu);
11021 mib[0] = CTL_HW;
11022 mib[1] = HW_NCPU;
11023 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11024 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011025#endif
11026 if (ncpu >= 1)
11027 return PyLong_FromLong(ncpu);
11028 else
11029 Py_RETURN_NONE;
11030}
11031
Victor Stinnerdaf45552013-08-28 00:53:59 +020011032PyDoc_STRVAR(get_inheritable__doc__,
11033 "get_inheritable(fd) -> bool\n" \
11034 "\n" \
11035 "Get the close-on-exe flag of the specified file descriptor.");
11036
11037static PyObject*
11038posix_get_inheritable(PyObject *self, PyObject *args)
11039{
11040 int fd;
11041 int inheritable;
11042
11043 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11044 return NULL;
11045
11046 if (!_PyVerify_fd(fd))
11047 return posix_error();
11048
11049 inheritable = _Py_get_inheritable(fd);
11050 if (inheritable < 0)
11051 return NULL;
11052 return PyBool_FromLong(inheritable);
11053}
11054
11055PyDoc_STRVAR(set_inheritable__doc__,
11056 "set_inheritable(fd, inheritable)\n" \
11057 "\n" \
11058 "Set the inheritable flag of the specified file descriptor.");
11059
11060static PyObject*
11061posix_set_inheritable(PyObject *self, PyObject *args)
11062{
11063 int fd, inheritable;
11064
11065 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11066 return NULL;
11067
11068 if (!_PyVerify_fd(fd))
11069 return posix_error();
11070
11071 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11072 return NULL;
11073 Py_RETURN_NONE;
11074}
11075
11076
11077#ifdef MS_WINDOWS
11078PyDoc_STRVAR(get_handle_inheritable__doc__,
11079 "get_handle_inheritable(fd) -> bool\n" \
11080 "\n" \
11081 "Get the close-on-exe flag of the specified file descriptor.");
11082
11083static PyObject*
11084posix_get_handle_inheritable(PyObject *self, PyObject *args)
11085{
11086 Py_intptr_t handle;
11087 DWORD flags;
11088
11089 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11090 return NULL;
11091
11092 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11093 PyErr_SetFromWindowsErr(0);
11094 return NULL;
11095 }
11096
11097 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11098}
11099
11100PyDoc_STRVAR(set_handle_inheritable__doc__,
11101 "set_handle_inheritable(fd, inheritable)\n" \
11102 "\n" \
11103 "Set the inheritable flag of the specified handle.");
11104
11105static PyObject*
11106posix_set_handle_inheritable(PyObject *self, PyObject *args)
11107{
11108 int inheritable = 1;
11109 Py_intptr_t handle;
11110 DWORD flags;
11111
11112 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11113 &handle, &inheritable))
11114 return NULL;
11115
11116 if (inheritable)
11117 flags = HANDLE_FLAG_INHERIT;
11118 else
11119 flags = 0;
11120 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11121 PyErr_SetFromWindowsErr(0);
11122 return NULL;
11123 }
11124 Py_RETURN_NONE;
11125}
11126#endif /* MS_WINDOWS */
11127
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011128
Larry Hastings31826802013-10-19 00:09:25 -070011129
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011130static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011131
11132 OS_STAT_METHODDEF
11133 OS_ACCESS_METHODDEF
11134 OS_TTYNAME_METHODDEF
11135
Larry Hastings9cf065c2012-06-22 16:30:09 -070011136 {"chdir", (PyCFunction)posix_chdir,
11137 METH_VARARGS | METH_KEYWORDS,
11138 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011139#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011140 {"chflags", (PyCFunction)posix_chflags,
11141 METH_VARARGS | METH_KEYWORDS,
11142 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011143#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 {"chmod", (PyCFunction)posix_chmod,
11145 METH_VARARGS | METH_KEYWORDS,
11146 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011147#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011149#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011150#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011151 {"chown", (PyCFunction)posix_chown,
11152 METH_VARARGS | METH_KEYWORDS,
11153 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011154#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011155#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011157#endif /* HAVE_LCHMOD */
11158#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011160#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011161#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011163#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011164#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011166#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011167#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011169#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011170#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011172#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11174 METH_NOARGS, posix_getcwd__doc__},
11175 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11176 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11178 {"link", (PyCFunction)posix_link,
11179 METH_VARARGS | METH_KEYWORDS,
11180 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011181#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011182 {"listdir", (PyCFunction)posix_listdir,
11183 METH_VARARGS | METH_KEYWORDS,
11184 posix_listdir__doc__},
11185 {"lstat", (PyCFunction)posix_lstat,
11186 METH_VARARGS | METH_KEYWORDS,
11187 posix_lstat__doc__},
11188 {"mkdir", (PyCFunction)posix_mkdir,
11189 METH_VARARGS | METH_KEYWORDS,
11190 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011191#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011193#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011194#ifdef HAVE_GETPRIORITY
11195 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11196#endif /* HAVE_GETPRIORITY */
11197#ifdef HAVE_SETPRIORITY
11198 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11199#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011200#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011201 {"readlink", (PyCFunction)posix_readlink,
11202 METH_VARARGS | METH_KEYWORDS,
11203 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011204#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011205#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011206 {"readlink", (PyCFunction)win_readlink,
11207 METH_VARARGS | METH_KEYWORDS,
11208 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011209#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011210 {"rename", (PyCFunction)posix_rename,
11211 METH_VARARGS | METH_KEYWORDS,
11212 posix_rename__doc__},
11213 {"replace", (PyCFunction)posix_replace,
11214 METH_VARARGS | METH_KEYWORDS,
11215 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011216 {"rmdir", (PyCFunction)posix_rmdir,
11217 METH_VARARGS | METH_KEYWORDS,
11218 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011220#if defined(HAVE_SYMLINK)
11221 {"symlink", (PyCFunction)posix_symlink,
11222 METH_VARARGS | METH_KEYWORDS,
11223 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011224#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011225#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011227#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011229#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011231#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011232 {"unlink", (PyCFunction)posix_unlink,
11233 METH_VARARGS | METH_KEYWORDS,
11234 posix_unlink__doc__},
11235 {"remove", (PyCFunction)posix_unlink,
11236 METH_VARARGS | METH_KEYWORDS,
11237 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011238 {"utime", (PyCFunction)posix_utime,
11239 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011240#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011242#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011244#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011246 {"execve", (PyCFunction)posix_execve,
11247 METH_VARARGS | METH_KEYWORDS,
11248 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011249#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011250#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11252 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011253#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011254#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011256#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011257#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011259#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011260#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011261#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011262 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11263 {"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 +020011264#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011265#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011266 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011267#endif
11268#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011269 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011270#endif
11271#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011272 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011273#endif
11274#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011275 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011276#endif
11277#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011278 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011279#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011280 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011281#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011282 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11283 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11284#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011285#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011286#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011288#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011289#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011291#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011292#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011294#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011295#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011297#endif /* HAVE_GETEUID */
11298#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011300#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011301#ifdef HAVE_GETGROUPLIST
11302 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11303#endif
Fred Drakec9680921999-12-13 16:37:25 +000011304#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011306#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011308#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011310#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011311#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011313#endif /* HAVE_GETPPID */
11314#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011316#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011317#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011319#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011320#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011322#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011323#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011325#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011326#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011328#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011329#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11331 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011332#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011333#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011335#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011336#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011338#endif /* HAVE_SETEUID */
11339#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011341#endif /* HAVE_SETEGID */
11342#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011344#endif /* HAVE_SETREUID */
11345#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011347#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011348#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011350#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011351#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011353#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011354#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011356#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011357#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011359#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011360#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011362#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011363#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011365#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011366#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011367 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011368#endif /* HAVE_WAIT3 */
11369#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011370 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011371#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011372#if defined(HAVE_WAITID) && !defined(__APPLE__)
11373 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11374#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011375#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011377#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011378#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011380#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011381#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011383#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011384#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011386#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011387#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011389#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011390#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011392#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011393 {"open", (PyCFunction)posix_open,\
11394 METH_VARARGS | METH_KEYWORDS,
11395 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11397 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11398 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11399 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011400 {"dup2", (PyCFunction)posix_dup2,
11401 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011402#ifdef HAVE_LOCKF
11403 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11404#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11406 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011407#ifdef HAVE_READV
11408 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11409#endif
11410#ifdef HAVE_PREAD
11411 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11412#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011414#ifdef HAVE_WRITEV
11415 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11416#endif
11417#ifdef HAVE_PWRITE
11418 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11419#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011420#ifdef HAVE_SENDFILE
11421 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11422 posix_sendfile__doc__},
11423#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011424 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011426#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011428#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011429#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011430 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011431#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011432#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011433 {"mkfifo", (PyCFunction)posix_mkfifo,
11434 METH_VARARGS | METH_KEYWORDS,
11435 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011436#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011437#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011438 {"mknod", (PyCFunction)posix_mknod,
11439 METH_VARARGS | METH_KEYWORDS,
11440 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011441#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011442#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11444 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11445 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011446#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011447#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011449#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011450#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011451 {"truncate", (PyCFunction)posix_truncate,
11452 METH_VARARGS | METH_KEYWORDS,
11453 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011454#endif
11455#ifdef HAVE_POSIX_FALLOCATE
11456 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11457#endif
11458#ifdef HAVE_POSIX_FADVISE
11459 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11460#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011461#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011463#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011464#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011466#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011468#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011470#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011471#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011473#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011474#ifdef HAVE_SYNC
11475 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11476#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011477#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011479#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011480#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011481#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011483#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011484#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011486#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011487#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011489#endif /* WIFSTOPPED */
11490#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011492#endif /* WIFSIGNALED */
11493#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011495#endif /* WIFEXITED */
11496#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011498#endif /* WEXITSTATUS */
11499#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011501#endif /* WTERMSIG */
11502#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011504#endif /* WSTOPSIG */
11505#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011506#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011508#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011509#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011510 {"statvfs", (PyCFunction)posix_statvfs,
11511 METH_VARARGS | METH_KEYWORDS,
11512 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011513#endif
Fred Drakec9680921999-12-13 16:37:25 +000011514#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011515 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011516#endif
11517#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011518 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011519#endif
11520#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011522#endif
11523#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011524 {"pathconf", (PyCFunction)posix_pathconf,
11525 METH_VARARGS | METH_KEYWORDS,
11526 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011527#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011529#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011531 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011532 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011533 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011534 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011535#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011536#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011538#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011539 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011540#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011542#endif
11543#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011545#endif
11546#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011548#endif
11549#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011551#endif
11552
Benjamin Peterson9428d532011-09-14 11:45:52 -040011553#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011554 {"setxattr", (PyCFunction)posix_setxattr,
11555 METH_VARARGS | METH_KEYWORDS,
11556 posix_setxattr__doc__},
11557 {"getxattr", (PyCFunction)posix_getxattr,
11558 METH_VARARGS | METH_KEYWORDS,
11559 posix_getxattr__doc__},
11560 {"removexattr", (PyCFunction)posix_removexattr,
11561 METH_VARARGS | METH_KEYWORDS,
11562 posix_removexattr__doc__},
11563 {"listxattr", (PyCFunction)posix_listxattr,
11564 METH_VARARGS | METH_KEYWORDS,
11565 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011566#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011567#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11568 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11569#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011570 {"cpu_count", (PyCFunction)posix_cpu_count,
11571 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011572 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11573 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11574#ifdef MS_WINDOWS
11575 {"get_handle_inheritable", posix_get_handle_inheritable,
11576 METH_VARARGS, get_handle_inheritable__doc__},
11577 {"set_handle_inheritable", posix_set_handle_inheritable,
11578 METH_VARARGS, set_handle_inheritable__doc__},
11579#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011581};
11582
11583
Brian Curtin52173d42010-12-02 18:29:18 +000011584#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011585static int
Brian Curtin52173d42010-12-02 18:29:18 +000011586enable_symlink()
11587{
11588 HANDLE tok;
11589 TOKEN_PRIVILEGES tok_priv;
11590 LUID luid;
11591 int meth_idx = 0;
11592
11593 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011594 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011595
11596 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011597 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011598
11599 tok_priv.PrivilegeCount = 1;
11600 tok_priv.Privileges[0].Luid = luid;
11601 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11602
11603 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11604 sizeof(TOKEN_PRIVILEGES),
11605 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011606 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011607
Brian Curtin3b4499c2010-12-28 14:31:47 +000011608 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11609 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011610}
11611#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11612
Barry Warsaw4a342091996-12-19 23:50:02 +000011613static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011614all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011615{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011616#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011617 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011618#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011619#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011620 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011621#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011622#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011623 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011624#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011625#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011626 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011627#endif
Fred Drakec9680921999-12-13 16:37:25 +000011628#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011629 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011630#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011631#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011632 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011633#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011634#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011635 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011636#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011637#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011638 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011639#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011640#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011641 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011642#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011643#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011644 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011645#endif
11646#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011647 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011648#endif
11649#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011650 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011651#endif
11652#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011653 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011654#endif
11655#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011656 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011657#endif
11658#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011659 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011660#endif
11661#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011662 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011663#endif
11664#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011665 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011666#endif
11667#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011668 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011669#endif
11670#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011671 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011672#endif
11673#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011674 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011675#endif
11676#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011677 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011678#endif
11679#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011680 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011681#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011682#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011683 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011684#endif
11685#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011686 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011687#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011688#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011689 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011690#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011691#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011692 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011693#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011694#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011695 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011696#endif
11697#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011698 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011699#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011700#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011701 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011702#endif
11703#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011704 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011705#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011706#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011707 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011708#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011709#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011710 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011711#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011712#ifdef O_TMPFILE
11713 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11714#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011715#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011716 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011717#endif
11718#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011719 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011720#endif
11721#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011722 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011723#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011724#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011725 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011726#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011727#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011728 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011729#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011730
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011731
Jesus Cea94363612012-06-22 18:32:07 +020011732#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011733 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011734#endif
11735#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011736 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011737#endif
11738
Tim Peters5aa91602002-01-30 05:46:57 +000011739/* MS Windows */
11740#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011741 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011742 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011743#endif
11744#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011745 /* Optimize for short life (keep in memory). */
11746 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011747 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011748#endif
11749#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011750 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011752#endif
11753#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011754 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011755 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011756#endif
11757#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011759 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011760#endif
11761
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011762/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011763#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 /* Send a SIGIO signal whenever input or output
11765 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011767#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011768#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011769 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011770 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011771#endif
11772#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011773 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011774 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011775#endif
11776#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011777 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011778 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011779#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011780#ifdef O_NOLINKS
11781 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011782 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011783#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011784#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011785 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011786 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011787#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011788
Victor Stinner8c62be82010-05-06 00:08:46 +000011789 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011790#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011791 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011792#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011793#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011794 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011795#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011796#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011797 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011798#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011799#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011800 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011801#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011802#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011803 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011804#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011805#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011806 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011807#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011808#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011809 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011810#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011811#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011812 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011813#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011814#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011815 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011816#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011817#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011818 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011819#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011820#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011821 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011822#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011823#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011824 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011825#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011826#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011827 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011828#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011829#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011830 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011831#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011832#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011833 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011834#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011835#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011836 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011837#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011838#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011839 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011840#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011841
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011842 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011843#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011844 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011845#endif /* ST_RDONLY */
11846#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011847 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011848#endif /* ST_NOSUID */
11849
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011850 /* FreeBSD sendfile() constants */
11851#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011852 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011853#endif
11854#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011855 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011856#endif
11857#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011858 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011859#endif
11860
Ross Lagerwall7807c352011-03-17 20:20:30 +020011861 /* constants for posix_fadvise */
11862#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011863 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011864#endif
11865#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011866 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011867#endif
11868#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011869 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011870#endif
11871#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011872 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011873#endif
11874#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011875 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011876#endif
11877#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011878 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011879#endif
11880
11881 /* constants for waitid */
11882#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011883 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11884 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11885 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011886#endif
11887#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011888 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011889#endif
11890#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011891 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011892#endif
11893#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011894 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011895#endif
11896#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011897 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011898#endif
11899#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011900 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011901#endif
11902#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011903 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011904#endif
11905#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011906 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011907#endif
11908
11909 /* constants for lockf */
11910#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011911 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011912#endif
11913#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011914 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011915#endif
11916#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011917 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011918#endif
11919#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011920 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011921#endif
11922
Guido van Rossum246bc171999-02-01 23:54:31 +000011923#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011924 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11925 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11926 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11927 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11928 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011929#endif
11930
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011931#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011932 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11933 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11934 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011935#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011936 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011937#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011938#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011939 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011940#endif
11941#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011942 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011943#endif
11944#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011945 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011946#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011947#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011948 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011949#endif
11950#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011951 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011952#endif
11953#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011954 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011955#endif
11956#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011957 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011958#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011959#endif
11960
Benjamin Peterson9428d532011-09-14 11:45:52 -040011961#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011962 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11963 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11964 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011965#endif
11966
Victor Stinner8b905bd2011-10-25 13:34:04 +020011967#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011968 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011969#endif
11970#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011971 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011972#endif
11973#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011974 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011975#endif
11976#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011977 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011978#endif
11979#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011980 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011981#endif
11982#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011983 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011984#endif
11985#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011986 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011987#endif
11988
Victor Stinner8c62be82010-05-06 00:08:46 +000011989 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011990}
11991
11992
Tim Peters5aa91602002-01-30 05:46:57 +000011993#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011994#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011995#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011996
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011997#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011998#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011999#define MODNAME "posix"
12000#endif
12001
Martin v. Löwis1a214512008-06-11 05:26:20 +000012002static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012003 PyModuleDef_HEAD_INIT,
12004 MODNAME,
12005 posix__doc__,
12006 -1,
12007 posix_methods,
12008 NULL,
12009 NULL,
12010 NULL,
12011 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012012};
12013
12014
Larry Hastings9cf065c2012-06-22 16:30:09 -070012015static char *have_functions[] = {
12016
12017#ifdef HAVE_FACCESSAT
12018 "HAVE_FACCESSAT",
12019#endif
12020
12021#ifdef HAVE_FCHDIR
12022 "HAVE_FCHDIR",
12023#endif
12024
12025#ifdef HAVE_FCHMOD
12026 "HAVE_FCHMOD",
12027#endif
12028
12029#ifdef HAVE_FCHMODAT
12030 "HAVE_FCHMODAT",
12031#endif
12032
12033#ifdef HAVE_FCHOWN
12034 "HAVE_FCHOWN",
12035#endif
12036
Larry Hastings00964ed2013-08-12 13:49:30 -040012037#ifdef HAVE_FCHOWNAT
12038 "HAVE_FCHOWNAT",
12039#endif
12040
Larry Hastings9cf065c2012-06-22 16:30:09 -070012041#ifdef HAVE_FEXECVE
12042 "HAVE_FEXECVE",
12043#endif
12044
12045#ifdef HAVE_FDOPENDIR
12046 "HAVE_FDOPENDIR",
12047#endif
12048
Georg Brandl306336b2012-06-24 12:55:33 +020012049#ifdef HAVE_FPATHCONF
12050 "HAVE_FPATHCONF",
12051#endif
12052
Larry Hastings9cf065c2012-06-22 16:30:09 -070012053#ifdef HAVE_FSTATAT
12054 "HAVE_FSTATAT",
12055#endif
12056
12057#ifdef HAVE_FSTATVFS
12058 "HAVE_FSTATVFS",
12059#endif
12060
Georg Brandl306336b2012-06-24 12:55:33 +020012061#ifdef HAVE_FTRUNCATE
12062 "HAVE_FTRUNCATE",
12063#endif
12064
Larry Hastings9cf065c2012-06-22 16:30:09 -070012065#ifdef HAVE_FUTIMENS
12066 "HAVE_FUTIMENS",
12067#endif
12068
12069#ifdef HAVE_FUTIMES
12070 "HAVE_FUTIMES",
12071#endif
12072
12073#ifdef HAVE_FUTIMESAT
12074 "HAVE_FUTIMESAT",
12075#endif
12076
12077#ifdef HAVE_LINKAT
12078 "HAVE_LINKAT",
12079#endif
12080
12081#ifdef HAVE_LCHFLAGS
12082 "HAVE_LCHFLAGS",
12083#endif
12084
12085#ifdef HAVE_LCHMOD
12086 "HAVE_LCHMOD",
12087#endif
12088
12089#ifdef HAVE_LCHOWN
12090 "HAVE_LCHOWN",
12091#endif
12092
12093#ifdef HAVE_LSTAT
12094 "HAVE_LSTAT",
12095#endif
12096
12097#ifdef HAVE_LUTIMES
12098 "HAVE_LUTIMES",
12099#endif
12100
12101#ifdef HAVE_MKDIRAT
12102 "HAVE_MKDIRAT",
12103#endif
12104
12105#ifdef HAVE_MKFIFOAT
12106 "HAVE_MKFIFOAT",
12107#endif
12108
12109#ifdef HAVE_MKNODAT
12110 "HAVE_MKNODAT",
12111#endif
12112
12113#ifdef HAVE_OPENAT
12114 "HAVE_OPENAT",
12115#endif
12116
12117#ifdef HAVE_READLINKAT
12118 "HAVE_READLINKAT",
12119#endif
12120
12121#ifdef HAVE_RENAMEAT
12122 "HAVE_RENAMEAT",
12123#endif
12124
12125#ifdef HAVE_SYMLINKAT
12126 "HAVE_SYMLINKAT",
12127#endif
12128
12129#ifdef HAVE_UNLINKAT
12130 "HAVE_UNLINKAT",
12131#endif
12132
12133#ifdef HAVE_UTIMENSAT
12134 "HAVE_UTIMENSAT",
12135#endif
12136
12137#ifdef MS_WINDOWS
12138 "MS_WINDOWS",
12139#endif
12140
12141 NULL
12142};
12143
12144
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012145PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012146INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012147{
Victor Stinner8c62be82010-05-06 00:08:46 +000012148 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012149 PyObject *list;
12150 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012151
Brian Curtin52173d42010-12-02 18:29:18 +000012152#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012153 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012154#endif
12155
Victor Stinner8c62be82010-05-06 00:08:46 +000012156 m = PyModule_Create(&posixmodule);
12157 if (m == NULL)
12158 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012159
Victor Stinner8c62be82010-05-06 00:08:46 +000012160 /* Initialize environ dictionary */
12161 v = convertenviron();
12162 Py_XINCREF(v);
12163 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12164 return NULL;
12165 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012166
Victor Stinner8c62be82010-05-06 00:08:46 +000012167 if (all_ins(m))
12168 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012169
Victor Stinner8c62be82010-05-06 00:08:46 +000012170 if (setup_confname_tables(m))
12171 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012172
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 Py_INCREF(PyExc_OSError);
12174 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012175
Guido van Rossumb3d39562000-01-31 18:41:26 +000012176#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012177 if (posix_putenv_garbage == NULL)
12178 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012179#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012180
Victor Stinner8c62be82010-05-06 00:08:46 +000012181 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012182#if defined(HAVE_WAITID) && !defined(__APPLE__)
12183 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012184 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12185 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012186#endif
12187
Christian Heimes25827622013-10-12 01:27:08 +020012188 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012189 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12190 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12191 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012192 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12193 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012194 structseq_new = StatResultType.tp_new;
12195 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012196
Christian Heimes25827622013-10-12 01:27:08 +020012197 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012198 if (PyStructSequence_InitType2(&StatVFSResultType,
12199 &statvfs_result_desc) < 0)
12200 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012201#ifdef NEED_TICKS_PER_SECOND
12202# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012203 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012204# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012205 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012206# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012207 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012208# endif
12209#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012210
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012211#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012212 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012213 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12214 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012215 SchedParamType.tp_new = sched_param_new;
12216#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012217
12218 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012219 if (PyStructSequence_InitType2(&TerminalSizeType,
12220 &TerminalSize_desc) < 0)
12221 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012222 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012223#if defined(HAVE_WAITID) && !defined(__APPLE__)
12224 Py_INCREF((PyObject*) &WaitidResultType);
12225 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12226#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012227 Py_INCREF((PyObject*) &StatResultType);
12228 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12229 Py_INCREF((PyObject*) &StatVFSResultType);
12230 PyModule_AddObject(m, "statvfs_result",
12231 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012232
12233#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012234 Py_INCREF(&SchedParamType);
12235 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012236#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012237
Larry Hastings605a62d2012-06-24 04:33:36 -070012238 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012239 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12240 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012241 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12242
12243 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012244 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12245 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012246 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12247
Thomas Wouters477c8d52006-05-27 19:21:47 +000012248#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012249 /*
12250 * Step 2 of weak-linking support on Mac OS X.
12251 *
12252 * The code below removes functions that are not available on the
12253 * currently active platform.
12254 *
12255 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012256 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012257 * OSX 10.4.
12258 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012259#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 if (fstatvfs == NULL) {
12261 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12262 return NULL;
12263 }
12264 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012265#endif /* HAVE_FSTATVFS */
12266
12267#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012268 if (statvfs == NULL) {
12269 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12270 return NULL;
12271 }
12272 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012273#endif /* HAVE_STATVFS */
12274
12275# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012276 if (lchown == NULL) {
12277 if (PyObject_DelAttrString(m, "lchown") == -1) {
12278 return NULL;
12279 }
12280 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012281#endif /* HAVE_LCHOWN */
12282
12283
12284#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012285
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012286 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012287 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12288
Larry Hastings6fe20b32012-04-19 15:07:49 -070012289 billion = PyLong_FromLong(1000000000);
12290 if (!billion)
12291 return NULL;
12292
Larry Hastings9cf065c2012-06-22 16:30:09 -070012293 /* suppress "function not used" warnings */
12294 {
12295 int ignored;
12296 fd_specified("", -1);
12297 follow_symlinks_specified("", 1);
12298 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12299 dir_fd_converter(Py_None, &ignored);
12300 dir_fd_unavailable(Py_None, &ignored);
12301 }
12302
12303 /*
12304 * provide list of locally available functions
12305 * so os.py can populate support_* lists
12306 */
12307 list = PyList_New(0);
12308 if (!list)
12309 return NULL;
12310 for (trace = have_functions; *trace; trace++) {
12311 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12312 if (!unicode)
12313 return NULL;
12314 if (PyList_Append(list, unicode))
12315 return NULL;
12316 Py_DECREF(unicode);
12317 }
12318 PyModule_AddObject(m, "_have_functions", list);
12319
12320 initialized = 1;
12321
Victor Stinner8c62be82010-05-06 00:08:46 +000012322 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012323}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012324
12325#ifdef __cplusplus
12326}
12327#endif