blob: 7e6bdc8879e353ed96effec2003538fae234083b [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;
Victor Stinner59799a82013-11-13 14:17:30 +0100832
833 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
834 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700835 Py_DECREF(unicode);
836 return 0;
837 }
Victor Stinner59799a82013-11-13 14:17:30 +0100838 if (length > 32767) {
839 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840 Py_DECREF(unicode);
841 return 0;
842 }
843
844 path->wide = wide;
845 path->narrow = NULL;
846 path->length = length;
847 path->object = o;
848 path->fd = -1;
849 path->cleanup = unicode;
850 return Py_CLEANUP_SUPPORTED;
851#else
852 int converted = PyUnicode_FSConverter(unicode, &bytes);
853 Py_DECREF(unicode);
854 if (!converted)
855 bytes = NULL;
856#endif
857 }
858 else {
859 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200860 if (PyObject_CheckBuffer(o))
861 bytes = PyBytes_FromObject(o);
862 else
863 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700864 if (!bytes) {
865 PyErr_Clear();
866 if (path->allow_fd) {
867 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200868 int result = _fd_converter(o, &fd,
869 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700870 if (result) {
871 path->wide = NULL;
872 path->narrow = NULL;
873 path->length = 0;
874 path->object = o;
875 path->fd = fd;
876 return result;
877 }
878 }
879 }
880 }
881
882 if (!bytes) {
883 if (!PyErr_Occurred())
884 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
885 return 0;
886 }
887
888#ifdef MS_WINDOWS
889 if (win32_warn_bytes_api()) {
890 Py_DECREF(bytes);
891 return 0;
892 }
893#endif
894
895 length = PyBytes_GET_SIZE(bytes);
896#ifdef MS_WINDOWS
897 if (length > MAX_PATH) {
898 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
899 Py_DECREF(bytes);
900 return 0;
901 }
902#endif
903
904 narrow = PyBytes_AS_STRING(bytes);
905 if (length != strlen(narrow)) {
906 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
907 Py_DECREF(bytes);
908 return 0;
909 }
910
911 path->wide = NULL;
912 path->narrow = narrow;
913 path->length = length;
914 path->object = o;
915 path->fd = -1;
916 path->cleanup = bytes;
917 return Py_CLEANUP_SUPPORTED;
918}
919
920static void
921argument_unavailable_error(char *function_name, char *argument_name) {
922 PyErr_Format(PyExc_NotImplementedError,
923 "%s%s%s unavailable on this platform",
924 (function_name != NULL) ? function_name : "",
925 (function_name != NULL) ? ": ": "",
926 argument_name);
927}
928
929static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200930dir_fd_unavailable(PyObject *o, void *p)
931{
932 int dir_fd;
933 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200935 if (dir_fd != DEFAULT_DIR_FD) {
936 argument_unavailable_error(NULL, "dir_fd");
937 return 0;
938 }
939 *(int *)p = dir_fd;
940 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941}
942
943static int
944fd_specified(char *function_name, int fd) {
945 if (fd == -1)
946 return 0;
947
948 argument_unavailable_error(function_name, "fd");
949 return 1;
950}
951
952static int
953follow_symlinks_specified(char *function_name, int follow_symlinks) {
954 if (follow_symlinks)
955 return 0;
956
957 argument_unavailable_error(function_name, "follow_symlinks");
958 return 1;
959}
960
961static int
962path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
963 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
964 PyErr_Format(PyExc_ValueError,
965 "%s: can't specify dir_fd without matching path",
966 function_name);
967 return 1;
968 }
969 return 0;
970}
971
972static int
973dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
974 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
975 PyErr_Format(PyExc_ValueError,
976 "%s: can't specify both dir_fd and fd",
977 function_name);
978 return 1;
979 }
980 return 0;
981}
982
983static int
984fd_and_follow_symlinks_invalid(char *function_name, int fd,
985 int follow_symlinks) {
986 if ((fd > 0) && (!follow_symlinks)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: cannot use fd and follow_symlinks together",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
995static int
996dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
997 int follow_symlinks) {
998 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
999 PyErr_Format(PyExc_ValueError,
1000 "%s: cannot use dir_fd and follow_symlinks together",
1001 function_name);
1002 return 1;
1003 }
1004 return 0;
1005}
1006
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001007/* A helper used by a number of POSIX-only functions */
1008#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001009static int
1010_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001011{
1012#if !defined(HAVE_LARGEFILE_SUPPORT)
1013 *((off_t*)addr) = PyLong_AsLong(arg);
1014#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001015 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001016#endif
1017 if (PyErr_Occurred())
1018 return 0;
1019 return 1;
1020}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001021#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001022
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001023#if defined _MSC_VER && _MSC_VER >= 1400
1024/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001025 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001026 * Normally, an invalid fd is likely to be a C program error and therefore
1027 * an assertion can be useful, but it does contradict the POSIX standard
1028 * which for write(2) states:
1029 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1030 * "[EBADF] The fildes argument is not a valid file descriptor open for
1031 * writing."
1032 * Furthermore, python allows the user to enter any old integer
1033 * as a fd and should merely raise a python exception on error.
1034 * The Microsoft CRT doesn't provide an official way to check for the
1035 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001036 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001037 * internal structures involved.
1038 * The structures below must be updated for each version of visual studio
1039 * according to the file internal.h in the CRT source, until MS comes
1040 * up with a less hacky way to do this.
1041 * (all of this is to avoid globally modifying the CRT behaviour using
1042 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1043 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001044/* The actual size of the structure is determined at runtime.
1045 * Only the first items must be present.
1046 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001047typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001048 intptr_t osfhnd;
1049 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001050} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001051
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001052extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001053#define IOINFO_L2E 5
1054#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1055#define IOINFO_ARRAYS 64
1056#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1057#define FOPEN 0x01
1058#define _NO_CONSOLE_FILENO (intptr_t)-2
1059
1060/* This function emulates what the windows CRT does to validate file handles */
1061int
1062_PyVerify_fd(int fd)
1063{
Victor Stinner8c62be82010-05-06 00:08:46 +00001064 const int i1 = fd >> IOINFO_L2E;
1065 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001066
Antoine Pitrou22e41552010-08-15 18:07:50 +00001067 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 /* Determine the actual size of the ioinfo structure,
1070 * as used by the CRT loaded in memory
1071 */
1072 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1073 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1074 }
1075 if (sizeof_ioinfo == 0) {
1076 /* This should not happen... */
1077 goto fail;
1078 }
1079
1080 /* See that it isn't a special CLEAR fileno */
1081 if (fd != _NO_CONSOLE_FILENO) {
1082 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1083 * we check pointer validity and other info
1084 */
1085 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1086 /* finally, check that the file is open */
1087 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1088 if (info->osfile & FOPEN) {
1089 return 1;
1090 }
1091 }
1092 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001093 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001094 errno = EBADF;
1095 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001096}
1097
1098/* the special case of checking dup2. The target fd must be in a sensible range */
1099static int
1100_PyVerify_fd_dup2(int fd1, int fd2)
1101{
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 if (!_PyVerify_fd(fd1))
1103 return 0;
1104 if (fd2 == _NO_CONSOLE_FILENO)
1105 return 0;
1106 if ((unsigned)fd2 < _NHANDLE_)
1107 return 1;
1108 else
1109 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001110}
1111#else
1112/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1113#define _PyVerify_fd_dup2(A, B) (1)
1114#endif
1115
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001116#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001117/* The following structure was copied from
1118 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1119 include doesn't seem to be present in the Windows SDK (at least as included
1120 with Visual Studio Express). */
1121typedef struct _REPARSE_DATA_BUFFER {
1122 ULONG ReparseTag;
1123 USHORT ReparseDataLength;
1124 USHORT Reserved;
1125 union {
1126 struct {
1127 USHORT SubstituteNameOffset;
1128 USHORT SubstituteNameLength;
1129 USHORT PrintNameOffset;
1130 USHORT PrintNameLength;
1131 ULONG Flags;
1132 WCHAR PathBuffer[1];
1133 } SymbolicLinkReparseBuffer;
1134
1135 struct {
1136 USHORT SubstituteNameOffset;
1137 USHORT SubstituteNameLength;
1138 USHORT PrintNameOffset;
1139 USHORT PrintNameLength;
1140 WCHAR PathBuffer[1];
1141 } MountPointReparseBuffer;
1142
1143 struct {
1144 UCHAR DataBuffer[1];
1145 } GenericReparseBuffer;
1146 };
1147} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1148
1149#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1150 GenericReparseBuffer)
1151#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1152
1153static int
Brian Curtind25aef52011-06-13 15:16:04 -05001154win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001155{
1156 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1157 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1158 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001159
1160 if (0 == DeviceIoControl(
1161 reparse_point_handle,
1162 FSCTL_GET_REPARSE_POINT,
1163 NULL, 0, /* in buffer */
1164 target_buffer, sizeof(target_buffer),
1165 &n_bytes_returned,
1166 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001167 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001168
1169 if (reparse_tag)
1170 *reparse_tag = rdb->ReparseTag;
1171
Brian Curtind25aef52011-06-13 15:16:04 -05001172 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001173}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001174
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001175#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001176
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001178#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001179/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001180** environ directly, we must obtain it with _NSGetEnviron(). See also
1181** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001182*/
1183#include <crt_externs.h>
1184static char **environ;
1185#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001187#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188
Barry Warsaw53699e91996-12-10 23:23:01 +00001189static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001190convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191{
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001193#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001194 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001196 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001197#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001198
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 d = PyDict_New();
1200 if (d == NULL)
1201 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001202#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001203 if (environ == NULL)
1204 environ = *_NSGetEnviron();
1205#endif
1206#ifdef MS_WINDOWS
1207 /* _wenviron must be initialized in this way if the program is started
1208 through main() instead of wmain(). */
1209 _wgetenv(L"");
1210 if (_wenviron == NULL)
1211 return d;
1212 /* This part ignores errors */
1213 for (e = _wenviron; *e != NULL; e++) {
1214 PyObject *k;
1215 PyObject *v;
1216 wchar_t *p = wcschr(*e, L'=');
1217 if (p == NULL)
1218 continue;
1219 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1220 if (k == NULL) {
1221 PyErr_Clear();
1222 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001223 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1225 if (v == NULL) {
1226 PyErr_Clear();
1227 Py_DECREF(k);
1228 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001229 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001230 if (PyDict_GetItem(d, k) == NULL) {
1231 if (PyDict_SetItem(d, k, v) != 0)
1232 PyErr_Clear();
1233 }
1234 Py_DECREF(k);
1235 Py_DECREF(v);
1236 }
1237#else
1238 if (environ == NULL)
1239 return d;
1240 /* This part ignores errors */
1241 for (e = environ; *e != NULL; e++) {
1242 PyObject *k;
1243 PyObject *v;
1244 char *p = strchr(*e, '=');
1245 if (p == NULL)
1246 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001247 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 if (k == NULL) {
1249 PyErr_Clear();
1250 continue;
1251 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001252 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (v == NULL) {
1254 PyErr_Clear();
1255 Py_DECREF(k);
1256 continue;
1257 }
1258 if (PyDict_GetItem(d, k) == NULL) {
1259 if (PyDict_SetItem(d, k, v) != 0)
1260 PyErr_Clear();
1261 }
1262 Py_DECREF(k);
1263 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001264 }
1265#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269/* Set a POSIX-specific error from errno, and return NULL */
1270
Barry Warsawd58d7641998-07-23 16:14:40 +00001271static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001272posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001273{
Victor Stinner8c62be82010-05-06 00:08:46 +00001274 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275}
Mark Hammondef8b6542001-05-13 08:04:26 +00001276
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001277#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001278static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001279win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001280{
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 /* XXX We should pass the function name along in the future.
1282 (winreg.c also wants to pass the function name.)
1283 This would however require an additional param to the
1284 Windows error object, which is non-trivial.
1285 */
1286 errno = GetLastError();
1287 if (filename)
1288 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1289 else
1290 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001291}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001292
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001293static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001294win32_error_object(char* function, PyObject* filename)
1295{
1296 /* XXX - see win32_error for comments on 'function' */
1297 errno = GetLastError();
1298 if (filename)
1299 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001300 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001301 errno,
1302 filename);
1303 else
1304 return PyErr_SetFromWindowsErr(errno);
1305}
1306
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001307#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308
Larry Hastings9cf065c2012-06-22 16:30:09 -07001309static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001310path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001311{
1312#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001313 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1314 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001315#else
Victor Stinner292c8352012-10-30 02:17:38 +01001316 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001317#endif
1318}
1319
Larry Hastings31826802013-10-19 00:09:25 -07001320
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001321/* POSIX generic methods */
1322
Barry Warsaw53699e91996-12-10 23:23:01 +00001323static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001324posix_fildes(PyObject *fdobj, int (*func)(int))
1325{
Victor Stinner8c62be82010-05-06 00:08:46 +00001326 int fd;
1327 int res;
1328 fd = PyObject_AsFileDescriptor(fdobj);
1329 if (fd < 0)
1330 return NULL;
1331 if (!_PyVerify_fd(fd))
1332 return posix_error();
1333 Py_BEGIN_ALLOW_THREADS
1334 res = (*func)(fd);
1335 Py_END_ALLOW_THREADS
1336 if (res < 0)
1337 return posix_error();
1338 Py_INCREF(Py_None);
1339 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001340}
Guido van Rossum21142a01999-01-08 21:05:37 +00001341
1342static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001343posix_1str(const char *func_name, PyObject *args, char *format,
1344 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345{
Victor Stinner292c8352012-10-30 02:17:38 +01001346 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001348 memset(&path, 0, sizeof(path));
1349 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001351 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001354 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001356 if (res < 0) {
1357 path_error(&path);
1358 path_cleanup(&path);
1359 return NULL;
1360 }
1361 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 Py_INCREF(Py_None);
1363 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364}
1365
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001367#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368/* This is a reimplementation of the C library's chdir function,
1369 but one that produces Win32 errors instead of DOS error codes.
1370 chdir is essentially a wrapper around SetCurrentDirectory; however,
1371 it also needs to set "magic" environment variables indicating
1372 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001373static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001374win32_chdir(LPCSTR path)
1375{
Victor Stinner8c62be82010-05-06 00:08:46 +00001376 char new_path[MAX_PATH+1];
1377 int result;
1378 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001379
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 if(!SetCurrentDirectoryA(path))
1381 return FALSE;
1382 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1383 if (!result)
1384 return FALSE;
1385 /* In the ANSI API, there should not be any paths longer
1386 than MAX_PATH. */
1387 assert(result <= MAX_PATH+1);
1388 if (strncmp(new_path, "\\\\", 2) == 0 ||
1389 strncmp(new_path, "//", 2) == 0)
1390 /* UNC path, nothing to do. */
1391 return TRUE;
1392 env[1] = new_path[0];
1393 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001394}
1395
1396/* The Unicode version differs from the ANSI version
1397 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001398static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399win32_wchdir(LPCWSTR path)
1400{
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1402 int result;
1403 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404
Victor Stinner8c62be82010-05-06 00:08:46 +00001405 if(!SetCurrentDirectoryW(path))
1406 return FALSE;
1407 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1408 if (!result)
1409 return FALSE;
1410 if (result > MAX_PATH+1) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001411 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001412 if (!new_path) {
1413 SetLastError(ERROR_OUTOFMEMORY);
1414 return FALSE;
1415 }
1416 result = GetCurrentDirectoryW(result, new_path);
1417 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001418 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 return FALSE;
1420 }
1421 }
1422 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1423 wcsncmp(new_path, L"//", 2) == 0)
1424 /* UNC path, nothing to do. */
1425 return TRUE;
1426 env[1] = new_path[0];
1427 result = SetEnvironmentVariableW(env, new_path);
1428 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001429 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431}
1432#endif
1433
Martin v. Löwis14694662006-02-03 12:54:16 +00001434#ifdef MS_WINDOWS
1435/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1436 - time stamps are restricted to second resolution
1437 - file modification times suffer from forth-and-back conversions between
1438 UTC and local time
1439 Therefore, we implement our own stat, based on the Win32 API directly.
1440*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001441#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001442
1443struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001444 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001445 __int64 st_ino;
1446 unsigned short st_mode;
1447 int st_nlink;
1448 int st_uid;
1449 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001450 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001451 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001452 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001454 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001455 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001456 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001457 int st_ctime_nsec;
1458};
1459
1460static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1461
1462static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001463FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001464{
Victor Stinner8c62be82010-05-06 00:08:46 +00001465 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1466 /* Cannot simply cast and dereference in_ptr,
1467 since it might not be aligned properly */
1468 __int64 in;
1469 memcpy(&in, in_ptr, sizeof(in));
1470 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001471 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001472}
1473
Thomas Wouters477c8d52006-05-27 19:21:47 +00001474static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001475time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001476{
Victor Stinner8c62be82010-05-06 00:08:46 +00001477 /* XXX endianness */
1478 __int64 out;
1479 out = time_in + secs_between_epochs;
1480 out = out * 10000000 + nsec_in / 100;
1481 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482}
1483
Martin v. Löwis14694662006-02-03 12:54:16 +00001484/* Below, we *know* that ugo+r is 0444 */
1485#if _S_IREAD != 0400
1486#error Unsupported C library
1487#endif
1488static int
1489attributes_to_mode(DWORD attr)
1490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 int m = 0;
1492 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1493 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1494 else
1495 m |= _S_IFREG;
1496 if (attr & FILE_ATTRIBUTE_READONLY)
1497 m |= 0444;
1498 else
1499 m |= 0666;
1500 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001501}
1502
1503static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001504attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001505{
Victor Stinner8c62be82010-05-06 00:08:46 +00001506 memset(result, 0, sizeof(*result));
1507 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1508 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001509 result->st_dev = info->dwVolumeSerialNumber;
1510 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1512 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1513 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001514 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001515 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001516 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1517 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001518 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001519 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001520 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001522
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001524}
1525
Guido van Rossumd8faa362007-04-27 19:54:29 +00001526static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001527attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001528{
Victor Stinner8c62be82010-05-06 00:08:46 +00001529 HANDLE hFindFile;
1530 WIN32_FIND_DATAA FileData;
1531 hFindFile = FindFirstFileA(pszFile, &FileData);
1532 if (hFindFile == INVALID_HANDLE_VALUE)
1533 return FALSE;
1534 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001535 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001536 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001537 info->dwFileAttributes = FileData.dwFileAttributes;
1538 info->ftCreationTime = FileData.ftCreationTime;
1539 info->ftLastAccessTime = FileData.ftLastAccessTime;
1540 info->ftLastWriteTime = FileData.ftLastWriteTime;
1541 info->nFileSizeHigh = FileData.nFileSizeHigh;
1542 info->nFileSizeLow = FileData.nFileSizeLow;
1543/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1545 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001547}
1548
1549static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001550attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001551{
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 HANDLE hFindFile;
1553 WIN32_FIND_DATAW FileData;
1554 hFindFile = FindFirstFileW(pszFile, &FileData);
1555 if (hFindFile == INVALID_HANDLE_VALUE)
1556 return FALSE;
1557 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001559 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560 info->dwFileAttributes = FileData.dwFileAttributes;
1561 info->ftCreationTime = FileData.ftCreationTime;
1562 info->ftLastAccessTime = FileData.ftLastAccessTime;
1563 info->ftLastWriteTime = FileData.ftLastWriteTime;
1564 info->nFileSizeHigh = FileData.nFileSizeHigh;
1565 info->nFileSizeLow = FileData.nFileSizeLow;
1566/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001567 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1568 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001570}
1571
Brian Curtind25aef52011-06-13 15:16:04 -05001572/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001573static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001574static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1575 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576static int
Brian Curtind25aef52011-06-13 15:16:04 -05001577check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001578{
Brian Curtind25aef52011-06-13 15:16:04 -05001579 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001580 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1581 DWORD);
1582
Brian Curtind25aef52011-06-13 15:16:04 -05001583 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001584 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001585 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001586 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001587 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1588 "GetFinalPathNameByHandleA");
1589 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1590 "GetFinalPathNameByHandleW");
1591 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1592 Py_GetFinalPathNameByHandleW;
1593 }
1594 return has_GetFinalPathNameByHandle;
1595}
1596
1597static BOOL
1598get_target_path(HANDLE hdl, wchar_t **target_path)
1599{
1600 int buf_size, result_length;
1601 wchar_t *buf;
1602
1603 /* We have a good handle to the target, use it to determine
1604 the target path name (then we'll call lstat on it). */
1605 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1606 VOLUME_NAME_DOS);
1607 if(!buf_size)
1608 return FALSE;
1609
Victor Stinnerb6404912013-07-07 16:21:41 +02001610 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001611 if (!buf) {
1612 SetLastError(ERROR_OUTOFMEMORY);
1613 return FALSE;
1614 }
1615
Brian Curtind25aef52011-06-13 15:16:04 -05001616 result_length = Py_GetFinalPathNameByHandleW(hdl,
1617 buf, buf_size, VOLUME_NAME_DOS);
1618
1619 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001620 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001621 return FALSE;
1622 }
1623
1624 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001625 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001626 return FALSE;
1627 }
1628
1629 buf[result_length] = 0;
1630
1631 *target_path = buf;
1632 return TRUE;
1633}
1634
1635static int
1636win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1637 BOOL traverse);
1638static int
1639win32_xstat_impl(const char *path, struct win32_stat *result,
1640 BOOL traverse)
1641{
Victor Stinner26de69d2011-06-17 15:15:38 +02001642 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001643 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001645 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001646 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001647 const char *dot;
1648
Brian Curtind25aef52011-06-13 15:16:04 -05001649 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001650 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1651 traverse reparse point. */
1652 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 }
1654
Brian Curtinf5e76d02010-11-24 13:14:05 +00001655 hFile = CreateFileA(
1656 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001657 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001658 0, /* share mode */
1659 NULL, /* security attributes */
1660 OPEN_EXISTING,
1661 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001662 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1663 Because of this, calls like GetFinalPathNameByHandle will return
1664 the symlink path agin and not the actual final path. */
1665 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1666 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001667 NULL);
1668
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 /* Either the target doesn't exist, or we don't have access to
1671 get a handle to it. If the former, we need to return an error.
1672 If the latter, we can use attributes_from_dir. */
1673 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 return -1;
1675 /* Could not get attributes on open file. Fall back to
1676 reading the directory. */
1677 if (!attributes_from_dir(path, &info, &reparse_tag))
1678 /* Very strange. This should not fail now */
1679 return -1;
1680 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1681 if (traverse) {
1682 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001684 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 } else {
1688 if (!GetFileInformationByHandle(hFile, &info)) {
1689 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001690 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001691 }
1692 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001693 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1694 return -1;
1695
1696 /* Close the outer open file handle now that we're about to
1697 reopen it with different flags. */
1698 if (!CloseHandle(hFile))
1699 return -1;
1700
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001701 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001702 /* In order to call GetFinalPathNameByHandle we need to open
1703 the file without the reparse handling flag set. */
1704 hFile2 = CreateFileA(
1705 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1706 NULL, OPEN_EXISTING,
1707 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1708 NULL);
1709 if (hFile2 == INVALID_HANDLE_VALUE)
1710 return -1;
1711
1712 if (!get_target_path(hFile2, &target_path))
1713 return -1;
1714
1715 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001716 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001717 return code;
1718 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001719 } else
1720 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001723
1724 /* Set S_IEXEC if it is an .exe, .bat, ... */
1725 dot = strrchr(path, '.');
1726 if (dot) {
1727 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1728 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1729 result->st_mode |= 0111;
1730 }
1731 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732}
1733
1734static int
Brian Curtind25aef52011-06-13 15:16:04 -05001735win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1736 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001737{
1738 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001739 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001740 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001742 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001743 const wchar_t *dot;
1744
Brian Curtind25aef52011-06-13 15:16:04 -05001745 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001746 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1747 traverse reparse point. */
1748 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 }
1750
Brian Curtinf5e76d02010-11-24 13:14:05 +00001751 hFile = CreateFileW(
1752 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001753 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001754 0, /* share mode */
1755 NULL, /* security attributes */
1756 OPEN_EXISTING,
1757 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001758 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1759 Because of this, calls like GetFinalPathNameByHandle will return
1760 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001761 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001762 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001763 NULL);
1764
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001766 /* Either the target doesn't exist, or we don't have access to
1767 get a handle to it. If the former, we need to return an error.
1768 If the latter, we can use attributes_from_dir. */
1769 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770 return -1;
1771 /* Could not get attributes on open file. Fall back to
1772 reading the directory. */
1773 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1774 /* Very strange. This should not fail now */
1775 return -1;
1776 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1777 if (traverse) {
1778 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001779 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001780 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001781 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001782 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001783 } else {
1784 if (!GetFileInformationByHandle(hFile, &info)) {
1785 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001786 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001787 }
1788 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001789 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1790 return -1;
1791
1792 /* Close the outer open file handle now that we're about to
1793 reopen it with different flags. */
1794 if (!CloseHandle(hFile))
1795 return -1;
1796
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001797 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001798 /* In order to call GetFinalPathNameByHandle we need to open
1799 the file without the reparse handling flag set. */
1800 hFile2 = CreateFileW(
1801 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1802 NULL, OPEN_EXISTING,
1803 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1804 NULL);
1805 if (hFile2 == INVALID_HANDLE_VALUE)
1806 return -1;
1807
1808 if (!get_target_path(hFile2, &target_path))
1809 return -1;
1810
1811 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001812 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001813 return code;
1814 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001815 } else
1816 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001817 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001819
1820 /* Set S_IEXEC if it is an .exe, .bat, ... */
1821 dot = wcsrchr(path, '.');
1822 if (dot) {
1823 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1824 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1825 result->st_mode |= 0111;
1826 }
1827 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001828}
1829
1830static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001831win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001832{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 /* Protocol violation: we explicitly clear errno, instead of
1834 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001835 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001836 errno = 0;
1837 return code;
1838}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001839
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001840static int
1841win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1842{
1843 /* Protocol violation: we explicitly clear errno, instead of
1844 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001845 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001846 errno = 0;
1847 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001848}
Brian Curtind25aef52011-06-13 15:16:04 -05001849/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001850
1851 In Posix, stat automatically traverses symlinks and returns the stat
1852 structure for the target. In Windows, the equivalent GetFileAttributes by
1853 default does not traverse symlinks and instead returns attributes for
1854 the symlink.
1855
1856 Therefore, win32_lstat will get the attributes traditionally, and
1857 win32_stat will first explicitly resolve the symlink target and then will
1858 call win32_lstat on that result.
1859
Ezio Melotti4969f702011-03-15 05:59:46 +02001860 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001861
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001862static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001863win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001864{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001865 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001866}
1867
Victor Stinner8c62be82010-05-06 00:08:46 +00001868static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001869win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001870{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001871 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001872}
1873
1874static int
1875win32_stat(const char* path, struct win32_stat *result)
1876{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001877 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001878}
1879
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001880static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001881win32_stat_w(const wchar_t* path, struct win32_stat *result)
1882{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001883 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001884}
1885
1886static int
1887win32_fstat(int file_number, struct win32_stat *result)
1888{
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 BY_HANDLE_FILE_INFORMATION info;
1890 HANDLE h;
1891 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001892
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001893 if (!_PyVerify_fd(file_number))
1894 h = INVALID_HANDLE_VALUE;
1895 else
1896 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001897
Victor Stinner8c62be82010-05-06 00:08:46 +00001898 /* Protocol violation: we explicitly clear errno, instead of
1899 setting it to a POSIX error. Callers should use GetLastError. */
1900 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001901
Victor Stinner8c62be82010-05-06 00:08:46 +00001902 if (h == INVALID_HANDLE_VALUE) {
1903 /* This is really a C library error (invalid file handle).
1904 We set the Win32 error to the closes one matching. */
1905 SetLastError(ERROR_INVALID_HANDLE);
1906 return -1;
1907 }
1908 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001909
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 type = GetFileType(h);
1911 if (type == FILE_TYPE_UNKNOWN) {
1912 DWORD error = GetLastError();
1913 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001914 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 }
1916 /* else: valid but unknown file */
1917 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001918
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 if (type != FILE_TYPE_DISK) {
1920 if (type == FILE_TYPE_CHAR)
1921 result->st_mode = _S_IFCHR;
1922 else if (type == FILE_TYPE_PIPE)
1923 result->st_mode = _S_IFIFO;
1924 return 0;
1925 }
1926
1927 if (!GetFileInformationByHandle(h, &info)) {
1928 return -1;
1929 }
1930
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001931 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1934 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001935}
1936
1937#endif /* MS_WINDOWS */
1938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001940"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001942 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001943or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1944\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001945Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1946or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001947\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001948See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001949
1950static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 {"st_mode", "protection bits"},
1952 {"st_ino", "inode"},
1953 {"st_dev", "device"},
1954 {"st_nlink", "number of hard links"},
1955 {"st_uid", "user ID of owner"},
1956 {"st_gid", "group ID of owner"},
1957 {"st_size", "total size, in bytes"},
1958 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1959 {NULL, "integer time of last access"},
1960 {NULL, "integer time of last modification"},
1961 {NULL, "integer time of last change"},
1962 {"st_atime", "time of last access"},
1963 {"st_mtime", "time of last modification"},
1964 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001965 {"st_atime_ns", "time of last access in nanoseconds"},
1966 {"st_mtime_ns", "time of last modification in nanoseconds"},
1967 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001968#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001970#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001971#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001973#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001974#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001977#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001979#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001980#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001982#endif
1983#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987};
1988
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001989#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001990#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001992#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001993#endif
1994
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001995#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001996#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1997#else
1998#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1999#endif
2000
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002001#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002002#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2003#else
2004#define ST_RDEV_IDX ST_BLOCKS_IDX
2005#endif
2006
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002007#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2008#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2009#else
2010#define ST_FLAGS_IDX ST_RDEV_IDX
2011#endif
2012
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002014#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002015#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002016#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002017#endif
2018
2019#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2020#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2021#else
2022#define ST_BIRTHTIME_IDX ST_GEN_IDX
2023#endif
2024
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 "stat_result", /* name */
2027 stat_result__doc__, /* doc */
2028 stat_result_fields,
2029 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030};
2031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002033"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2034This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002035 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002036or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002037\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002038See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039
2040static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 {"f_bsize", },
2042 {"f_frsize", },
2043 {"f_blocks", },
2044 {"f_bfree", },
2045 {"f_bavail", },
2046 {"f_files", },
2047 {"f_ffree", },
2048 {"f_favail", },
2049 {"f_flag", },
2050 {"f_namemax",},
2051 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002052};
2053
2054static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 "statvfs_result", /* name */
2056 statvfs_result__doc__, /* doc */
2057 statvfs_result_fields,
2058 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002059};
2060
Ross Lagerwall7807c352011-03-17 20:20:30 +02002061#if defined(HAVE_WAITID) && !defined(__APPLE__)
2062PyDoc_STRVAR(waitid_result__doc__,
2063"waitid_result: Result from waitid.\n\n\
2064This object may be accessed either as a tuple of\n\
2065 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2066or via the attributes si_pid, si_uid, and so on.\n\
2067\n\
2068See os.waitid for more information.");
2069
2070static PyStructSequence_Field waitid_result_fields[] = {
2071 {"si_pid", },
2072 {"si_uid", },
2073 {"si_signo", },
2074 {"si_status", },
2075 {"si_code", },
2076 {0}
2077};
2078
2079static PyStructSequence_Desc waitid_result_desc = {
2080 "waitid_result", /* name */
2081 waitid_result__doc__, /* doc */
2082 waitid_result_fields,
2083 5
2084};
2085static PyTypeObject WaitidResultType;
2086#endif
2087
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002088static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002089static PyTypeObject StatResultType;
2090static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002091#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002092static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002093#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002094static newfunc structseq_new;
2095
2096static PyObject *
2097statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2098{
Victor Stinner8c62be82010-05-06 00:08:46 +00002099 PyStructSequence *result;
2100 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002101
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 result = (PyStructSequence*)structseq_new(type, args, kwds);
2103 if (!result)
2104 return NULL;
2105 /* If we have been initialized from a tuple,
2106 st_?time might be set to None. Initialize it
2107 from the int slots. */
2108 for (i = 7; i <= 9; i++) {
2109 if (result->ob_item[i+3] == Py_None) {
2110 Py_DECREF(Py_None);
2111 Py_INCREF(result->ob_item[i]);
2112 result->ob_item[i+3] = result->ob_item[i];
2113 }
2114 }
2115 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002116}
2117
2118
2119
2120/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002121static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002122
2123PyDoc_STRVAR(stat_float_times__doc__,
2124"stat_float_times([newval]) -> oldval\n\n\
2125Determine whether os.[lf]stat represents time stamps as float objects.\n\
2126If newval is True, future calls to stat() return floats, if it is False,\n\
2127future calls return ints. \n\
2128If newval is omitted, return the current setting.\n");
2129
2130static PyObject*
2131stat_float_times(PyObject* self, PyObject *args)
2132{
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 int newval = -1;
2134 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2135 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002136 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2137 "stat_float_times() is deprecated",
2138 1))
2139 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 if (newval == -1)
2141 /* Return old value */
2142 return PyBool_FromLong(_stat_float_times);
2143 _stat_float_times = newval;
2144 Py_INCREF(Py_None);
2145 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002146}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002147
Larry Hastings6fe20b32012-04-19 15:07:49 -07002148static PyObject *billion = NULL;
2149
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002150static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002151fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002152{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002153 PyObject *s = _PyLong_FromTime_t(sec);
2154 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2155 PyObject *s_in_ns = NULL;
2156 PyObject *ns_total = NULL;
2157 PyObject *float_s = NULL;
2158
2159 if (!(s && ns_fractional))
2160 goto exit;
2161
2162 s_in_ns = PyNumber_Multiply(s, billion);
2163 if (!s_in_ns)
2164 goto exit;
2165
2166 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2167 if (!ns_total)
2168 goto exit;
2169
Victor Stinner4195b5c2012-02-08 23:03:19 +01002170 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002171 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2172 if (!float_s)
2173 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002174 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002175 else {
2176 float_s = s;
2177 Py_INCREF(float_s);
2178 }
2179
2180 PyStructSequence_SET_ITEM(v, index, s);
2181 PyStructSequence_SET_ITEM(v, index+3, float_s);
2182 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2183 s = NULL;
2184 float_s = NULL;
2185 ns_total = NULL;
2186exit:
2187 Py_XDECREF(s);
2188 Py_XDECREF(ns_fractional);
2189 Py_XDECREF(s_in_ns);
2190 Py_XDECREF(ns_total);
2191 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002192}
2193
Tim Peters5aa91602002-01-30 05:46:57 +00002194/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002195 (used by posix_stat() and posix_fstat()) */
2196static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002197_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002198{
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 unsigned long ansec, mnsec, cnsec;
2200 PyObject *v = PyStructSequence_New(&StatResultType);
2201 if (v == NULL)
2202 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002203
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002205#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 PyStructSequence_SET_ITEM(v, 1,
2207 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002208#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002210#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002211#ifdef MS_WINDOWS
2212 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2213#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 PyStructSequence_SET_ITEM(v, 2,
2215 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002216#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002217 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002219 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002220#if defined(MS_WINDOWS)
2221 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2222 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2223#else
2224 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2225 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2226#endif
Fred Drake699f3522000-06-29 21:12:41 +00002227#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002228 PyStructSequence_SET_ITEM(v, 6,
2229 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002230#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002231 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002232#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002233
Martin v. Löwis14694662006-02-03 12:54:16 +00002234#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 ansec = st->st_atim.tv_nsec;
2236 mnsec = st->st_mtim.tv_nsec;
2237 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002238#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 ansec = st->st_atimespec.tv_nsec;
2240 mnsec = st->st_mtimespec.tv_nsec;
2241 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002242#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002243 ansec = st->st_atime_nsec;
2244 mnsec = st->st_mtime_nsec;
2245 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002246#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002247 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002248#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002249 fill_time(v, 7, st->st_atime, ansec);
2250 fill_time(v, 8, st->st_mtime, mnsec);
2251 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002252
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002253#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2255 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002256#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002257#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2259 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002260#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002261#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2263 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002264#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002265#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002266 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2267 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002268#endif
2269#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002270 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002271 PyObject *val;
2272 unsigned long bsec,bnsec;
2273 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002274#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002275 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002276#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002277 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002278#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002279 if (_stat_float_times) {
2280 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2281 } else {
2282 val = PyLong_FromLong((long)bsec);
2283 }
2284 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2285 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002287#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002288#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002289 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2290 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002291#endif
Fred Drake699f3522000-06-29 21:12:41 +00002292
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 if (PyErr_Occurred()) {
2294 Py_DECREF(v);
2295 return NULL;
2296 }
Fred Drake699f3522000-06-29 21:12:41 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002299}
2300
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301/* POSIX methods */
2302
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303
2304static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002305posix_do_stat(char *function_name, path_t *path,
2306 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002308 STRUCT_STAT st;
2309 int result;
2310
2311#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2312 if (follow_symlinks_specified(function_name, follow_symlinks))
2313 return NULL;
2314#endif
2315
2316 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2317 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2318 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2319 return NULL;
2320
2321 Py_BEGIN_ALLOW_THREADS
2322 if (path->fd != -1)
2323 result = FSTAT(path->fd, &st);
2324 else
2325#ifdef MS_WINDOWS
2326 if (path->wide) {
2327 if (follow_symlinks)
2328 result = win32_stat_w(path->wide, &st);
2329 else
2330 result = win32_lstat_w(path->wide, &st);
2331 }
2332 else
2333#endif
2334#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2335 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2336 result = LSTAT(path->narrow, &st);
2337 else
2338#endif
2339#ifdef HAVE_FSTATAT
2340 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2341 result = fstatat(dir_fd, path->narrow, &st,
2342 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2343 else
2344#endif
2345 result = STAT(path->narrow, &st);
2346 Py_END_ALLOW_THREADS
2347
Victor Stinner292c8352012-10-30 02:17:38 +01002348 if (result != 0) {
2349 return path_error(path);
2350 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002351
2352 return _pystat_fromstructstat(&st);
2353}
2354
Larry Hastings31826802013-10-19 00:09:25 -07002355#ifdef HAVE_FSTATAT
2356 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2357#else
2358 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2359#endif
2360
2361
2362/*[python]
2363
2364class path_t_converter(CConverter):
2365
2366 type = "path_t"
2367 impl_by_reference = True
2368 parse_by_reference = True
2369
2370 converter = 'path_converter'
2371
2372 def converter_init(self, *, allow_fd=False, nullable=False):
2373 def strify(value):
2374 return str(int(bool(value)))
2375
2376 # right now path_t doesn't support default values.
2377 # to support a default value, you'll need to override initialize().
2378
2379 assert self.default is unspecified
2380
2381 self.nullable = nullable
2382 self.allow_fd = allow_fd
2383
2384 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2385 self.function.name,
2386 strify(nullable),
2387 strify(allow_fd),
2388 )
2389
2390 def cleanup(self):
2391 return "path_cleanup(&" + self.name + ");\n"
2392
2393
2394class dir_fd_converter(CConverter):
2395 type = 'int'
2396 converter = 'OS_STAT_DIR_FD_CONVERTER'
2397
2398 def converter_init(self):
2399 if self.default in (unspecified, None):
2400 self.c_default = 'DEFAULT_DIR_FD'
2401
2402
2403[python]*/
2404/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
2405
2406/*[clinic]
2407module os
2408
2409os.stat -> object(doc_default='stat_result')
2410
2411 path : path_t(allow_fd=True)
2412 Path to be examined; can be string, bytes, or open-file-descriptor int.
2413
2414 *
2415
2416 dir_fd : dir_fd = None
2417 If not None, it should be a file descriptor open to a directory,
2418 and path should be a relative string; path will then be relative to
2419 that directory.
2420
2421 follow_symlinks: bool = True
2422 If False, and the last element of the path is a symbolic link,
2423 stat will examine the symbolic link itself instead of the file
2424 the link points to.
2425
2426Perform a stat system call on the given path.
2427
2428dir_fd and follow_symlinks may not be implemented
2429 on your platform. If they are unavailable, using them will raise a
2430 NotImplementedError.
2431
2432It's an error to use dir_fd or follow_symlinks when specifying path as
2433 an open file descriptor.
2434
2435[clinic]*/
2436
2437PyDoc_STRVAR(os_stat__doc__,
2438"Perform a stat system call on the given path.\n"
2439"\n"
2440"os.stat(path, *, dir_fd=None, follow_symlinks=True) -> stat_result\n"
2441" path\n"
2442" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2443" dir_fd\n"
2444" If not None, it should be a file descriptor open to a directory,\n"
2445" and path should be a relative string; path will then be relative to\n"
2446" that directory.\n"
2447" follow_symlinks\n"
2448" If False, and the last element of the path is a symbolic link,\n"
2449" stat will examine the symbolic link itself instead of the file\n"
2450" the link points to.\n"
2451"\n"
2452"dir_fd and follow_symlinks may not be implemented\n"
2453" on your platform. If they are unavailable, using them will raise a\n"
2454" NotImplementedError.\n"
2455"\n"
2456"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2457" an open file descriptor.");
2458
2459#define OS_STAT_METHODDEF \
2460 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002461
2462static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002463os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks);
2464
2465static PyObject *
2466os_stat(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002467{
Larry Hastings31826802013-10-19 00:09:25 -07002468 PyObject *return_value = NULL;
2469 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2470 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002471 int dir_fd = DEFAULT_DIR_FD;
2472 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002473
Larry Hastings31826802013-10-19 00:09:25 -07002474 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2475 "O&|$O&p:stat", _keywords,
2476 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2477 goto exit;
2478 return_value = os_stat_impl(self, &path, dir_fd, follow_symlinks);
2479
2480exit:
2481 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002482 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002483
Larry Hastings9cf065c2012-06-22 16:30:09 -07002484 return return_value;
2485}
2486
Larry Hastings31826802013-10-19 00:09:25 -07002487static PyObject *
2488os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks)
2489/*[clinic checksum: 9d9af08e8cfafd12f94e73ea3065eb3056f99515]*/
2490{
2491 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2492}
2493
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494PyDoc_STRVAR(posix_lstat__doc__,
2495"lstat(path, *, dir_fd=None) -> stat result\n\n\
2496Like stat(), but do not follow symbolic links.\n\
2497Equivalent to stat(path, follow_symlinks=False).");
2498
2499static PyObject *
2500posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2501{
2502 static char *keywords[] = {"path", "dir_fd", NULL};
2503 path_t path;
2504 int dir_fd = DEFAULT_DIR_FD;
2505 int follow_symlinks = 0;
2506 PyObject *return_value;
2507
2508 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002509 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2511 path_converter, &path,
2512#ifdef HAVE_FSTATAT
2513 dir_fd_converter, &dir_fd
2514#else
2515 dir_fd_unavailable, &dir_fd
2516#endif
2517 ))
2518 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002519 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002520 path_cleanup(&path);
2521 return return_value;
2522}
2523
Larry Hastings31826802013-10-19 00:09:25 -07002524
2525#ifdef HAVE_FACCESSAT
2526 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2527#else
2528 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2529#endif
2530/*[clinic]
2531os.access -> object(doc_default='True if granted, False otherwise')
2532
2533 path: path_t(allow_fd=True)
2534 Path to be tested; can be string, bytes, or open-file-descriptor int.
2535
2536 mode: int
2537 Operating-system mode bitfield. Can be F_OK to test existence,
2538 or the inclusive-OR of R_OK, W_OK, and X_OK.
2539
2540 *
2541
2542 dir_fd : dir_fd = None
2543 If not None, it should be a file descriptor open to a directory,
2544 and path should be relative; path will then be relative to that
2545 directory.
2546
2547 effective_ids: bool = False
2548 If True, access will use the effective uid/gid instead of
2549 the real uid/gid.
2550
2551 follow_symlinks: bool = True
2552 If False, and the last element of the path is a symbolic link,
2553 access will examine the symbolic link itself instead of the file
2554 the link points to.
2555
2556Use the real uid/gid to test for access to a path.
2557
2558{parameters}
2559dir_fd, effective_ids, and follow_symlinks may not be implemented
2560 on your platform. If they are unavailable, using them will raise a
2561 NotImplementedError.
2562
2563Note that most operations will use the effective uid/gid, therefore this
2564 routine can be used in a suid/sgid environment to test if the invoking user
2565 has the specified access to the path.
2566
2567[clinic]*/
2568
2569PyDoc_STRVAR(os_access__doc__,
2570"Use the real uid/gid to test for access to a path.\n"
2571"\n"
2572"os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) -> True if granted, False otherwise\n"
2573" path\n"
2574" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2575" mode\n"
2576" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2577" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2578" dir_fd\n"
2579" If not None, it should be a file descriptor open to a directory,\n"
2580" and path should be relative; path will then be relative to that\n"
2581" directory.\n"
2582" effective_ids\n"
2583" If True, access will use the effective uid/gid instead of\n"
2584" the real uid/gid.\n"
2585" follow_symlinks\n"
2586" If False, and the last element of the path is a symbolic link,\n"
2587" access will examine the symbolic link itself instead of the file\n"
2588" the link points to.\n"
2589"\n"
2590"{parameters}\n"
2591"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2592" on your platform. If they are unavailable, using them will raise a\n"
2593" NotImplementedError.\n"
2594"\n"
2595"Note that most operations will use the effective uid/gid, therefore this\n"
2596" routine can be used in a suid/sgid environment to test if the invoking user\n"
2597" has the specified access to the path.");
2598
2599#define OS_ACCESS_METHODDEF \
2600 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601
2602static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002603os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
2604
2605static PyObject *
2606os_access(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607{
Larry Hastings31826802013-10-19 00:09:25 -07002608 PyObject *return_value = NULL;
2609 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2610 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612 int dir_fd = DEFAULT_DIR_FD;
2613 int effective_ids = 0;
2614 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002615
2616 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2617 "O&i|$O&pp:access", _keywords,
2618 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2619 goto exit;
2620 return_value = os_access_impl(self, &path, mode, dir_fd, effective_ids, follow_symlinks);
2621
2622exit:
2623 /* Cleanup for path */
2624 path_cleanup(&path);
2625
2626 return return_value;
2627}
2628
2629static PyObject *
2630os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
2631/*[clinic checksum: 0147557eb43243df57ba616cc7c35f232c69bc6a]*/
2632{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002634
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002635#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002636 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002637#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002638 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002639#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641#ifndef HAVE_FACCESSAT
2642 if (follow_symlinks_specified("access", follow_symlinks))
2643 goto exit;
2644
2645 if (effective_ids) {
2646 argument_unavailable_error("access", "effective_ids");
2647 goto exit;
2648 }
2649#endif
2650
2651#ifdef MS_WINDOWS
2652 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002653 if (path->wide != NULL)
2654 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002655 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002656 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657 Py_END_ALLOW_THREADS
2658
2659 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002660 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002661 * * we didn't get a -1, and
2662 * * write access wasn't requested,
2663 * * or the file isn't read-only,
2664 * * or it's a directory.
2665 * (Directories cannot be read-only on Windows.)
2666 */
2667 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002668 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002669 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002670 !(attr & FILE_ATTRIBUTE_READONLY) ||
2671 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2672#else
2673
2674 Py_BEGIN_ALLOW_THREADS
2675#ifdef HAVE_FACCESSAT
2676 if ((dir_fd != DEFAULT_DIR_FD) ||
2677 effective_ids ||
2678 !follow_symlinks) {
2679 int flags = 0;
2680 if (!follow_symlinks)
2681 flags |= AT_SYMLINK_NOFOLLOW;
2682 if (effective_ids)
2683 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002684 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685 }
2686 else
2687#endif
Larry Hastings31826802013-10-19 00:09:25 -07002688 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689 Py_END_ALLOW_THREADS
2690 return_value = PyBool_FromLong(!result);
2691#endif
2692
2693#ifndef HAVE_FACCESSAT
2694exit:
2695#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002697}
2698
Guido van Rossumd371ff11999-01-25 16:12:23 +00002699#ifndef F_OK
2700#define F_OK 0
2701#endif
2702#ifndef R_OK
2703#define R_OK 4
2704#endif
2705#ifndef W_OK
2706#define W_OK 2
2707#endif
2708#ifndef X_OK
2709#define X_OK 1
2710#endif
2711
Larry Hastings31826802013-10-19 00:09:25 -07002712
Guido van Rossumd371ff11999-01-25 16:12:23 +00002713#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002714
2715/*[clinic]
2716os.ttyname -> DecodeFSDefault
2717
2718 fd: int
2719 Integer file descriptor handle.
2720
2721 /
2722
2723Return the name of the terminal device connected to 'fd'.
2724[clinic]*/
2725
2726PyDoc_STRVAR(os_ttyname__doc__,
2727"Return the name of the terminal device connected to \'fd\'.\n"
2728"\n"
2729"os.ttyname(fd)\n"
2730" fd\n"
2731" Integer file descriptor handle.");
2732
2733#define OS_TTYNAME_METHODDEF \
2734 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2735
2736static char *
2737os_ttyname_impl(PyObject *self, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002738
2739static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002740os_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002741{
Larry Hastings31826802013-10-19 00:09:25 -07002742 PyObject *return_value = NULL;
2743 int fd;
2744 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002745
Larry Hastings31826802013-10-19 00:09:25 -07002746 if (!PyArg_ParseTuple(args,
2747 "i:ttyname",
2748 &fd))
2749 goto exit;
2750 _return_value = os_ttyname_impl(self, fd);
2751 if (_return_value == NULL)
2752 goto exit;
2753 return_value = PyUnicode_DecodeFSDefault(_return_value);
2754
2755exit:
2756 return return_value;
2757}
2758
2759static char *
2760os_ttyname_impl(PyObject *self, int fd)
2761/*[clinic checksum: ea680155d87bb733f542d67653eca732dd0981a8]*/
2762{
2763 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002764
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002765#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 /* file descriptor 0 only, the default input device (stdin) */
Larry Hastings31826802013-10-19 00:09:25 -07002767 if (fd == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002768 ret = ttyname();
2769 }
2770 else {
2771 ret = NULL;
2772 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002773#else
Larry Hastings31826802013-10-19 00:09:25 -07002774 ret = ttyname(fd);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002775#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002777 posix_error();
2778 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002779}
Larry Hastings31826802013-10-19 00:09:25 -07002780#else
2781#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002782#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002783
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002784#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002785PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002786"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002788
2789static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002790posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002791{
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 char *ret;
2793 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002794
Greg Wardb48bc172000-03-01 21:51:56 +00002795#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002797#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002798 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002799#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 if (ret == NULL)
2801 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002802 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002803}
2804#endif
2805
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002807"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808Change the current working directory to the specified path.\n\
2809\n\
2810path may always be specified as a string.\n\
2811On some platforms, path may also be specified as an open file descriptor.\n\
2812 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002813
Barry Warsaw53699e91996-12-10 23:23:01 +00002814static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002816{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 path_t path;
2818 int result;
2819 PyObject *return_value = NULL;
2820 static char *keywords[] = {"path", NULL};
2821
2822 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002823 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824#ifdef HAVE_FCHDIR
2825 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002826#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2828 path_converter, &path
2829 ))
2830 return NULL;
2831
2832 Py_BEGIN_ALLOW_THREADS
2833#ifdef MS_WINDOWS
2834 if (path.wide)
2835 result = win32_wchdir(path.wide);
2836 else
2837 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002838 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839#else
2840#ifdef HAVE_FCHDIR
2841 if (path.fd != -1)
2842 result = fchdir(path.fd);
2843 else
2844#endif
2845 result = chdir(path.narrow);
2846#endif
2847 Py_END_ALLOW_THREADS
2848
2849 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002850 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 goto exit;
2852 }
2853
2854 return_value = Py_None;
2855 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002856
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857exit:
2858 path_cleanup(&path);
2859 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002860}
2861
Fred Drake4d1e64b2002-04-15 19:40:07 +00002862#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002864"fchdir(fd)\n\n\
2865Change to the directory of the given file descriptor. fd must be\n\
2866opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002867
2868static PyObject *
2869posix_fchdir(PyObject *self, PyObject *fdobj)
2870{
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002872}
2873#endif /* HAVE_FCHDIR */
2874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002876PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002877"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2878Change the access permissions of a file.\n\
2879\n\
2880path may always be specified as a string.\n\
2881On some platforms, path may also be specified as an open file descriptor.\n\
2882 If this functionality is unavailable, using it raises an exception.\n\
2883If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2884 and path should be relative; path will then be relative to that directory.\n\
2885If follow_symlinks is False, and the last element of the path is a symbolic\n\
2886 link, chmod will modify the symbolic link itself instead of the file the\n\
2887 link points to.\n\
2888It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2889 an open file descriptor.\n\
2890dir_fd and follow_symlinks may not be implemented on your platform.\n\
2891 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Barry Warsaw53699e91996-12-10 23:23:01 +00002893static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002894posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002895{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002896 path_t path;
2897 int mode;
2898 int dir_fd = DEFAULT_DIR_FD;
2899 int follow_symlinks = 1;
2900 int result;
2901 PyObject *return_value = NULL;
2902 static char *keywords[] = {"path", "mode", "dir_fd",
2903 "follow_symlinks", NULL};
2904
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002905#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002907#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002908
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909#ifdef HAVE_FCHMODAT
2910 int fchmodat_nofollow_unsupported = 0;
2911#endif
2912
2913 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002914 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915#ifdef HAVE_FCHMOD
2916 path.allow_fd = 1;
2917#endif
2918 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2919 path_converter, &path,
2920 &mode,
2921#ifdef HAVE_FCHMODAT
2922 dir_fd_converter, &dir_fd,
2923#else
2924 dir_fd_unavailable, &dir_fd,
2925#endif
2926 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002928
2929#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2930 if (follow_symlinks_specified("chmod", follow_symlinks))
2931 goto exit;
2932#endif
2933
2934#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936 if (path.wide)
2937 attr = GetFileAttributesW(path.wide);
2938 else
2939 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002940 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941 result = 0;
2942 else {
2943 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 attr &= ~FILE_ATTRIBUTE_READONLY;
2945 else
2946 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002947 if (path.wide)
2948 result = SetFileAttributesW(path.wide, attr);
2949 else
2950 result = SetFileAttributesA(path.narrow, attr);
2951 }
2952 Py_END_ALLOW_THREADS
2953
2954 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002955 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956 goto exit;
2957 }
2958#else /* MS_WINDOWS */
2959 Py_BEGIN_ALLOW_THREADS
2960#ifdef HAVE_FCHMOD
2961 if (path.fd != -1)
2962 result = fchmod(path.fd, mode);
2963 else
2964#endif
2965#ifdef HAVE_LCHMOD
2966 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2967 result = lchmod(path.narrow, mode);
2968 else
2969#endif
2970#ifdef HAVE_FCHMODAT
2971 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2972 /*
2973 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2974 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002975 * and then says it isn't implemented yet.
2976 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977 *
2978 * Once it is supported, os.chmod will automatically
2979 * support dir_fd and follow_symlinks=False. (Hopefully.)
2980 * Until then, we need to be careful what exception we raise.
2981 */
2982 result = fchmodat(dir_fd, path.narrow, mode,
2983 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2984 /*
2985 * But wait! We can't throw the exception without allowing threads,
2986 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2987 */
2988 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002989 result &&
2990 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2991 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 }
2993 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002994#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002995 result = chmod(path.narrow, mode);
2996 Py_END_ALLOW_THREADS
2997
2998 if (result) {
2999#ifdef HAVE_FCHMODAT
3000 if (fchmodat_nofollow_unsupported) {
3001 if (dir_fd != DEFAULT_DIR_FD)
3002 dir_fd_and_follow_symlinks_invalid("chmod",
3003 dir_fd, follow_symlinks);
3004 else
3005 follow_symlinks_specified("chmod", follow_symlinks);
3006 }
3007 else
3008#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003009 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 goto exit;
3011 }
3012#endif
3013
3014 Py_INCREF(Py_None);
3015 return_value = Py_None;
3016exit:
3017 path_cleanup(&path);
3018 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003019}
3020
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021
Christian Heimes4e30a842007-11-30 22:12:06 +00003022#ifdef HAVE_FCHMOD
3023PyDoc_STRVAR(posix_fchmod__doc__,
3024"fchmod(fd, mode)\n\n\
3025Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003026descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003027
3028static PyObject *
3029posix_fchmod(PyObject *self, PyObject *args)
3030{
Victor Stinner8c62be82010-05-06 00:08:46 +00003031 int fd, mode, res;
3032 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3033 return NULL;
3034 Py_BEGIN_ALLOW_THREADS
3035 res = fchmod(fd, mode);
3036 Py_END_ALLOW_THREADS
3037 if (res < 0)
3038 return posix_error();
3039 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003040}
3041#endif /* HAVE_FCHMOD */
3042
3043#ifdef HAVE_LCHMOD
3044PyDoc_STRVAR(posix_lchmod__doc__,
3045"lchmod(path, mode)\n\n\
3046Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003047affects the link itself rather than the target.\n\
3048Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003049
3050static PyObject *
3051posix_lchmod(PyObject *self, PyObject *args)
3052{
Victor Stinner292c8352012-10-30 02:17:38 +01003053 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003054 int i;
3055 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003056 memset(&path, 0, sizeof(path));
3057 path.function_name = "lchmod";
3058 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3059 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003060 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003062 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003063 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003064 if (res < 0) {
3065 path_error(&path);
3066 path_cleanup(&path);
3067 return NULL;
3068 }
3069 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003070 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003071}
3072#endif /* HAVE_LCHMOD */
3073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003074
Thomas Wouterscf297e42007-02-23 15:07:44 +00003075#ifdef HAVE_CHFLAGS
3076PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003077"chflags(path, flags, *, follow_symlinks=True)\n\n\
3078Set file flags.\n\
3079\n\
3080If follow_symlinks is False, and the last element of the path is a symbolic\n\
3081 link, chflags will change flags on the symbolic link itself instead of the\n\
3082 file the link points to.\n\
3083follow_symlinks may not be implemented on your platform. If it is\n\
3084unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003085
3086static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003088{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003089 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003090 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003091 int follow_symlinks = 1;
3092 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003093 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003094 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3095
3096 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003097 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3099 path_converter, &path,
3100 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003101 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003102
3103#ifndef HAVE_LCHFLAGS
3104 if (follow_symlinks_specified("chflags", follow_symlinks))
3105 goto exit;
3106#endif
3107
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109#ifdef HAVE_LCHFLAGS
3110 if (!follow_symlinks)
3111 result = lchflags(path.narrow, flags);
3112 else
3113#endif
3114 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003115 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116
3117 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003118 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119 goto exit;
3120 }
3121
3122 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124
3125exit:
3126 path_cleanup(&path);
3127 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003128}
3129#endif /* HAVE_CHFLAGS */
3130
3131#ifdef HAVE_LCHFLAGS
3132PyDoc_STRVAR(posix_lchflags__doc__,
3133"lchflags(path, flags)\n\n\
3134Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135This function will not follow symbolic links.\n\
3136Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003137
3138static PyObject *
3139posix_lchflags(PyObject *self, PyObject *args)
3140{
Victor Stinner292c8352012-10-30 02:17:38 +01003141 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003142 unsigned long flags;
3143 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003144 memset(&path, 0, sizeof(path));
3145 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003146 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003147 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003150 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003152 if (res < 0) {
3153 path_error(&path);
3154 path_cleanup(&path);
3155 return NULL;
3156 }
3157 path_cleanup(&path);
3158 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003159}
3160#endif /* HAVE_LCHFLAGS */
3161
Martin v. Löwis244edc82001-10-04 22:44:26 +00003162#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003163PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003164"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003165Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003166
3167static PyObject *
3168posix_chroot(PyObject *self, PyObject *args)
3169{
Victor Stinner292c8352012-10-30 02:17:38 +01003170 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003171}
3172#endif
3173
Guido van Rossum21142a01999-01-08 21:05:37 +00003174#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003175PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003176"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003178
3179static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003180posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003181{
Stefan Krah0e803b32010-11-26 16:16:47 +00003182 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003183}
3184#endif /* HAVE_FSYNC */
3185
Ross Lagerwall7807c352011-03-17 20:20:30 +02003186#ifdef HAVE_SYNC
3187PyDoc_STRVAR(posix_sync__doc__,
3188"sync()\n\n\
3189Force write of everything to disk.");
3190
3191static PyObject *
3192posix_sync(PyObject *self, PyObject *noargs)
3193{
3194 Py_BEGIN_ALLOW_THREADS
3195 sync();
3196 Py_END_ALLOW_THREADS
3197 Py_RETURN_NONE;
3198}
3199#endif
3200
Guido van Rossum21142a01999-01-08 21:05:37 +00003201#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003202
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003203#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003204extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3205#endif
3206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003207PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003208"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003209force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003211
3212static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003213posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003214{
Stefan Krah0e803b32010-11-26 16:16:47 +00003215 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003216}
3217#endif /* HAVE_FDATASYNC */
3218
3219
Fredrik Lundh10723342000-07-10 16:38:09 +00003220#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003221PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003222"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3223Change the owner and group id of path to the numeric uid and gid.\n\
3224\n\
3225path may always be specified as a string.\n\
3226On some platforms, path may also be specified as an open file descriptor.\n\
3227 If this functionality is unavailable, using it raises an exception.\n\
3228If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3229 and path should be relative; path will then be relative to that directory.\n\
3230If follow_symlinks is False, and the last element of the path is a symbolic\n\
3231 link, chown will modify the symbolic link itself instead of the file the\n\
3232 link points to.\n\
3233It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3234 an open file descriptor.\n\
3235dir_fd and follow_symlinks may not be implemented on your platform.\n\
3236 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003237
Barry Warsaw53699e91996-12-10 23:23:01 +00003238static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003240{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003241 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 uid_t uid;
3243 gid_t gid;
3244 int dir_fd = DEFAULT_DIR_FD;
3245 int follow_symlinks = 1;
3246 int result;
3247 PyObject *return_value = NULL;
3248 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3249 "follow_symlinks", NULL};
3250
3251 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003252 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253#ifdef HAVE_FCHOWN
3254 path.allow_fd = 1;
3255#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003256 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003258 _Py_Uid_Converter, &uid,
3259 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260#ifdef HAVE_FCHOWNAT
3261 dir_fd_converter, &dir_fd,
3262#else
3263 dir_fd_unavailable, &dir_fd,
3264#endif
3265 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267
3268#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3269 if (follow_symlinks_specified("chown", follow_symlinks))
3270 goto exit;
3271#endif
3272 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3273 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3274 goto exit;
3275
3276#ifdef __APPLE__
3277 /*
3278 * This is for Mac OS X 10.3, which doesn't have lchown.
3279 * (But we still have an lchown symbol because of weak-linking.)
3280 * It doesn't have fchownat either. So there's no possibility
3281 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003282 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283 if ((!follow_symlinks) && (lchown == NULL)) {
3284 follow_symlinks_specified("chown", follow_symlinks);
3285 goto exit;
3286 }
3287#endif
3288
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290#ifdef HAVE_FCHOWN
3291 if (path.fd != -1)
3292 result = fchown(path.fd, uid, gid);
3293 else
3294#endif
3295#ifdef HAVE_LCHOWN
3296 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3297 result = lchown(path.narrow, uid, gid);
3298 else
3299#endif
3300#ifdef HAVE_FCHOWNAT
3301 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3302 result = fchownat(dir_fd, path.narrow, uid, gid,
3303 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3304 else
3305#endif
3306 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003308
3309 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003310 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311 goto exit;
3312 }
3313
3314 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003316
3317exit:
3318 path_cleanup(&path);
3319 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003320}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003321#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003322
Christian Heimes4e30a842007-11-30 22:12:06 +00003323#ifdef HAVE_FCHOWN
3324PyDoc_STRVAR(posix_fchown__doc__,
3325"fchown(fd, uid, gid)\n\n\
3326Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003327fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003328
3329static PyObject *
3330posix_fchown(PyObject *self, PyObject *args)
3331{
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003333 uid_t uid;
3334 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003336 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3337 _Py_Uid_Converter, &uid,
3338 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003339 return NULL;
3340 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003341 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 Py_END_ALLOW_THREADS
3343 if (res < 0)
3344 return posix_error();
3345 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003346}
3347#endif /* HAVE_FCHOWN */
3348
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003349#ifdef HAVE_LCHOWN
3350PyDoc_STRVAR(posix_lchown__doc__,
3351"lchown(path, uid, gid)\n\n\
3352Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003353This function will not follow symbolic links.\n\
3354Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003355
3356static PyObject *
3357posix_lchown(PyObject *self, PyObject *args)
3358{
Victor Stinner292c8352012-10-30 02:17:38 +01003359 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003360 uid_t uid;
3361 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003363 memset(&path, 0, sizeof(path));
3364 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003365 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003366 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003367 _Py_Uid_Converter, &uid,
3368 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003371 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003373 if (res < 0) {
3374 path_error(&path);
3375 path_cleanup(&path);
3376 return NULL;
3377 }
3378 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 Py_INCREF(Py_None);
3380 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003381}
3382#endif /* HAVE_LCHOWN */
3383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003384
Barry Warsaw53699e91996-12-10 23:23:01 +00003385static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003386posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003387{
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 char buf[1026];
3389 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003390
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003391#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 if (!use_bytes) {
3393 wchar_t wbuf[1026];
3394 wchar_t *wbuf2 = wbuf;
3395 PyObject *resobj;
3396 DWORD len;
3397 Py_BEGIN_ALLOW_THREADS
3398 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3399 /* If the buffer is large enough, len does not include the
3400 terminating \0. If the buffer is too small, len includes
3401 the space needed for the terminator. */
3402 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003403 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 if (wbuf2)
3405 len = GetCurrentDirectoryW(len, wbuf2);
3406 }
3407 Py_END_ALLOW_THREADS
3408 if (!wbuf2) {
3409 PyErr_NoMemory();
3410 return NULL;
3411 }
3412 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003413 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003414 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003415 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 }
3417 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003418 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003419 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 return resobj;
3421 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003422
3423 if (win32_warn_bytes_api())
3424 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003425#endif
3426
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 Py_END_ALLOW_THREADS
3430 if (res == NULL)
3431 return posix_error();
3432 if (use_bytes)
3433 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003434 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003435}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003436
3437PyDoc_STRVAR(posix_getcwd__doc__,
3438"getcwd() -> path\n\n\
3439Return a unicode string representing the current working directory.");
3440
3441static PyObject *
3442posix_getcwd_unicode(PyObject *self)
3443{
3444 return posix_getcwd(0);
3445}
3446
3447PyDoc_STRVAR(posix_getcwdb__doc__,
3448"getcwdb() -> path\n\n\
3449Return a bytes string representing the current working directory.");
3450
3451static PyObject *
3452posix_getcwd_bytes(PyObject *self)
3453{
3454 return posix_getcwd(1);
3455}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003456
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3458#define HAVE_LINK 1
3459#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003460
Guido van Rossumb6775db1994-08-01 11:34:53 +00003461#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003462PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3464Create a hard link to a file.\n\
3465\n\
3466If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3467 descriptor open to a directory, and the respective path string (src or dst)\n\
3468 should be relative; the path will then be relative to that directory.\n\
3469If follow_symlinks is False, and the last element of src is a symbolic\n\
3470 link, link will create a link to the symbolic link itself instead of the\n\
3471 file the link points to.\n\
3472src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3473 platform. If they are unavailable, using them will raise a\n\
3474 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003475
Barry Warsaw53699e91996-12-10 23:23:01 +00003476static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003478{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 path_t src, dst;
3480 int src_dir_fd = DEFAULT_DIR_FD;
3481 int dst_dir_fd = DEFAULT_DIR_FD;
3482 int follow_symlinks = 1;
3483 PyObject *return_value = NULL;
3484 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3485 "follow_symlinks", NULL};
3486#ifdef MS_WINDOWS
3487 BOOL result;
3488#else
3489 int result;
3490#endif
3491
3492 memset(&src, 0, sizeof(src));
3493 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003494 src.function_name = "link";
3495 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3497 path_converter, &src,
3498 path_converter, &dst,
3499 dir_fd_converter, &src_dir_fd,
3500 dir_fd_converter, &dst_dir_fd,
3501 &follow_symlinks))
3502 return NULL;
3503
3504#ifndef HAVE_LINKAT
3505 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3506 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3507 goto exit;
3508 }
3509#endif
3510
3511 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3512 PyErr_SetString(PyExc_NotImplementedError,
3513 "link: src and dst must be the same type");
3514 goto exit;
3515 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003516
Brian Curtin1b9df392010-11-24 20:24:31 +00003517#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_BEGIN_ALLOW_THREADS
3519 if (src.wide)
3520 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3521 else
3522 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3523 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003524
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003526 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003528 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529#else
3530 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003531#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3533 (dst_dir_fd != DEFAULT_DIR_FD) ||
3534 (!follow_symlinks))
3535 result = linkat(src_dir_fd, src.narrow,
3536 dst_dir_fd, dst.narrow,
3537 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3538 else
3539#endif
3540 result = link(src.narrow, dst.narrow);
3541 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003542
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003544 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003546 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547#endif
3548
3549 return_value = Py_None;
3550 Py_INCREF(Py_None);
3551
3552exit:
3553 path_cleanup(&src);
3554 path_cleanup(&dst);
3555 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003556}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557#endif
3558
Brian Curtin1b9df392010-11-24 20:24:31 +00003559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003561PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003562"listdir(path='.') -> list_of_filenames\n\n\
3563Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003564The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565entries '.' and '..' even if they are present in the directory.\n\
3566\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003567path can be specified as either str or bytes. If path is bytes,\n\
3568 the filenames returned will also be bytes; in all other circumstances\n\
3569 the filenames returned will be str.\n\
3570On some platforms, path may also be specified as an open file descriptor;\n\
3571 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003573
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003574#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003575static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003577{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 PyObject *v;
3580 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3581 BOOL result;
3582 WIN32_FIND_DATA FileData;
3583 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3584 char *bufptr = namebuf;
3585 /* only claim to have space for MAX_PATH */
3586 Py_ssize_t len = sizeof(namebuf)-5;
3587 PyObject *po = NULL;
3588 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589
Gregory P. Smith40a21602013-03-20 20:52:50 -07003590 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003593
Gregory P. Smith40a21602013-03-20 20:52:50 -07003594 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003595 po_wchars = L".";
3596 len = 1;
3597 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 po_wchars = path->wide;
3599 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003600 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003602 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 if (!wnamebuf) {
3604 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003607 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003609 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003610 if (wch != SEP && wch != ALTSEP && wch != L':')
3611 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 wcscpy(wnamebuf + len, L"*.*");
3613 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 if ((list = PyList_New(0)) == NULL) {
3615 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003617 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003619 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 if (hFindFile == INVALID_HANDLE_VALUE) {
3621 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622 if (error == ERROR_FILE_NOT_FOUND)
3623 goto exit;
3624 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003625 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 }
3628 do {
3629 /* Skip over . and .. */
3630 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3631 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 v = PyUnicode_FromWideChar(wFileData.cFileName,
3633 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 Py_DECREF(list);
3636 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 break;
3638 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 Py_DECREF(list);
3642 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 break;
3644 }
3645 Py_DECREF(v);
3646 }
3647 Py_BEGIN_ALLOW_THREADS
3648 result = FindNextFileW(hFindFile, &wFileData);
3649 Py_END_ALLOW_THREADS
3650 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3651 it got to the end of the directory. */
3652 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003654 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 }
3657 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003658
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003661 strcpy(namebuf, path->narrow);
3662 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 if (len > 0) {
3664 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003665 if (ch != '\\' && ch != '/' && ch != ':')
3666 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 strcpy(namebuf + len, "*.*");
3668 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003669
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003672
Antoine Pitroub73caab2010-08-09 23:39:31 +00003673 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003674 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003675 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 if (hFindFile == INVALID_HANDLE_VALUE) {
3677 int error = GetLastError();
3678 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 goto exit;
3680 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003681 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003682 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 }
3684 do {
3685 /* Skip over . and .. */
3686 if (strcmp(FileData.cFileName, ".") != 0 &&
3687 strcmp(FileData.cFileName, "..") != 0) {
3688 v = PyBytes_FromString(FileData.cFileName);
3689 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_DECREF(list);
3691 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 break;
3693 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696 Py_DECREF(list);
3697 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 break;
3699 }
3700 Py_DECREF(v);
3701 }
3702 Py_BEGIN_ALLOW_THREADS
3703 result = FindNextFile(hFindFile, &FileData);
3704 Py_END_ALLOW_THREADS
3705 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3706 it got to the end of the directory. */
3707 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003709 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 }
3712 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003713
Larry Hastings9cf065c2012-06-22 16:30:09 -07003714exit:
3715 if (hFindFile != INVALID_HANDLE_VALUE) {
3716 if (FindClose(hFindFile) == FALSE) {
3717 if (list != NULL) {
3718 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003719 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720 }
3721 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003722 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003723 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003724
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003726} /* end of _listdir_windows_no_opendir */
3727
3728#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3729
3730static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003731_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003732{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003733 PyObject *v;
3734 DIR *dirp = NULL;
3735 struct dirent *ep;
3736 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003737#ifdef HAVE_FDOPENDIR
3738 int fd = -1;
3739#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003740
Victor Stinner8c62be82010-05-06 00:08:46 +00003741 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003742#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003743 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003744 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003745 fd = _Py_dup(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003746 if (fd == -1) {
3747 list = posix_error();
3748 goto exit;
3749 }
3750
Larry Hastingsfdaea062012-06-25 04:42:23 -07003751 return_str = 1;
3752
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 Py_BEGIN_ALLOW_THREADS
3754 dirp = fdopendir(fd);
3755 Py_END_ALLOW_THREADS
3756 }
3757 else
3758#endif
3759 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003760 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003761 if (path->narrow) {
3762 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003763 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003764 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003765 }
3766 else {
3767 name = ".";
3768 return_str = 1;
3769 }
3770
Larry Hastings9cf065c2012-06-22 16:30:09 -07003771 Py_BEGIN_ALLOW_THREADS
3772 dirp = opendir(name);
3773 Py_END_ALLOW_THREADS
3774 }
3775
3776 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003777 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003778#ifdef HAVE_FDOPENDIR
3779 if (fd != -1) {
3780 Py_BEGIN_ALLOW_THREADS
3781 close(fd);
3782 Py_END_ALLOW_THREADS
3783 }
3784#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003785 goto exit;
3786 }
3787 if ((list = PyList_New(0)) == NULL) {
3788 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003789 }
3790 for (;;) {
3791 errno = 0;
3792 Py_BEGIN_ALLOW_THREADS
3793 ep = readdir(dirp);
3794 Py_END_ALLOW_THREADS
3795 if (ep == NULL) {
3796 if (errno == 0) {
3797 break;
3798 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003799 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003800 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003801 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 }
3803 }
3804 if (ep->d_name[0] == '.' &&
3805 (NAMLEN(ep) == 1 ||
3806 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3807 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003808 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003809 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3810 else
3811 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003813 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003814 break;
3815 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003816 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003818 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003819 break;
3820 }
3821 Py_DECREF(v);
3822 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003823
Larry Hastings9cf065c2012-06-22 16:30:09 -07003824exit:
3825 if (dirp != NULL) {
3826 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003827#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003828 if (fd > -1)
3829 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003830#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 closedir(dirp);
3832 Py_END_ALLOW_THREADS
3833 }
3834
Larry Hastings9cf065c2012-06-22 16:30:09 -07003835 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003836} /* end of _posix_listdir */
3837#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003838
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003839static PyObject *
3840posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3841{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003842 path_t path;
3843 PyObject *list = NULL;
3844 static char *keywords[] = {"path", NULL};
3845 PyObject *return_value;
3846
3847 memset(&path, 0, sizeof(path));
3848 path.function_name = "listdir";
3849 path.nullable = 1;
3850#ifdef HAVE_FDOPENDIR
3851 path.allow_fd = 1;
3852 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003853#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003854
3855 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3856 path_converter, &path)) {
3857 return NULL;
3858 }
3859
3860#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3861 return_value = _listdir_windows_no_opendir(&path, list);
3862#else
3863 return_value = _posix_listdir(&path, list);
3864#endif
3865 path_cleanup(&path);
3866 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003867}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003868
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003869#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003870/* A helper function for abspath on win32 */
3871static PyObject *
3872posix__getfullpathname(PyObject *self, PyObject *args)
3873{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003874 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 char outbuf[MAX_PATH*2];
3876 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003877 PyObject *po;
3878
3879 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3880 {
3881 wchar_t *wpath;
3882 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3883 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 DWORD result;
3885 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003886
3887 wpath = PyUnicode_AsUnicode(po);
3888 if (wpath == NULL)
3889 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003890 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003891 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003893 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003894 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 if (!woutbufp)
3896 return PyErr_NoMemory();
3897 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3898 }
3899 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003900 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003902 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003904 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 return v;
3906 }
3907 /* Drop the argument parsing error as narrow strings
3908 are also valid. */
3909 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003910
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003911 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3912 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003914 if (win32_warn_bytes_api())
3915 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003916 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 outbuf, &temp)) {
3918 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 return NULL;
3920 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003921 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3922 return PyUnicode_Decode(outbuf, strlen(outbuf),
3923 Py_FileSystemDefaultEncoding, NULL);
3924 }
3925 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003926} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003927
Brian Curtind25aef52011-06-13 15:16:04 -05003928
Brian Curtinf5e76d02010-11-24 13:14:05 +00003929
Brian Curtind40e6f72010-07-08 21:39:08 +00003930/* A helper function for samepath on windows */
3931static PyObject *
3932posix__getfinalpathname(PyObject *self, PyObject *args)
3933{
3934 HANDLE hFile;
3935 int buf_size;
3936 wchar_t *target_path;
3937 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003938 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003939 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003940
Victor Stinnereb5657a2011-09-30 01:44:27 +02003941 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003942 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003943 path = PyUnicode_AsUnicode(po);
3944 if (path == NULL)
3945 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003946
3947 if(!check_GetFinalPathNameByHandle()) {
3948 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3949 NotImplementedError. */
3950 return PyErr_Format(PyExc_NotImplementedError,
3951 "GetFinalPathNameByHandle not available on this platform");
3952 }
3953
3954 hFile = CreateFileW(
3955 path,
3956 0, /* desired access */
3957 0, /* share mode */
3958 NULL, /* security attributes */
3959 OPEN_EXISTING,
3960 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3961 FILE_FLAG_BACKUP_SEMANTICS,
3962 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003963
Victor Stinnereb5657a2011-09-30 01:44:27 +02003964 if(hFile == INVALID_HANDLE_VALUE)
3965 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003966
3967 /* We have a good handle to the target, use it to determine the
3968 target path name. */
3969 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3970
3971 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003972 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003973
Victor Stinnerb6404912013-07-07 16:21:41 +02003974 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003975 if(!target_path)
3976 return PyErr_NoMemory();
3977
3978 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3979 buf_size, VOLUME_NAME_DOS);
3980 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003981 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003982
3983 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003984 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003985
3986 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003987 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003988 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003989 return result;
3990
3991} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003992
Brian Curtin95d028f2011-06-09 09:10:38 -05003993PyDoc_STRVAR(posix__isdir__doc__,
3994"Return true if the pathname refers to an existing directory.");
3995
Brian Curtin9c669cc2011-06-08 18:17:18 -05003996static PyObject *
3997posix__isdir(PyObject *self, PyObject *args)
3998{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003999 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004000 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004001 DWORD attributes;
4002
4003 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004004 wchar_t *wpath = PyUnicode_AsUnicode(po);
4005 if (wpath == NULL)
4006 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004007
4008 attributes = GetFileAttributesW(wpath);
4009 if (attributes == INVALID_FILE_ATTRIBUTES)
4010 Py_RETURN_FALSE;
4011 goto check;
4012 }
4013 /* Drop the argument parsing error as narrow strings
4014 are also valid. */
4015 PyErr_Clear();
4016
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004017 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004018 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004019 if (win32_warn_bytes_api())
4020 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004021 attributes = GetFileAttributesA(path);
4022 if (attributes == INVALID_FILE_ATTRIBUTES)
4023 Py_RETURN_FALSE;
4024
4025check:
4026 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4027 Py_RETURN_TRUE;
4028 else
4029 Py_RETURN_FALSE;
4030}
Tim Golden6b528062013-08-01 12:44:00 +01004031
4032PyDoc_STRVAR(posix__getvolumepathname__doc__,
4033"Return volume mount point of the specified path.");
4034
4035/* A helper function for ismount on windows */
4036static PyObject *
4037posix__getvolumepathname(PyObject *self, PyObject *args)
4038{
4039 PyObject *po, *result;
4040 wchar_t *path, *mountpath=NULL;
4041 size_t bufsize;
4042 BOOL ret;
4043
4044 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4045 return NULL;
4046 path = PyUnicode_AsUnicode(po);
4047 if (path == NULL)
4048 return NULL;
4049
4050 /* Volume path should be shorter than entire path */
4051 bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
4052 mountpath = (wchar_t *)PyMem_Malloc(bufsize);
4053 if (mountpath == NULL)
4054 return PyErr_NoMemory();
4055
4056 Py_BEGIN_ALLOW_THREADS
4057 ret = GetVolumePathNameW(path, mountpath, bufsize);
4058 Py_END_ALLOW_THREADS
4059
4060 if (!ret) {
4061 result = win32_error_object("_getvolumepathname", po);
4062 goto exit;
4063 }
4064 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4065
4066exit:
4067 PyMem_Free(mountpath);
4068 return result;
4069}
4070/* end of posix__getvolumepathname */
4071
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004072#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004074PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004075"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4076Create a directory.\n\
4077\n\
4078If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4079 and path should be relative; path will then be relative to that directory.\n\
4080dir_fd may not be implemented on your platform.\n\
4081 If it is unavailable, using it will raise a NotImplementedError.\n\
4082\n\
4083The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004084
Barry Warsaw53699e91996-12-10 23:23:01 +00004085static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004087{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090 int dir_fd = DEFAULT_DIR_FD;
4091 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4092 PyObject *return_value = NULL;
4093 int result;
4094
4095 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004096 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4098 path_converter, &path, &mode,
4099#ifdef HAVE_MKDIRAT
4100 dir_fd_converter, &dir_fd
4101#else
4102 dir_fd_unavailable, &dir_fd
4103#endif
4104 ))
4105 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004106
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004108 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004109 if (path.wide)
4110 result = CreateDirectoryW(path.wide, NULL);
4111 else
4112 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004113 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004114
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004116 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004117 goto exit;
4118 }
4119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004120 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121#if HAVE_MKDIRAT
4122 if (dir_fd != DEFAULT_DIR_FD)
4123 result = mkdirat(dir_fd, path.narrow, mode);
4124 else
4125#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004126#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004128#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004130#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004133 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 goto exit;
4135 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004136#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 return_value = Py_None;
4138 Py_INCREF(Py_None);
4139exit:
4140 path_cleanup(&path);
4141 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004142}
4143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004144
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004145/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4146#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004147#include <sys/resource.h>
4148#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004149
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004150
4151#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004153"nice(inc) -> new_priority\n\n\
4154Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004155
Barry Warsaw53699e91996-12-10 23:23:01 +00004156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004157posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004158{
Victor Stinner8c62be82010-05-06 00:08:46 +00004159 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004160
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4162 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004163
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 /* There are two flavours of 'nice': one that returns the new
4165 priority (as required by almost all standards out there) and the
4166 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4167 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004168
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 If we are of the nice family that returns the new priority, we
4170 need to clear errno before the call, and check if errno is filled
4171 before calling posix_error() on a returnvalue of -1, because the
4172 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004173
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 errno = 0;
4175 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004176#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 if (value == 0)
4178 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004179#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 if (value == -1 && errno != 0)
4181 /* either nice() or getpriority() returned an error */
4182 return posix_error();
4183 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004184}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004185#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004186
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004187
4188#ifdef HAVE_GETPRIORITY
4189PyDoc_STRVAR(posix_getpriority__doc__,
4190"getpriority(which, who) -> current_priority\n\n\
4191Get program scheduling priority.");
4192
4193static PyObject *
4194posix_getpriority(PyObject *self, PyObject *args)
4195{
4196 int which, who, retval;
4197
4198 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4199 return NULL;
4200 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004201 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004202 if (errno != 0)
4203 return posix_error();
4204 return PyLong_FromLong((long)retval);
4205}
4206#endif /* HAVE_GETPRIORITY */
4207
4208
4209#ifdef HAVE_SETPRIORITY
4210PyDoc_STRVAR(posix_setpriority__doc__,
4211"setpriority(which, who, prio) -> None\n\n\
4212Set program scheduling priority.");
4213
4214static PyObject *
4215posix_setpriority(PyObject *self, PyObject *args)
4216{
4217 int which, who, prio, retval;
4218
4219 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4220 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004221 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004222 if (retval == -1)
4223 return posix_error();
4224 Py_RETURN_NONE;
4225}
4226#endif /* HAVE_SETPRIORITY */
4227
4228
Barry Warsaw53699e91996-12-10 23:23:01 +00004229static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232 char *function_name = is_replace ? "replace" : "rename";
4233 path_t src;
4234 path_t dst;
4235 int src_dir_fd = DEFAULT_DIR_FD;
4236 int dst_dir_fd = DEFAULT_DIR_FD;
4237 int dir_fd_specified;
4238 PyObject *return_value = NULL;
4239 char format[24];
4240 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4241
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004242#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004244 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004245#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004246 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004247#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004248
4249 memset(&src, 0, sizeof(src));
4250 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004251 src.function_name = function_name;
4252 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004253 strcpy(format, "O&O&|$O&O&:");
4254 strcat(format, function_name);
4255 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4256 path_converter, &src,
4257 path_converter, &dst,
4258 dir_fd_converter, &src_dir_fd,
4259 dir_fd_converter, &dst_dir_fd))
4260 return NULL;
4261
4262 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4263 (dst_dir_fd != DEFAULT_DIR_FD);
4264#ifndef HAVE_RENAMEAT
4265 if (dir_fd_specified) {
4266 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4267 goto exit;
4268 }
4269#endif
4270
4271 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4272 PyErr_Format(PyExc_ValueError,
4273 "%s: src and dst must be the same type", function_name);
4274 goto exit;
4275 }
4276
4277#ifdef MS_WINDOWS
4278 Py_BEGIN_ALLOW_THREADS
4279 if (src.wide)
4280 result = MoveFileExW(src.wide, dst.wide, flags);
4281 else
4282 result = MoveFileExA(src.narrow, dst.narrow, flags);
4283 Py_END_ALLOW_THREADS
4284
4285 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004286 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004287 goto exit;
4288 }
4289
4290#else
4291 Py_BEGIN_ALLOW_THREADS
4292#ifdef HAVE_RENAMEAT
4293 if (dir_fd_specified)
4294 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4295 else
4296#endif
4297 result = rename(src.narrow, dst.narrow);
4298 Py_END_ALLOW_THREADS
4299
4300 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004301 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302 goto exit;
4303 }
4304#endif
4305
4306 Py_INCREF(Py_None);
4307 return_value = Py_None;
4308exit:
4309 path_cleanup(&src);
4310 path_cleanup(&dst);
4311 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004312}
4313
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004314PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4316Rename a file or directory.\n\
4317\n\
4318If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4319 descriptor open to a directory, and the respective path string (src or dst)\n\
4320 should be relative; the path will then be relative to that directory.\n\
4321src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4322 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004323
4324static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004326{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004327 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004328}
4329
4330PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4332Rename a file or directory, overwriting the destination.\n\
4333\n\
4334If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4335 descriptor open to a directory, and the respective path string (src or dst)\n\
4336 should be relative; the path will then be relative to that directory.\n\
4337src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4338 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004339
4340static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004342{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004344}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004345
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004347"rmdir(path, *, dir_fd=None)\n\n\
4348Remove a directory.\n\
4349\n\
4350If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4351 and path should be relative; path will then be relative to that directory.\n\
4352dir_fd may not be implemented on your platform.\n\
4353 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004354
Barry Warsaw53699e91996-12-10 23:23:01 +00004355static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004356posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004357{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004358 path_t path;
4359 int dir_fd = DEFAULT_DIR_FD;
4360 static char *keywords[] = {"path", "dir_fd", NULL};
4361 int result;
4362 PyObject *return_value = NULL;
4363
4364 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004365 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004366 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4367 path_converter, &path,
4368#ifdef HAVE_UNLINKAT
4369 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004370#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004371 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004372#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004373 ))
4374 return NULL;
4375
4376 Py_BEGIN_ALLOW_THREADS
4377#ifdef MS_WINDOWS
4378 if (path.wide)
4379 result = RemoveDirectoryW(path.wide);
4380 else
4381 result = RemoveDirectoryA(path.narrow);
4382 result = !result; /* Windows, success=1, UNIX, success=0 */
4383#else
4384#ifdef HAVE_UNLINKAT
4385 if (dir_fd != DEFAULT_DIR_FD)
4386 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4387 else
4388#endif
4389 result = rmdir(path.narrow);
4390#endif
4391 Py_END_ALLOW_THREADS
4392
4393 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004394 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004395 goto exit;
4396 }
4397
4398 return_value = Py_None;
4399 Py_INCREF(Py_None);
4400
4401exit:
4402 path_cleanup(&path);
4403 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004404}
4405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004406
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004407#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004408PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004409"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004411
Barry Warsaw53699e91996-12-10 23:23:01 +00004412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004413posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004414{
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004416#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004417 wchar_t *command;
4418 if (!PyArg_ParseTuple(args, "u:system", &command))
4419 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004420
Victor Stinner8c62be82010-05-06 00:08:46 +00004421 Py_BEGIN_ALLOW_THREADS
4422 sts = _wsystem(command);
4423 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004424#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004425 PyObject *command_obj;
4426 char *command;
4427 if (!PyArg_ParseTuple(args, "O&:system",
4428 PyUnicode_FSConverter, &command_obj))
4429 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004430
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 command = PyBytes_AsString(command_obj);
4432 Py_BEGIN_ALLOW_THREADS
4433 sts = system(command);
4434 Py_END_ALLOW_THREADS
4435 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004436#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004437 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004438}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004439#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004441
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004445
Barry Warsaw53699e91996-12-10 23:23:01 +00004446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004447posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 int i;
4450 if (!PyArg_ParseTuple(args, "i:umask", &i))
4451 return NULL;
4452 i = (int)umask(i);
4453 if (i < 0)
4454 return posix_error();
4455 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004456}
4457
Brian Curtind40e6f72010-07-08 21:39:08 +00004458#ifdef MS_WINDOWS
4459
4460/* override the default DeleteFileW behavior so that directory
4461symlinks can be removed with this function, the same as with
4462Unix symlinks */
4463BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4464{
4465 WIN32_FILE_ATTRIBUTE_DATA info;
4466 WIN32_FIND_DATAW find_data;
4467 HANDLE find_data_handle;
4468 int is_directory = 0;
4469 int is_link = 0;
4470
4471 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4472 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004473
Brian Curtind40e6f72010-07-08 21:39:08 +00004474 /* Get WIN32_FIND_DATA structure for the path to determine if
4475 it is a symlink */
4476 if(is_directory &&
4477 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4478 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4479
4480 if(find_data_handle != INVALID_HANDLE_VALUE) {
4481 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4482 FindClose(find_data_handle);
4483 }
4484 }
4485 }
4486
4487 if (is_directory && is_link)
4488 return RemoveDirectoryW(lpFileName);
4489
4490 return DeleteFileW(lpFileName);
4491}
4492#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004494PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004495"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496Remove a file (same as remove()).\n\
4497\n\
4498If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4499 and path should be relative; path will then be relative to that directory.\n\
4500dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004501 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004504"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004505Remove a file (same as unlink()).\n\
4506\n\
4507If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4508 and path should be relative; path will then be relative to that directory.\n\
4509dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004510 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004511
Barry Warsaw53699e91996-12-10 23:23:01 +00004512static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004514{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515 path_t path;
4516 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004517 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 int result;
4519 PyObject *return_value = NULL;
4520
4521 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004522 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004523 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 path_converter, &path,
4525#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004526 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004527#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004528 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004529#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004530 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 return NULL;
4532
4533 Py_BEGIN_ALLOW_THREADS
4534#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004535 if (path.wide)
4536 result = Py_DeleteFileW(path.wide);
4537 else
4538 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539 result = !result; /* Windows, success=1, UNIX, success=0 */
4540#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541#ifdef HAVE_UNLINKAT
4542 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004543 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 else
4545#endif /* HAVE_UNLINKAT */
4546 result = unlink(path.narrow);
4547#endif
4548 Py_END_ALLOW_THREADS
4549
4550 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004551 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552 goto exit;
4553 }
4554
4555 return_value = Py_None;
4556 Py_INCREF(Py_None);
4557
4558exit:
4559 path_cleanup(&path);
4560 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004561}
4562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004563
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004564PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004565"uname() -> uname_result\n\n\
4566Return an object identifying the current operating system.\n\
4567The object behaves like a named tuple with the following fields:\n\
4568 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004569
Larry Hastings605a62d2012-06-24 04:33:36 -07004570static PyStructSequence_Field uname_result_fields[] = {
4571 {"sysname", "operating system name"},
4572 {"nodename", "name of machine on network (implementation-defined)"},
4573 {"release", "operating system release"},
4574 {"version", "operating system version"},
4575 {"machine", "hardware identifier"},
4576 {NULL}
4577};
4578
4579PyDoc_STRVAR(uname_result__doc__,
4580"uname_result: Result from os.uname().\n\n\
4581This object may be accessed either as a tuple of\n\
4582 (sysname, nodename, release, version, machine),\n\
4583or via the attributes sysname, nodename, release, version, and machine.\n\
4584\n\
4585See os.uname for more information.");
4586
4587static PyStructSequence_Desc uname_result_desc = {
4588 "uname_result", /* name */
4589 uname_result__doc__, /* doc */
4590 uname_result_fields,
4591 5
4592};
4593
4594static PyTypeObject UnameResultType;
4595
4596
4597#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004598static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004599posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004600{
Victor Stinner8c62be82010-05-06 00:08:46 +00004601 struct utsname u;
4602 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004603 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004604
Victor Stinner8c62be82010-05-06 00:08:46 +00004605 Py_BEGIN_ALLOW_THREADS
4606 res = uname(&u);
4607 Py_END_ALLOW_THREADS
4608 if (res < 0)
4609 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004610
4611 value = PyStructSequence_New(&UnameResultType);
4612 if (value == NULL)
4613 return NULL;
4614
4615#define SET(i, field) \
4616 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004617 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004618 if (!o) { \
4619 Py_DECREF(value); \
4620 return NULL; \
4621 } \
4622 PyStructSequence_SET_ITEM(value, i, o); \
4623 } \
4624
4625 SET(0, u.sysname);
4626 SET(1, u.nodename);
4627 SET(2, u.release);
4628 SET(3, u.version);
4629 SET(4, u.machine);
4630
4631#undef SET
4632
4633 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004634}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004635#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004636
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004637
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638PyDoc_STRVAR(posix_utime__doc__,
4639"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4640Set the access and modified time of path.\n\
4641\n\
4642path may always be specified as a string.\n\
4643On some platforms, path may also be specified as an open file descriptor.\n\
4644 If this functionality is unavailable, using it raises an exception.\n\
4645\n\
4646If times is not None, it must be a tuple (atime, mtime);\n\
4647 atime and mtime should be expressed as float seconds since the epoch.\n\
4648If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4649 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4650 since the epoch.\n\
4651If both times and ns are None, utime uses the current time.\n\
4652Specifying tuples for both times and ns is an error.\n\
4653\n\
4654If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4655 and path should be relative; path will then be relative to that directory.\n\
4656If follow_symlinks is False, and the last element of the path is a symbolic\n\
4657 link, utime will modify the symbolic link itself instead of the file the\n\
4658 link points to.\n\
4659It is an error to use dir_fd or follow_symlinks when specifying path\n\
4660 as an open file descriptor.\n\
4661dir_fd and follow_symlinks may not be available on your platform.\n\
4662 If they are unavailable, using them will raise a NotImplementedError.");
4663
4664typedef struct {
4665 int now;
4666 time_t atime_s;
4667 long atime_ns;
4668 time_t mtime_s;
4669 long mtime_ns;
4670} utime_t;
4671
4672/*
4673 * these macros assume that "utime" is a pointer to a utime_t
4674 * they also intentionally leak the declaration of a pointer named "time"
4675 */
4676#define UTIME_TO_TIMESPEC \
4677 struct timespec ts[2]; \
4678 struct timespec *time; \
4679 if (utime->now) \
4680 time = NULL; \
4681 else { \
4682 ts[0].tv_sec = utime->atime_s; \
4683 ts[0].tv_nsec = utime->atime_ns; \
4684 ts[1].tv_sec = utime->mtime_s; \
4685 ts[1].tv_nsec = utime->mtime_ns; \
4686 time = ts; \
4687 } \
4688
4689#define UTIME_TO_TIMEVAL \
4690 struct timeval tv[2]; \
4691 struct timeval *time; \
4692 if (utime->now) \
4693 time = NULL; \
4694 else { \
4695 tv[0].tv_sec = utime->atime_s; \
4696 tv[0].tv_usec = utime->atime_ns / 1000; \
4697 tv[1].tv_sec = utime->mtime_s; \
4698 tv[1].tv_usec = utime->mtime_ns / 1000; \
4699 time = tv; \
4700 } \
4701
4702#define UTIME_TO_UTIMBUF \
4703 struct utimbuf u[2]; \
4704 struct utimbuf *time; \
4705 if (utime->now) \
4706 time = NULL; \
4707 else { \
4708 u.actime = utime->atime_s; \
4709 u.modtime = utime->mtime_s; \
4710 time = u; \
4711 }
4712
4713#define UTIME_TO_TIME_T \
4714 time_t timet[2]; \
4715 struct timet time; \
4716 if (utime->now) \
4717 time = NULL; \
4718 else { \
4719 timet[0] = utime->atime_s; \
4720 timet[1] = utime->mtime_s; \
4721 time = &timet; \
4722 } \
4723
4724
4725#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4726
4727#if UTIME_HAVE_DIR_FD
4728
4729static int
4730utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4731{
4732#ifdef HAVE_UTIMENSAT
4733 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4734 UTIME_TO_TIMESPEC;
4735 return utimensat(dir_fd, path, time, flags);
4736#elif defined(HAVE_FUTIMESAT)
4737 UTIME_TO_TIMEVAL;
4738 /*
4739 * follow_symlinks will never be false here;
4740 * we only allow !follow_symlinks and dir_fd together
4741 * if we have utimensat()
4742 */
4743 assert(follow_symlinks);
4744 return futimesat(dir_fd, path, time);
4745#endif
4746}
4747
4748#endif
4749
4750#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4751
4752#if UTIME_HAVE_FD
4753
4754static int
4755utime_fd(utime_t *utime, int fd)
4756{
4757#ifdef HAVE_FUTIMENS
4758 UTIME_TO_TIMESPEC;
4759 return futimens(fd, time);
4760#else
4761 UTIME_TO_TIMEVAL;
4762 return futimes(fd, time);
4763#endif
4764}
4765
4766#endif
4767
4768
4769#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4770 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4771
4772#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4773
4774static int
4775utime_nofollow_symlinks(utime_t *utime, char *path)
4776{
4777#ifdef HAVE_UTIMENSAT
4778 UTIME_TO_TIMESPEC;
4779 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4780#else
4781 UTIME_TO_TIMEVAL;
4782 return lutimes(path, time);
4783#endif
4784}
4785
4786#endif
4787
4788#ifndef MS_WINDOWS
4789
4790static int
4791utime_default(utime_t *utime, char *path)
4792{
4793#ifdef HAVE_UTIMENSAT
4794 UTIME_TO_TIMESPEC;
4795 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4796#elif defined(HAVE_UTIMES)
4797 UTIME_TO_TIMEVAL;
4798 return utimes(path, time);
4799#elif defined(HAVE_UTIME_H)
4800 UTIME_TO_UTIMBUF;
4801 return utime(path, time);
4802#else
4803 UTIME_TO_TIME_T;
4804 return utime(path, time);
4805#endif
4806}
4807
4808#endif
4809
Larry Hastings76ad59b2012-05-03 00:30:07 -07004810static int
4811split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4812{
4813 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004814 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004815 divmod = PyNumber_Divmod(py_long, billion);
4816 if (!divmod)
4817 goto exit;
4818 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4819 if ((*s == -1) && PyErr_Occurred())
4820 goto exit;
4821 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004822 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004823 goto exit;
4824
4825 result = 1;
4826exit:
4827 Py_XDECREF(divmod);
4828 return result;
4829}
4830
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831static PyObject *
4832posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004833{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004835 PyObject *times = NULL;
4836 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837 int dir_fd = DEFAULT_DIR_FD;
4838 int follow_symlinks = 1;
4839 char *keywords[] = {"path", "times", "ns", "dir_fd",
4840 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004841
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004843
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844#ifdef MS_WINDOWS
4845 HANDLE hFile;
4846 FILETIME atime, mtime;
4847#else
4848 int result;
4849#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004850
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004852
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004854 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004855 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856#if UTIME_HAVE_FD
4857 path.allow_fd = 1;
4858#endif
4859 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4860 "O&|O$OO&p:utime", keywords,
4861 path_converter, &path,
4862 &times, &ns,
4863#if UTIME_HAVE_DIR_FD
4864 dir_fd_converter, &dir_fd,
4865#else
4866 dir_fd_unavailable, &dir_fd,
4867#endif
4868 &follow_symlinks
4869 ))
4870 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004871
Larry Hastings9cf065c2012-06-22 16:30:09 -07004872 if (times && (times != Py_None) && ns) {
4873 PyErr_SetString(PyExc_ValueError,
4874 "utime: you may specify either 'times'"
4875 " or 'ns' but not both");
4876 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004877 }
4878
4879 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004880 time_t a_sec, m_sec;
4881 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004882 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 PyErr_SetString(PyExc_TypeError,
4884 "utime: 'times' must be either"
4885 " a tuple of two ints or None");
4886 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004887 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004888 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004889 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004890 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004891 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004892 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004894 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004895 utime.atime_s = a_sec;
4896 utime.atime_ns = a_nsec;
4897 utime.mtime_s = m_sec;
4898 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004899 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004901 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004902 PyErr_SetString(PyExc_TypeError,
4903 "utime: 'ns' must be a tuple of two ints");
4904 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004905 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004906 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004907 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004908 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004909 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004910 &utime.mtime_s, &utime.mtime_ns)) {
4911 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004912 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004913 }
4914 else {
4915 /* times and ns are both None/unspecified. use "now". */
4916 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004917 }
4918
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4920 if (follow_symlinks_specified("utime", follow_symlinks))
4921 goto exit;
4922#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004923
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4925 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4926 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4927 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004928
Larry Hastings9cf065c2012-06-22 16:30:09 -07004929#if !defined(HAVE_UTIMENSAT)
4930 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004931 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004932 "utime: cannot use dir_fd and follow_symlinks "
4933 "together on this platform");
4934 goto exit;
4935 }
4936#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004937
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004938#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939 Py_BEGIN_ALLOW_THREADS
4940 if (path.wide)
4941 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 NULL, OPEN_EXISTING,
4943 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004944 else
4945 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 NULL, OPEN_EXISTING,
4947 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004948 Py_END_ALLOW_THREADS
4949 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004950 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004951 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004952 }
4953
Larry Hastings9cf065c2012-06-22 16:30:09 -07004954 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 SYSTEMTIME now;
4956 GetSystemTime(&now);
4957 if (!SystemTimeToFileTime(&now, &mtime) ||
4958 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004959 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004961 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4965 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 }
4967 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4968 /* Avoid putting the file name into the error here,
4969 as that may confuse the user into believing that
4970 something is wrong with the file, when it also
4971 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004972 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004973 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004975#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004976 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004977
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4979 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4980 result = utime_nofollow_symlinks(&utime, path.narrow);
4981 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004982#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983
4984#if UTIME_HAVE_DIR_FD
4985 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4986 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4987 else
4988#endif
4989
4990#if UTIME_HAVE_FD
4991 if (path.fd != -1)
4992 result = utime_fd(&utime, path.fd);
4993 else
4994#endif
4995
4996 result = utime_default(&utime, path.narrow);
4997
4998 Py_END_ALLOW_THREADS
4999
5000 if (result < 0) {
5001 /* see previous comment about not putting filename in error here */
5002 return_value = posix_error();
5003 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005004 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005005
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005006#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007
5008 Py_INCREF(Py_None);
5009 return_value = Py_None;
5010
5011exit:
5012 path_cleanup(&path);
5013#ifdef MS_WINDOWS
5014 if (hFile != INVALID_HANDLE_VALUE)
5015 CloseHandle(hFile);
5016#endif
5017 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005018}
5019
Guido van Rossum3b066191991-06-04 19:40:25 +00005020/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005022PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005023"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005024Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005025
Barry Warsaw53699e91996-12-10 23:23:01 +00005026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005027posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005028{
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 int sts;
5030 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5031 return NULL;
5032 _exit(sts);
5033 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005034}
5035
Martin v. Löwis114619e2002-10-07 06:44:21 +00005036#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5037static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005038free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005039{
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 Py_ssize_t i;
5041 for (i = 0; i < count; i++)
5042 PyMem_Free(array[i]);
5043 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005044}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005045
Antoine Pitrou69f71142009-05-24 21:25:49 +00005046static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005047int fsconvert_strdup(PyObject *o, char**out)
5048{
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 PyObject *bytes;
5050 Py_ssize_t size;
5051 if (!PyUnicode_FSConverter(o, &bytes))
5052 return 0;
5053 size = PyBytes_GET_SIZE(bytes);
5054 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005055 if (!*out) {
5056 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005058 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 memcpy(*out, PyBytes_AsString(bytes), size+1);
5060 Py_DECREF(bytes);
5061 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005062}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005063#endif
5064
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005066static char**
5067parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5068{
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 char **envlist;
5070 Py_ssize_t i, pos, envc;
5071 PyObject *keys=NULL, *vals=NULL;
5072 PyObject *key, *val, *key2, *val2;
5073 char *p, *k, *v;
5074 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005075
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 i = PyMapping_Size(env);
5077 if (i < 0)
5078 return NULL;
5079 envlist = PyMem_NEW(char *, i + 1);
5080 if (envlist == NULL) {
5081 PyErr_NoMemory();
5082 return NULL;
5083 }
5084 envc = 0;
5085 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005086 if (!keys)
5087 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005088 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005089 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 goto error;
5091 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5092 PyErr_Format(PyExc_TypeError,
5093 "env.keys() or env.values() is not a list");
5094 goto error;
5095 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005096
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 for (pos = 0; pos < i; pos++) {
5098 key = PyList_GetItem(keys, pos);
5099 val = PyList_GetItem(vals, pos);
5100 if (!key || !val)
5101 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 if (PyUnicode_FSConverter(key, &key2) == 0)
5104 goto error;
5105 if (PyUnicode_FSConverter(val, &val2) == 0) {
5106 Py_DECREF(key2);
5107 goto error;
5108 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 k = PyBytes_AsString(key2);
5111 v = PyBytes_AsString(val2);
5112 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 p = PyMem_NEW(char, len);
5115 if (p == NULL) {
5116 PyErr_NoMemory();
5117 Py_DECREF(key2);
5118 Py_DECREF(val2);
5119 goto error;
5120 }
5121 PyOS_snprintf(p, len, "%s=%s", k, v);
5122 envlist[envc++] = p;
5123 Py_DECREF(key2);
5124 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005125 }
5126 Py_DECREF(vals);
5127 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005128
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 envlist[envc] = 0;
5130 *envc_ptr = envc;
5131 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005132
5133error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 Py_XDECREF(keys);
5135 Py_XDECREF(vals);
5136 while (--envc >= 0)
5137 PyMem_DEL(envlist[envc]);
5138 PyMem_DEL(envlist);
5139 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005140}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005141
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142static char**
5143parse_arglist(PyObject* argv, Py_ssize_t *argc)
5144{
5145 int i;
5146 char **argvlist = PyMem_NEW(char *, *argc+1);
5147 if (argvlist == NULL) {
5148 PyErr_NoMemory();
5149 return NULL;
5150 }
5151 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005152 PyObject* item = PySequence_ITEM(argv, i);
5153 if (item == NULL)
5154 goto fail;
5155 if (!fsconvert_strdup(item, &argvlist[i])) {
5156 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005157 goto fail;
5158 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005159 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 }
5161 argvlist[*argc] = NULL;
5162 return argvlist;
5163fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005164 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005165 free_string_array(argvlist, *argc);
5166 return NULL;
5167}
5168#endif
5169
5170#ifdef HAVE_EXECV
5171PyDoc_STRVAR(posix_execv__doc__,
5172"execv(path, args)\n\n\
5173Execute an executable path with arguments, replacing current process.\n\
5174\n\
5175 path: path of executable file\n\
5176 args: tuple or list of strings");
5177
5178static PyObject *
5179posix_execv(PyObject *self, PyObject *args)
5180{
5181 PyObject *opath;
5182 char *path;
5183 PyObject *argv;
5184 char **argvlist;
5185 Py_ssize_t argc;
5186
5187 /* execv has two arguments: (path, argv), where
5188 argv is a list or tuple of strings. */
5189
5190 if (!PyArg_ParseTuple(args, "O&O:execv",
5191 PyUnicode_FSConverter,
5192 &opath, &argv))
5193 return NULL;
5194 path = PyBytes_AsString(opath);
5195 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5196 PyErr_SetString(PyExc_TypeError,
5197 "execv() arg 2 must be a tuple or list");
5198 Py_DECREF(opath);
5199 return NULL;
5200 }
5201 argc = PySequence_Size(argv);
5202 if (argc < 1) {
5203 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5204 Py_DECREF(opath);
5205 return NULL;
5206 }
5207
5208 argvlist = parse_arglist(argv, &argc);
5209 if (argvlist == NULL) {
5210 Py_DECREF(opath);
5211 return NULL;
5212 }
5213
5214 execv(path, argvlist);
5215
5216 /* If we get here it's definitely an error */
5217
5218 free_string_array(argvlist, argc);
5219 Py_DECREF(opath);
5220 return posix_error();
5221}
5222
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005223PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005224"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005225Execute a path with arguments and environment, replacing current process.\n\
5226\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005227 path: path of executable file\n\
5228 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005229 env: dictionary of strings mapping to strings\n\
5230\n\
5231On some platforms, you may specify an open file descriptor for path;\n\
5232 execve will execute the program the file descriptor is open to.\n\
5233 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005234
Barry Warsaw53699e91996-12-10 23:23:01 +00005235static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005236posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005237{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005238 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005239 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005240 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005241 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005242 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005243 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005244
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 /* execve has three arguments: (path, argv, env), where
5246 argv is a list or tuple of strings and env is a dictionary
5247 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005248
Larry Hastings9cf065c2012-06-22 16:30:09 -07005249 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005250 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005251#ifdef HAVE_FEXECVE
5252 path.allow_fd = 1;
5253#endif
5254 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5255 path_converter, &path,
5256 &argv, &env
5257 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005259
Ross Lagerwall7807c352011-03-17 20:20:30 +02005260 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005262 "execve: argv must be a tuple or list");
5263 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005265 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 if (!PyMapping_Check(env)) {
5267 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005268 "execve: environment must be a mapping object");
5269 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005271
Ross Lagerwall7807c352011-03-17 20:20:30 +02005272 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005274 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005276
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 envlist = parse_envlist(env, &envc);
5278 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005279 goto fail;
5280
Larry Hastings9cf065c2012-06-22 16:30:09 -07005281#ifdef HAVE_FEXECVE
5282 if (path.fd > -1)
5283 fexecve(path.fd, argvlist, envlist);
5284 else
5285#endif
5286 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005287
5288 /* If we get here it's definitely an error */
5289
Victor Stinner292c8352012-10-30 02:17:38 +01005290 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005291
5292 while (--envc >= 0)
5293 PyMem_DEL(envlist[envc]);
5294 PyMem_DEL(envlist);
5295 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005296 if (argvlist)
5297 free_string_array(argvlist, argc);
5298 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005299 return NULL;
5300}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005301#endif /* HAVE_EXECV */
5302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005303
Guido van Rossuma1065681999-01-25 23:20:23 +00005304#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005306"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005307Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005308\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 mode: mode of process creation\n\
5310 path: path of executable file\n\
5311 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005312
5313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005314posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005315{
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 PyObject *opath;
5317 char *path;
5318 PyObject *argv;
5319 char **argvlist;
5320 int mode, i;
5321 Py_ssize_t argc;
5322 Py_intptr_t spawnval;
5323 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005324
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 /* spawnv has three arguments: (mode, path, argv), where
5326 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005327
Victor Stinner8c62be82010-05-06 00:08:46 +00005328 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5329 PyUnicode_FSConverter,
5330 &opath, &argv))
5331 return NULL;
5332 path = PyBytes_AsString(opath);
5333 if (PyList_Check(argv)) {
5334 argc = PyList_Size(argv);
5335 getitem = PyList_GetItem;
5336 }
5337 else if (PyTuple_Check(argv)) {
5338 argc = PyTuple_Size(argv);
5339 getitem = PyTuple_GetItem;
5340 }
5341 else {
5342 PyErr_SetString(PyExc_TypeError,
5343 "spawnv() arg 2 must be a tuple or list");
5344 Py_DECREF(opath);
5345 return NULL;
5346 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 argvlist = PyMem_NEW(char *, argc+1);
5349 if (argvlist == NULL) {
5350 Py_DECREF(opath);
5351 return PyErr_NoMemory();
5352 }
5353 for (i = 0; i < argc; i++) {
5354 if (!fsconvert_strdup((*getitem)(argv, i),
5355 &argvlist[i])) {
5356 free_string_array(argvlist, i);
5357 PyErr_SetString(
5358 PyExc_TypeError,
5359 "spawnv() arg 2 must contain only strings");
5360 Py_DECREF(opath);
5361 return NULL;
5362 }
5363 }
5364 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005365
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 if (mode == _OLD_P_OVERLAY)
5367 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005368
Victor Stinner8c62be82010-05-06 00:08:46 +00005369 Py_BEGIN_ALLOW_THREADS
5370 spawnval = _spawnv(mode, path, argvlist);
5371 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005372
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 free_string_array(argvlist, argc);
5374 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005375
Victor Stinner8c62be82010-05-06 00:08:46 +00005376 if (spawnval == -1)
5377 return posix_error();
5378 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005379 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005380}
5381
5382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005384"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005385Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005386\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 mode: mode of process creation\n\
5388 path: path of executable file\n\
5389 args: tuple or list of arguments\n\
5390 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005391
5392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005394{
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 PyObject *opath;
5396 char *path;
5397 PyObject *argv, *env;
5398 char **argvlist;
5399 char **envlist;
5400 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005401 int mode;
5402 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 Py_intptr_t spawnval;
5404 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5405 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005406
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 /* spawnve has four arguments: (mode, path, argv, env), where
5408 argv is a list or tuple of strings and env is a dictionary
5409 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005410
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5412 PyUnicode_FSConverter,
5413 &opath, &argv, &env))
5414 return NULL;
5415 path = PyBytes_AsString(opath);
5416 if (PyList_Check(argv)) {
5417 argc = PyList_Size(argv);
5418 getitem = PyList_GetItem;
5419 }
5420 else if (PyTuple_Check(argv)) {
5421 argc = PyTuple_Size(argv);
5422 getitem = PyTuple_GetItem;
5423 }
5424 else {
5425 PyErr_SetString(PyExc_TypeError,
5426 "spawnve() arg 2 must be a tuple or list");
5427 goto fail_0;
5428 }
5429 if (!PyMapping_Check(env)) {
5430 PyErr_SetString(PyExc_TypeError,
5431 "spawnve() arg 3 must be a mapping object");
5432 goto fail_0;
5433 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005434
Victor Stinner8c62be82010-05-06 00:08:46 +00005435 argvlist = PyMem_NEW(char *, argc+1);
5436 if (argvlist == NULL) {
5437 PyErr_NoMemory();
5438 goto fail_0;
5439 }
5440 for (i = 0; i < argc; i++) {
5441 if (!fsconvert_strdup((*getitem)(argv, i),
5442 &argvlist[i]))
5443 {
5444 lastarg = i;
5445 goto fail_1;
5446 }
5447 }
5448 lastarg = argc;
5449 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005450
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 envlist = parse_envlist(env, &envc);
5452 if (envlist == NULL)
5453 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005454
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 if (mode == _OLD_P_OVERLAY)
5456 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005457
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 Py_BEGIN_ALLOW_THREADS
5459 spawnval = _spawnve(mode, path, argvlist, envlist);
5460 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005461
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 if (spawnval == -1)
5463 (void) posix_error();
5464 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005465 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005466
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 while (--envc >= 0)
5468 PyMem_DEL(envlist[envc]);
5469 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005470 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005472 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 Py_DECREF(opath);
5474 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005475}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005476
Guido van Rossuma1065681999-01-25 23:20:23 +00005477#endif /* HAVE_SPAWNV */
5478
5479
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005480#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005482"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005483Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5484\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005486
5487static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005488posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005489{
Victor Stinner8c62be82010-05-06 00:08:46 +00005490 pid_t pid;
5491 int result = 0;
5492 _PyImport_AcquireLock();
5493 pid = fork1();
5494 if (pid == 0) {
5495 /* child: this clobbers and resets the import lock. */
5496 PyOS_AfterFork();
5497 } else {
5498 /* parent: release the import lock. */
5499 result = _PyImport_ReleaseLock();
5500 }
5501 if (pid == -1)
5502 return posix_error();
5503 if (result < 0) {
5504 /* Don't clobber the OSError if the fork failed. */
5505 PyErr_SetString(PyExc_RuntimeError,
5506 "not holding the import lock");
5507 return NULL;
5508 }
5509 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005510}
5511#endif
5512
5513
Guido van Rossumad0ee831995-03-01 10:34:45 +00005514#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005517Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005518Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005519
Barry Warsaw53699e91996-12-10 23:23:01 +00005520static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005521posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005522{
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 pid_t pid;
5524 int result = 0;
5525 _PyImport_AcquireLock();
5526 pid = fork();
5527 if (pid == 0) {
5528 /* child: this clobbers and resets the import lock. */
5529 PyOS_AfterFork();
5530 } else {
5531 /* parent: release the import lock. */
5532 result = _PyImport_ReleaseLock();
5533 }
5534 if (pid == -1)
5535 return posix_error();
5536 if (result < 0) {
5537 /* Don't clobber the OSError if the fork failed. */
5538 PyErr_SetString(PyExc_RuntimeError,
5539 "not holding the import lock");
5540 return NULL;
5541 }
5542 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005543}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005544#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005545
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005546#ifdef HAVE_SCHED_H
5547
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005548#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5549
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005550PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5551"sched_get_priority_max(policy)\n\n\
5552Get the maximum scheduling priority for *policy*.");
5553
5554static PyObject *
5555posix_sched_get_priority_max(PyObject *self, PyObject *args)
5556{
5557 int policy, max;
5558
5559 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5560 return NULL;
5561 max = sched_get_priority_max(policy);
5562 if (max < 0)
5563 return posix_error();
5564 return PyLong_FromLong(max);
5565}
5566
5567PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5568"sched_get_priority_min(policy)\n\n\
5569Get the minimum scheduling priority for *policy*.");
5570
5571static PyObject *
5572posix_sched_get_priority_min(PyObject *self, PyObject *args)
5573{
5574 int policy, min;
5575
5576 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5577 return NULL;
5578 min = sched_get_priority_min(policy);
5579 if (min < 0)
5580 return posix_error();
5581 return PyLong_FromLong(min);
5582}
5583
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005584#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5585
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005586#ifdef HAVE_SCHED_SETSCHEDULER
5587
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005588PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5589"sched_getscheduler(pid)\n\n\
5590Get the scheduling policy for the process with a PID of *pid*.\n\
5591Passing a PID of 0 returns the scheduling policy for the calling process.");
5592
5593static PyObject *
5594posix_sched_getscheduler(PyObject *self, PyObject *args)
5595{
5596 pid_t pid;
5597 int policy;
5598
5599 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5600 return NULL;
5601 policy = sched_getscheduler(pid);
5602 if (policy < 0)
5603 return posix_error();
5604 return PyLong_FromLong(policy);
5605}
5606
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005607#endif
5608
5609#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5610
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611static PyObject *
5612sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5613{
5614 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005615 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005616
5617 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5618 return NULL;
5619 res = PyStructSequence_New(type);
5620 if (!res)
5621 return NULL;
5622 Py_INCREF(priority);
5623 PyStructSequence_SET_ITEM(res, 0, priority);
5624 return res;
5625}
5626
5627PyDoc_STRVAR(sched_param__doc__,
5628"sched_param(sched_priority): A scheduling parameter.\n\n\
5629Current has only one field: sched_priority");
5630
5631static PyStructSequence_Field sched_param_fields[] = {
5632 {"sched_priority", "the scheduling priority"},
5633 {0}
5634};
5635
5636static PyStructSequence_Desc sched_param_desc = {
5637 "sched_param", /* name */
5638 sched_param__doc__, /* doc */
5639 sched_param_fields,
5640 1
5641};
5642
5643static int
5644convert_sched_param(PyObject *param, struct sched_param *res)
5645{
5646 long priority;
5647
5648 if (Py_TYPE(param) != &SchedParamType) {
5649 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5650 return 0;
5651 }
5652 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5653 if (priority == -1 && PyErr_Occurred())
5654 return 0;
5655 if (priority > INT_MAX || priority < INT_MIN) {
5656 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5657 return 0;
5658 }
5659 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5660 return 1;
5661}
5662
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005663#endif
5664
5665#ifdef HAVE_SCHED_SETSCHEDULER
5666
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005667PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5668"sched_setscheduler(pid, policy, param)\n\n\
5669Set the scheduling policy, *policy*, for *pid*.\n\
5670If *pid* is 0, the calling process is changed.\n\
5671*param* is an instance of sched_param.");
5672
5673static PyObject *
5674posix_sched_setscheduler(PyObject *self, PyObject *args)
5675{
5676 pid_t pid;
5677 int policy;
5678 struct sched_param param;
5679
5680 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5681 &pid, &policy, &convert_sched_param, &param))
5682 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005683
5684 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005685 ** sched_setscheduler() returns 0 in Linux, but the previous
5686 ** scheduling policy under Solaris/Illumos, and others.
5687 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005688 */
5689 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005690 return posix_error();
5691 Py_RETURN_NONE;
5692}
5693
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005694#endif
5695
5696#ifdef HAVE_SCHED_SETPARAM
5697
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005698PyDoc_STRVAR(posix_sched_getparam__doc__,
5699"sched_getparam(pid) -> sched_param\n\n\
5700Returns scheduling parameters for the process with *pid* as an instance of the\n\
5701sched_param class. A PID of 0 means the calling process.");
5702
5703static PyObject *
5704posix_sched_getparam(PyObject *self, PyObject *args)
5705{
5706 pid_t pid;
5707 struct sched_param param;
5708 PyObject *res, *priority;
5709
5710 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5711 return NULL;
5712 if (sched_getparam(pid, &param))
5713 return posix_error();
5714 res = PyStructSequence_New(&SchedParamType);
5715 if (!res)
5716 return NULL;
5717 priority = PyLong_FromLong(param.sched_priority);
5718 if (!priority) {
5719 Py_DECREF(res);
5720 return NULL;
5721 }
5722 PyStructSequence_SET_ITEM(res, 0, priority);
5723 return res;
5724}
5725
5726PyDoc_STRVAR(posix_sched_setparam__doc__,
5727"sched_setparam(pid, param)\n\n\
5728Set scheduling parameters for a process with PID *pid*.\n\
5729A PID of 0 means the calling process.");
5730
5731static PyObject *
5732posix_sched_setparam(PyObject *self, PyObject *args)
5733{
5734 pid_t pid;
5735 struct sched_param param;
5736
5737 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5738 &pid, &convert_sched_param, &param))
5739 return NULL;
5740 if (sched_setparam(pid, &param))
5741 return posix_error();
5742 Py_RETURN_NONE;
5743}
5744
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005745#endif
5746
5747#ifdef HAVE_SCHED_RR_GET_INTERVAL
5748
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5750"sched_rr_get_interval(pid) -> float\n\n\
5751Return the round-robin quantum for the process with PID *pid* in seconds.");
5752
5753static PyObject *
5754posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5755{
5756 pid_t pid;
5757 struct timespec interval;
5758
5759 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5760 return NULL;
5761 if (sched_rr_get_interval(pid, &interval))
5762 return posix_error();
5763 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5764}
5765
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005766#endif
5767
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005768PyDoc_STRVAR(posix_sched_yield__doc__,
5769"sched_yield()\n\n\
5770Voluntarily relinquish the CPU.");
5771
5772static PyObject *
5773posix_sched_yield(PyObject *self, PyObject *noargs)
5774{
5775 if (sched_yield())
5776 return posix_error();
5777 Py_RETURN_NONE;
5778}
5779
Benjamin Peterson2740af82011-08-02 17:41:34 -05005780#ifdef HAVE_SCHED_SETAFFINITY
5781
Antoine Pitrou84869872012-08-04 16:16:35 +02005782/* The minimum number of CPUs allocated in a cpu_set_t */
5783static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005784
5785PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5786"sched_setaffinity(pid, cpu_set)\n\n\
5787Set the affinity of the process with PID *pid* to *cpu_set*.");
5788
5789static PyObject *
5790posix_sched_setaffinity(PyObject *self, PyObject *args)
5791{
5792 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005793 int ncpus;
5794 size_t setsize;
5795 cpu_set_t *mask = NULL;
5796 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797
Antoine Pitrou84869872012-08-04 16:16:35 +02005798 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5799 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005800 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005801
5802 iterator = PyObject_GetIter(iterable);
5803 if (iterator == NULL)
5804 return NULL;
5805
5806 ncpus = NCPUS_START;
5807 setsize = CPU_ALLOC_SIZE(ncpus);
5808 mask = CPU_ALLOC(ncpus);
5809 if (mask == NULL) {
5810 PyErr_NoMemory();
5811 goto error;
5812 }
5813 CPU_ZERO_S(setsize, mask);
5814
5815 while ((item = PyIter_Next(iterator))) {
5816 long cpu;
5817 if (!PyLong_Check(item)) {
5818 PyErr_Format(PyExc_TypeError,
5819 "expected an iterator of ints, "
5820 "but iterator yielded %R",
5821 Py_TYPE(item));
5822 Py_DECREF(item);
5823 goto error;
5824 }
5825 cpu = PyLong_AsLong(item);
5826 Py_DECREF(item);
5827 if (cpu < 0) {
5828 if (!PyErr_Occurred())
5829 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5830 goto error;
5831 }
5832 if (cpu > INT_MAX - 1) {
5833 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5834 goto error;
5835 }
5836 if (cpu >= ncpus) {
5837 /* Grow CPU mask to fit the CPU number */
5838 int newncpus = ncpus;
5839 cpu_set_t *newmask;
5840 size_t newsetsize;
5841 while (newncpus <= cpu) {
5842 if (newncpus > INT_MAX / 2)
5843 newncpus = cpu + 1;
5844 else
5845 newncpus = newncpus * 2;
5846 }
5847 newmask = CPU_ALLOC(newncpus);
5848 if (newmask == NULL) {
5849 PyErr_NoMemory();
5850 goto error;
5851 }
5852 newsetsize = CPU_ALLOC_SIZE(newncpus);
5853 CPU_ZERO_S(newsetsize, newmask);
5854 memcpy(newmask, mask, setsize);
5855 CPU_FREE(mask);
5856 setsize = newsetsize;
5857 mask = newmask;
5858 ncpus = newncpus;
5859 }
5860 CPU_SET_S(cpu, setsize, mask);
5861 }
5862 Py_CLEAR(iterator);
5863
5864 if (sched_setaffinity(pid, setsize, mask)) {
5865 posix_error();
5866 goto error;
5867 }
5868 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005869 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005870
5871error:
5872 if (mask)
5873 CPU_FREE(mask);
5874 Py_XDECREF(iterator);
5875 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005876}
5877
5878PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5879"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5880Return the affinity of the process with PID *pid*.\n\
5881The returned cpu_set will be of size *ncpus*.");
5882
5883static PyObject *
5884posix_sched_getaffinity(PyObject *self, PyObject *args)
5885{
5886 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005887 int cpu, ncpus, count;
5888 size_t setsize;
5889 cpu_set_t *mask = NULL;
5890 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005891
Antoine Pitrou84869872012-08-04 16:16:35 +02005892 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5893 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005895
5896 ncpus = NCPUS_START;
5897 while (1) {
5898 setsize = CPU_ALLOC_SIZE(ncpus);
5899 mask = CPU_ALLOC(ncpus);
5900 if (mask == NULL)
5901 return PyErr_NoMemory();
5902 if (sched_getaffinity(pid, setsize, mask) == 0)
5903 break;
5904 CPU_FREE(mask);
5905 if (errno != EINVAL)
5906 return posix_error();
5907 if (ncpus > INT_MAX / 2) {
5908 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5909 "a large enough CPU set");
5910 return NULL;
5911 }
5912 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005913 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005914
5915 res = PySet_New(NULL);
5916 if (res == NULL)
5917 goto error;
5918 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5919 if (CPU_ISSET_S(cpu, setsize, mask)) {
5920 PyObject *cpu_num = PyLong_FromLong(cpu);
5921 --count;
5922 if (cpu_num == NULL)
5923 goto error;
5924 if (PySet_Add(res, cpu_num)) {
5925 Py_DECREF(cpu_num);
5926 goto error;
5927 }
5928 Py_DECREF(cpu_num);
5929 }
5930 }
5931 CPU_FREE(mask);
5932 return res;
5933
5934error:
5935 if (mask)
5936 CPU_FREE(mask);
5937 Py_XDECREF(res);
5938 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005939}
5940
Benjamin Peterson2740af82011-08-02 17:41:34 -05005941#endif /* HAVE_SCHED_SETAFFINITY */
5942
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005943#endif /* HAVE_SCHED_H */
5944
Neal Norwitzb59798b2003-03-21 01:43:31 +00005945/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005946/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5947#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005948#define DEV_PTY_FILE "/dev/ptc"
5949#define HAVE_DEV_PTMX
5950#else
5951#define DEV_PTY_FILE "/dev/ptmx"
5952#endif
5953
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005954#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005955#ifdef HAVE_PTY_H
5956#include <pty.h>
5957#else
5958#ifdef HAVE_LIBUTIL_H
5959#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005960#else
5961#ifdef HAVE_UTIL_H
5962#include <util.h>
5963#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005964#endif /* HAVE_LIBUTIL_H */
5965#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005966#ifdef HAVE_STROPTS_H
5967#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005968#endif
5969#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005970
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005971#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005973"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005975
5976static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005977posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005978{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005980#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005982#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005983#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005985#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005987#endif
5988#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005989
Thomas Wouters70c21a12000-07-14 14:28:33 +00005990#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005992 goto posix_error;
5993
5994 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5995 goto error;
5996 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5997 goto error;
5998
Neal Norwitzb59798b2003-03-21 01:43:31 +00005999#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6001 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006002 goto posix_error;
6003 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6004 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006005
Victor Stinnerdaf45552013-08-28 00:53:59 +02006006 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 goto posix_error;
6009
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006010#else
Victor Stinnerdaf45552013-08-28 00:53:59 +02006011 master_fd = _Py_open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006013 goto posix_error;
6014
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006016
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 /* change permission of slave */
6018 if (grantpt(master_fd) < 0) {
6019 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006020 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006022
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 /* unlock slave */
6024 if (unlockpt(master_fd) < 0) {
6025 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006026 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006028
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006030
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 slave_name = ptsname(master_fd); /* get name of slave */
6032 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006033 goto posix_error;
6034
6035 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006037 goto posix_error;
Neal Norwitzb59798b2003-03-21 01:43:31 +00006038#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6040 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006041#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006043#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006044#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006045#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006046
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006048
Victor Stinnerdaf45552013-08-28 00:53:59 +02006049posix_error:
6050 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006051#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006052error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006053#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006054 if (master_fd != -1)
6055 close(master_fd);
6056 if (slave_fd != -1)
6057 close(slave_fd);
6058 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006059}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006060#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006061
6062#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006064"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006065Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6066Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006068
6069static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006070posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006071{
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 int master_fd = -1, result = 0;
6073 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006074
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 _PyImport_AcquireLock();
6076 pid = forkpty(&master_fd, NULL, NULL, NULL);
6077 if (pid == 0) {
6078 /* child: this clobbers and resets the import lock. */
6079 PyOS_AfterFork();
6080 } else {
6081 /* parent: release the import lock. */
6082 result = _PyImport_ReleaseLock();
6083 }
6084 if (pid == -1)
6085 return posix_error();
6086 if (result < 0) {
6087 /* Don't clobber the OSError if the fork failed. */
6088 PyErr_SetString(PyExc_RuntimeError,
6089 "not holding the import lock");
6090 return NULL;
6091 }
6092 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006093}
6094#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Ross Lagerwall7807c352011-03-17 20:20:30 +02006096
Guido van Rossumad0ee831995-03-01 10:34:45 +00006097#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006099"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006101
Barry Warsaw53699e91996-12-10 23:23:01 +00006102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006103posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006104{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006105 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006106}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006107#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006109
Guido van Rossumad0ee831995-03-01 10:34:45 +00006110#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006111PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006112"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006114
Barry Warsaw53699e91996-12-10 23:23:01 +00006115static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006116posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006117{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006118 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006119}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006120#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006122
Guido van Rossumad0ee831995-03-01 10:34:45 +00006123#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006125"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Barry Warsaw53699e91996-12-10 23:23:01 +00006128static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006129posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006130{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006131 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006132}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006133#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006139
Barry Warsaw53699e91996-12-10 23:23:01 +00006140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006141posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006144}
6145
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006146#ifdef HAVE_GETGROUPLIST
6147PyDoc_STRVAR(posix_getgrouplist__doc__,
6148"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6149Returns a list of groups to which a user belongs.\n\n\
6150 user: username to lookup\n\
6151 group: base group id of the user");
6152
6153static PyObject *
6154posix_getgrouplist(PyObject *self, PyObject *args)
6155{
6156#ifdef NGROUPS_MAX
6157#define MAX_GROUPS NGROUPS_MAX
6158#else
6159 /* defined to be 16 on Solaris7, so this should be a small number */
6160#define MAX_GROUPS 64
6161#endif
6162
6163 const char *user;
6164 int i, ngroups;
6165 PyObject *list;
6166#ifdef __APPLE__
6167 int *groups, basegid;
6168#else
6169 gid_t *groups, basegid;
6170#endif
6171 ngroups = MAX_GROUPS;
6172
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006173#ifdef __APPLE__
6174 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006175 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006176#else
6177 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6178 _Py_Gid_Converter, &basegid))
6179 return NULL;
6180#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006181
6182#ifdef __APPLE__
6183 groups = PyMem_Malloc(ngroups * sizeof(int));
6184#else
6185 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6186#endif
6187 if (groups == NULL)
6188 return PyErr_NoMemory();
6189
6190 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6191 PyMem_Del(groups);
6192 return posix_error();
6193 }
6194
6195 list = PyList_New(ngroups);
6196 if (list == NULL) {
6197 PyMem_Del(groups);
6198 return NULL;
6199 }
6200
6201 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006202#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006203 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006204#else
6205 PyObject *o = _PyLong_FromGid(groups[i]);
6206#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006207 if (o == NULL) {
6208 Py_DECREF(list);
6209 PyMem_Del(groups);
6210 return NULL;
6211 }
6212 PyList_SET_ITEM(list, i, o);
6213 }
6214
6215 PyMem_Del(groups);
6216
6217 return list;
6218}
6219#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006220
Fred Drakec9680921999-12-13 16:37:25 +00006221#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006223"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006225
6226static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006227posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006228{
6229 PyObject *result = NULL;
6230
Fred Drakec9680921999-12-13 16:37:25 +00006231#ifdef NGROUPS_MAX
6232#define MAX_GROUPS NGROUPS_MAX
6233#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006235#define MAX_GROUPS 64
6236#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006238
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006239 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006240 * This is a helper variable to store the intermediate result when
6241 * that happens.
6242 *
6243 * To keep the code readable the OSX behaviour is unconditional,
6244 * according to the POSIX spec this should be safe on all unix-y
6245 * systems.
6246 */
6247 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006248 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006249
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006250#ifdef __APPLE__
6251 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6252 * there are more groups than can fit in grouplist. Therefore, on OS X
6253 * always first call getgroups with length 0 to get the actual number
6254 * of groups.
6255 */
6256 n = getgroups(0, NULL);
6257 if (n < 0) {
6258 return posix_error();
6259 } else if (n <= MAX_GROUPS) {
6260 /* groups will fit in existing array */
6261 alt_grouplist = grouplist;
6262 } else {
6263 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6264 if (alt_grouplist == NULL) {
6265 errno = EINVAL;
6266 return posix_error();
6267 }
6268 }
6269
6270 n = getgroups(n, alt_grouplist);
6271 if (n == -1) {
6272 if (alt_grouplist != grouplist) {
6273 PyMem_Free(alt_grouplist);
6274 }
6275 return posix_error();
6276 }
6277#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006279 if (n < 0) {
6280 if (errno == EINVAL) {
6281 n = getgroups(0, NULL);
6282 if (n == -1) {
6283 return posix_error();
6284 }
6285 if (n == 0) {
6286 /* Avoid malloc(0) */
6287 alt_grouplist = grouplist;
6288 } else {
6289 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6290 if (alt_grouplist == NULL) {
6291 errno = EINVAL;
6292 return posix_error();
6293 }
6294 n = getgroups(n, alt_grouplist);
6295 if (n == -1) {
6296 PyMem_Free(alt_grouplist);
6297 return posix_error();
6298 }
6299 }
6300 } else {
6301 return posix_error();
6302 }
6303 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006304#endif
6305
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006306 result = PyList_New(n);
6307 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 int i;
6309 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006310 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006312 Py_DECREF(result);
6313 result = NULL;
6314 break;
Fred Drakec9680921999-12-13 16:37:25 +00006315 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006317 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006318 }
6319
6320 if (alt_grouplist != grouplist) {
6321 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006323
Fred Drakec9680921999-12-13 16:37:25 +00006324 return result;
6325}
6326#endif
6327
Antoine Pitroub7572f02009-12-02 20:46:48 +00006328#ifdef HAVE_INITGROUPS
6329PyDoc_STRVAR(posix_initgroups__doc__,
6330"initgroups(username, gid) -> None\n\n\
6331Call the system initgroups() to initialize the group access list with all of\n\
6332the groups of which the specified username is a member, plus the specified\n\
6333group id.");
6334
6335static PyObject *
6336posix_initgroups(PyObject *self, PyObject *args)
6337{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006338 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006340 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006341#ifdef __APPLE__
6342 int gid;
6343#else
6344 gid_t gid;
6345#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006346
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006347#ifdef __APPLE__
6348 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6349 PyUnicode_FSConverter, &oname,
6350 &gid))
6351#else
6352 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6353 PyUnicode_FSConverter, &oname,
6354 _Py_Gid_Converter, &gid))
6355#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006357 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006358
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006359 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006360 Py_DECREF(oname);
6361 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006363
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 Py_INCREF(Py_None);
6365 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006366}
6367#endif
6368
Martin v. Löwis606edc12002-06-13 21:09:11 +00006369#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006370PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006371"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006372Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006373
6374static PyObject *
6375posix_getpgid(PyObject *self, PyObject *args)
6376{
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 pid_t pid, pgid;
6378 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6379 return NULL;
6380 pgid = getpgid(pid);
6381 if (pgid < 0)
6382 return posix_error();
6383 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006384}
6385#endif /* HAVE_GETPGID */
6386
6387
Guido van Rossumb6775db1994-08-01 11:34:53 +00006388#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006389PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006390"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006391Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006392
Barry Warsaw53699e91996-12-10 23:23:01 +00006393static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006394posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006395{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006396#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006398#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006400#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006401}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006402#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006404
Guido van Rossumb6775db1994-08-01 11:34:53 +00006405#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006407"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006408Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006409
Barry Warsaw53699e91996-12-10 23:23:01 +00006410static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006411posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006412{
Guido van Rossum64933891994-10-20 21:56:42 +00006413#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006415#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006417#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 return posix_error();
6419 Py_INCREF(Py_None);
6420 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006421}
6422
Guido van Rossumb6775db1994-08-01 11:34:53 +00006423#endif /* HAVE_SETPGRP */
6424
Guido van Rossumad0ee831995-03-01 10:34:45 +00006425#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006426
6427#ifdef MS_WINDOWS
6428#include <tlhelp32.h>
6429
6430static PyObject*
6431win32_getppid()
6432{
6433 HANDLE snapshot;
6434 pid_t mypid;
6435 PyObject* result = NULL;
6436 BOOL have_record;
6437 PROCESSENTRY32 pe;
6438
6439 mypid = getpid(); /* This function never fails */
6440
6441 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6442 if (snapshot == INVALID_HANDLE_VALUE)
6443 return PyErr_SetFromWindowsErr(GetLastError());
6444
6445 pe.dwSize = sizeof(pe);
6446 have_record = Process32First(snapshot, &pe);
6447 while (have_record) {
6448 if (mypid == (pid_t)pe.th32ProcessID) {
6449 /* We could cache the ulong value in a static variable. */
6450 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6451 break;
6452 }
6453
6454 have_record = Process32Next(snapshot, &pe);
6455 }
6456
6457 /* If our loop exits and our pid was not found (result will be NULL)
6458 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6459 * error anyway, so let's raise it. */
6460 if (!result)
6461 result = PyErr_SetFromWindowsErr(GetLastError());
6462
6463 CloseHandle(snapshot);
6464
6465 return result;
6466}
6467#endif /*MS_WINDOWS*/
6468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006471Return the parent's process id. If the parent process has already exited,\n\
6472Windows machines will still return its id; others systems will return the id\n\
6473of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006474
Barry Warsaw53699e91996-12-10 23:23:01 +00006475static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006476posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006477{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006478#ifdef MS_WINDOWS
6479 return win32_getppid();
6480#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006482#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006483}
6484#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006486
Fred Drake12c6e2d1999-12-14 21:25:03 +00006487#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006488PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006489"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006491
6492static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006493posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006494{
Victor Stinner8c62be82010-05-06 00:08:46 +00006495 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006496#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006497 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006498 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006499
6500 if (GetUserNameW(user_name, &num_chars)) {
6501 /* num_chars is the number of unicode chars plus null terminator */
6502 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006503 }
6504 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006505 result = PyErr_SetFromWindowsErr(GetLastError());
6506#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 char *name;
6508 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006509
Victor Stinner8c62be82010-05-06 00:08:46 +00006510 errno = 0;
6511 name = getlogin();
6512 if (name == NULL) {
6513 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006514 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006515 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006516 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 }
6518 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006519 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006521#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006522 return result;
6523}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006524#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006525
Guido van Rossumad0ee831995-03-01 10:34:45 +00006526#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006528"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006529Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006530
Barry Warsaw53699e91996-12-10 23:23:01 +00006531static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006532posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006533{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006534 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006535}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006536#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006538
Guido van Rossumad0ee831995-03-01 10:34:45 +00006539#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006541"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006543
Barry Warsaw53699e91996-12-10 23:23:01 +00006544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006545posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006546{
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 pid_t pid;
6548 int sig;
6549 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6550 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 if (kill(pid, sig) == -1)
6552 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 Py_INCREF(Py_None);
6554 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006555}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006556#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006557
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006558#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006560"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006561Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006562
6563static PyObject *
6564posix_killpg(PyObject *self, PyObject *args)
6565{
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 int sig;
6567 pid_t pgid;
6568 /* XXX some man pages make the `pgid` parameter an int, others
6569 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6570 take the same type. Moreover, pid_t is always at least as wide as
6571 int (else compilation of this module fails), which is safe. */
6572 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6573 return NULL;
6574 if (killpg(pgid, sig) == -1)
6575 return posix_error();
6576 Py_INCREF(Py_None);
6577 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006578}
6579#endif
6580
Brian Curtineb24d742010-04-12 17:16:38 +00006581#ifdef MS_WINDOWS
6582PyDoc_STRVAR(win32_kill__doc__,
6583"kill(pid, sig)\n\n\
6584Kill a process with a signal.");
6585
6586static PyObject *
6587win32_kill(PyObject *self, PyObject *args)
6588{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006589 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006590 pid_t pid;
6591 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006593
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006594 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006596
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 /* Console processes which share a common console can be sent CTRL+C or
6598 CTRL+BREAK events, provided they handle said events. */
6599 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006600 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 err = GetLastError();
6602 PyErr_SetFromWindowsErr(err);
6603 }
6604 else
6605 Py_RETURN_NONE;
6606 }
Brian Curtineb24d742010-04-12 17:16:38 +00006607
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6609 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006610 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 if (handle == NULL) {
6612 err = GetLastError();
6613 return PyErr_SetFromWindowsErr(err);
6614 }
Brian Curtineb24d742010-04-12 17:16:38 +00006615
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 if (TerminateProcess(handle, sig) == 0) {
6617 err = GetLastError();
6618 result = PyErr_SetFromWindowsErr(err);
6619 } else {
6620 Py_INCREF(Py_None);
6621 result = Py_None;
6622 }
Brian Curtineb24d742010-04-12 17:16:38 +00006623
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 CloseHandle(handle);
6625 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006626}
6627#endif /* MS_WINDOWS */
6628
Guido van Rossumc0125471996-06-28 18:55:32 +00006629#ifdef HAVE_PLOCK
6630
6631#ifdef HAVE_SYS_LOCK_H
6632#include <sys/lock.h>
6633#endif
6634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006635PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006636"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006637Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006638
Barry Warsaw53699e91996-12-10 23:23:01 +00006639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006640posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006641{
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 int op;
6643 if (!PyArg_ParseTuple(args, "i:plock", &op))
6644 return NULL;
6645 if (plock(op) == -1)
6646 return posix_error();
6647 Py_INCREF(Py_None);
6648 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006649}
6650#endif
6651
Guido van Rossumb6775db1994-08-01 11:34:53 +00006652#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006653PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006654"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006655Set the current process's user id.");
6656
Barry Warsaw53699e91996-12-10 23:23:01 +00006657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006658posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006659{
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006661 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 if (setuid(uid) < 0)
6664 return posix_error();
6665 Py_INCREF(Py_None);
6666 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006667}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006668#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006670
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006671#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006672PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006673"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674Set the current process's effective user id.");
6675
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006676static PyObject *
6677posix_seteuid (PyObject *self, PyObject *args)
6678{
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006680 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006681 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 if (seteuid(euid) < 0) {
6683 return posix_error();
6684 } else {
6685 Py_INCREF(Py_None);
6686 return Py_None;
6687 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETEUID */
6690
6691#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006693"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006694Set the current process's effective group id.");
6695
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006696static PyObject *
6697posix_setegid (PyObject *self, PyObject *args)
6698{
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006700 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006702 if (setegid(egid) < 0) {
6703 return posix_error();
6704 } else {
6705 Py_INCREF(Py_None);
6706 return Py_None;
6707 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006708}
6709#endif /* HAVE_SETEGID */
6710
6711#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006713"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006714Set the current process's real and effective user ids.");
6715
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006716static PyObject *
6717posix_setreuid (PyObject *self, PyObject *args)
6718{
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006720 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6721 _Py_Uid_Converter, &ruid,
6722 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 if (setreuid(ruid, euid) < 0) {
6725 return posix_error();
6726 } else {
6727 Py_INCREF(Py_None);
6728 return Py_None;
6729 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006730}
6731#endif /* HAVE_SETREUID */
6732
6733#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006734PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006735"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006736Set the current process's real and effective group ids.");
6737
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006738static PyObject *
6739posix_setregid (PyObject *self, PyObject *args)
6740{
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006742 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6743 _Py_Gid_Converter, &rgid,
6744 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 if (setregid(rgid, egid) < 0) {
6747 return posix_error();
6748 } else {
6749 Py_INCREF(Py_None);
6750 return Py_None;
6751 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006752}
6753#endif /* HAVE_SETREGID */
6754
Guido van Rossumb6775db1994-08-01 11:34:53 +00006755#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006756PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006757"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006759
Barry Warsaw53699e91996-12-10 23:23:01 +00006760static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006761posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006762{
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006764 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 if (setgid(gid) < 0)
6767 return posix_error();
6768 Py_INCREF(Py_None);
6769 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006770}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006771#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006772
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006773#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006774PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006775"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006776Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006777
6778static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006779posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006780{
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 int i, len;
6782 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (!PySequence_Check(groups)) {
6785 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6786 return NULL;
6787 }
6788 len = PySequence_Size(groups);
6789 if (len > MAX_GROUPS) {
6790 PyErr_SetString(PyExc_ValueError, "too many groups");
6791 return NULL;
6792 }
6793 for(i = 0; i < len; i++) {
6794 PyObject *elem;
6795 elem = PySequence_GetItem(groups, i);
6796 if (!elem)
6797 return NULL;
6798 if (!PyLong_Check(elem)) {
6799 PyErr_SetString(PyExc_TypeError,
6800 "groups must be integers");
6801 Py_DECREF(elem);
6802 return NULL;
6803 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006804 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 Py_DECREF(elem);
6806 return NULL;
6807 }
6808 }
6809 Py_DECREF(elem);
6810 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006811
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 if (setgroups(len, grouplist) < 0)
6813 return posix_error();
6814 Py_INCREF(Py_None);
6815 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006816}
6817#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006818
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6820static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006821wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822{
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 PyObject *result;
6824 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006825 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006826
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 if (pid == -1)
6828 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 if (struct_rusage == NULL) {
6831 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6832 if (m == NULL)
6833 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006834 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 Py_DECREF(m);
6836 if (struct_rusage == NULL)
6837 return NULL;
6838 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6841 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6842 if (!result)
6843 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006844
6845#ifndef doubletime
6846#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6847#endif
6848
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006850 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006852 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006853#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6855 SET_INT(result, 2, ru->ru_maxrss);
6856 SET_INT(result, 3, ru->ru_ixrss);
6857 SET_INT(result, 4, ru->ru_idrss);
6858 SET_INT(result, 5, ru->ru_isrss);
6859 SET_INT(result, 6, ru->ru_minflt);
6860 SET_INT(result, 7, ru->ru_majflt);
6861 SET_INT(result, 8, ru->ru_nswap);
6862 SET_INT(result, 9, ru->ru_inblock);
6863 SET_INT(result, 10, ru->ru_oublock);
6864 SET_INT(result, 11, ru->ru_msgsnd);
6865 SET_INT(result, 12, ru->ru_msgrcv);
6866 SET_INT(result, 13, ru->ru_nsignals);
6867 SET_INT(result, 14, ru->ru_nvcsw);
6868 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869#undef SET_INT
6870
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 if (PyErr_Occurred()) {
6872 Py_DECREF(result);
6873 return NULL;
6874 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877}
6878#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6879
6880#ifdef HAVE_WAIT3
6881PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006882"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883Wait for completion of a child process.");
6884
6885static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006886posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006887{
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 pid_t pid;
6889 int options;
6890 struct rusage ru;
6891 WAIT_TYPE status;
6892 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893
Victor Stinner4195b5c2012-02-08 23:03:19 +01006894 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 Py_BEGIN_ALLOW_THREADS
6898 pid = wait3(&status, options, &ru);
6899 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900
Victor Stinner4195b5c2012-02-08 23:03:19 +01006901 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902}
6903#endif /* HAVE_WAIT3 */
6904
6905#ifdef HAVE_WAIT4
6906PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006907"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908Wait for completion of a given child process.");
6909
6910static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006911posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912{
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 pid_t pid;
6914 int options;
6915 struct rusage ru;
6916 WAIT_TYPE status;
6917 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918
Victor Stinner4195b5c2012-02-08 23:03:19 +01006919 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 Py_BEGIN_ALLOW_THREADS
6923 pid = wait4(pid, &status, options, &ru);
6924 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925
Victor Stinner4195b5c2012-02-08 23:03:19 +01006926 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006927}
6928#endif /* HAVE_WAIT4 */
6929
Ross Lagerwall7807c352011-03-17 20:20:30 +02006930#if defined(HAVE_WAITID) && !defined(__APPLE__)
6931PyDoc_STRVAR(posix_waitid__doc__,
6932"waitid(idtype, id, options) -> waitid_result\n\n\
6933Wait for the completion of one or more child processes.\n\n\
6934idtype can be P_PID, P_PGID or P_ALL.\n\
6935id specifies the pid to wait on.\n\
6936options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6937or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6938Returns either waitid_result or None if WNOHANG is specified and there are\n\
6939no children in a waitable state.");
6940
6941static PyObject *
6942posix_waitid(PyObject *self, PyObject *args)
6943{
6944 PyObject *result;
6945 idtype_t idtype;
6946 id_t id;
6947 int options, res;
6948 siginfo_t si;
6949 si.si_pid = 0;
6950 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6951 return NULL;
6952 Py_BEGIN_ALLOW_THREADS
6953 res = waitid(idtype, id, &si, options);
6954 Py_END_ALLOW_THREADS
6955 if (res == -1)
6956 return posix_error();
6957
6958 if (si.si_pid == 0)
6959 Py_RETURN_NONE;
6960
6961 result = PyStructSequence_New(&WaitidResultType);
6962 if (!result)
6963 return NULL;
6964
6965 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006966 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006967 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6968 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6969 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6970 if (PyErr_Occurred()) {
6971 Py_DECREF(result);
6972 return NULL;
6973 }
6974
6975 return result;
6976}
6977#endif
6978
Guido van Rossumb6775db1994-08-01 11:34:53 +00006979#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006981"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006983
Barry Warsaw53699e91996-12-10 23:23:01 +00006984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006985posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006986{
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 pid_t pid;
6988 int options;
6989 WAIT_TYPE status;
6990 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006991
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6993 return NULL;
6994 Py_BEGIN_ALLOW_THREADS
6995 pid = waitpid(pid, &status, options);
6996 Py_END_ALLOW_THREADS
6997 if (pid == -1)
6998 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006999
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007001}
7002
Tim Petersab034fa2002-02-01 11:27:43 +00007003#elif defined(HAVE_CWAIT)
7004
7005/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007006PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007007"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007008"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007009
7010static PyObject *
7011posix_waitpid(PyObject *self, PyObject *args)
7012{
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 Py_intptr_t pid;
7014 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007015
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007016 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 return NULL;
7018 Py_BEGIN_ALLOW_THREADS
7019 pid = _cwait(&status, pid, options);
7020 Py_END_ALLOW_THREADS
7021 if (pid == -1)
7022 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007023
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007025 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007026}
7027#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007028
Guido van Rossumad0ee831995-03-01 10:34:45 +00007029#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007030PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007031"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007032Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007033
Barry Warsaw53699e91996-12-10 23:23:01 +00007034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007035posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007036{
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 pid_t pid;
7038 WAIT_TYPE status;
7039 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007040
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 Py_BEGIN_ALLOW_THREADS
7042 pid = wait(&status);
7043 Py_END_ALLOW_THREADS
7044 if (pid == -1)
7045 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007046
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007048}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007049#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007051
Larry Hastings9cf065c2012-06-22 16:30:09 -07007052#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7053PyDoc_STRVAR(readlink__doc__,
7054"readlink(path, *, dir_fd=None) -> path\n\n\
7055Return a string representing the path to which the symbolic link points.\n\
7056\n\
7057If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7058 and path should be relative; path will then be relative to that directory.\n\
7059dir_fd may not be implemented on your platform.\n\
7060 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007061#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007062
Guido van Rossumb6775db1994-08-01 11:34:53 +00007063#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007064
Barry Warsaw53699e91996-12-10 23:23:01 +00007065static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007066posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007067{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007068 path_t path;
7069 int dir_fd = DEFAULT_DIR_FD;
7070 char buffer[MAXPATHLEN];
7071 ssize_t length;
7072 PyObject *return_value = NULL;
7073 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007074
Larry Hastings9cf065c2012-06-22 16:30:09 -07007075 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007076 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007077 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7078 path_converter, &path,
7079#ifdef HAVE_READLINKAT
7080 dir_fd_converter, &dir_fd
7081#else
7082 dir_fd_unavailable, &dir_fd
7083#endif
7084 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007086
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007088#ifdef HAVE_READLINKAT
7089 if (dir_fd != DEFAULT_DIR_FD)
7090 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007091 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007092#endif
7093 length = readlink(path.narrow, buffer, sizeof(buffer));
7094 Py_END_ALLOW_THREADS
7095
7096 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007097 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007098 goto exit;
7099 }
7100
7101 if (PyUnicode_Check(path.object))
7102 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7103 else
7104 return_value = PyBytes_FromStringAndSize(buffer, length);
7105exit:
7106 path_cleanup(&path);
7107 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007108}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007109
7110
Guido van Rossumb6775db1994-08-01 11:34:53 +00007111#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007113
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007115PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7117Create a symbolic link pointing to src named dst.\n\n\
7118target_is_directory is required on Windows if the target is to be\n\
7119 interpreted as a directory. (On Windows, symlink requires\n\
7120 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7121 target_is_directory is ignored on non-Windows platforms.\n\
7122\n\
7123If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7124 and path should be relative; path will then be relative to that directory.\n\
7125dir_fd may not be implemented on your platform.\n\
7126 If it is unavailable, using it will raise a NotImplementedError.");
7127
7128#if defined(MS_WINDOWS)
7129
7130/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7131static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7132static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007133
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007135check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136{
7137 HINSTANCE hKernel32;
7138 /* only recheck */
7139 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7140 return 1;
7141 hKernel32 = GetModuleHandleW(L"KERNEL32");
7142 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7143 "CreateSymbolicLinkW");
7144 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7145 "CreateSymbolicLinkA");
7146 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7147}
7148
Victor Stinner31b3b922013-06-05 01:49:17 +02007149/* Remove the last portion of the path */
7150static void
7151_dirnameW(WCHAR *path)
7152{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007153 WCHAR *ptr;
7154
7155 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007156 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007157 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007158 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007159 }
7160 *ptr = 0;
7161}
7162
Victor Stinner31b3b922013-06-05 01:49:17 +02007163/* Remove the last portion of the path */
7164static void
7165_dirnameA(char *path)
7166{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007167 char *ptr;
7168
7169 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007170 for(ptr = path + strlen(path); ptr != path; ptr--) {
7171 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007172 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007173 }
7174 *ptr = 0;
7175}
7176
Victor Stinner31b3b922013-06-05 01:49:17 +02007177/* Is this path absolute? */
7178static int
7179_is_absW(const WCHAR *path)
7180{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007181 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7182
7183}
7184
Victor Stinner31b3b922013-06-05 01:49:17 +02007185/* Is this path absolute? */
7186static int
7187_is_absA(const char *path)
7188{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007189 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7190
7191}
7192
Victor Stinner31b3b922013-06-05 01:49:17 +02007193/* join root and rest with a backslash */
7194static void
7195_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7196{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007197 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007198
Victor Stinner31b3b922013-06-05 01:49:17 +02007199 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007200 wcscpy(dest_path, rest);
7201 return;
7202 }
7203
7204 root_len = wcslen(root);
7205
7206 wcscpy(dest_path, root);
7207 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007208 dest_path[root_len] = L'\\';
7209 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007210 }
7211 wcscpy(dest_path+root_len, rest);
7212}
7213
Victor Stinner31b3b922013-06-05 01:49:17 +02007214/* join root and rest with a backslash */
7215static void
7216_joinA(char *dest_path, const char *root, const char *rest)
7217{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007218 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007219
Victor Stinner31b3b922013-06-05 01:49:17 +02007220 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007221 strcpy(dest_path, rest);
7222 return;
7223 }
7224
7225 root_len = strlen(root);
7226
7227 strcpy(dest_path, root);
7228 if(root_len) {
7229 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007230 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231 }
7232 strcpy(dest_path+root_len, rest);
7233}
7234
Victor Stinner31b3b922013-06-05 01:49:17 +02007235/* Return True if the path at src relative to dest is a directory */
7236static int
7237_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007238{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007239 WIN32_FILE_ATTRIBUTE_DATA src_info;
7240 WCHAR dest_parent[MAX_PATH];
7241 WCHAR src_resolved[MAX_PATH] = L"";
7242
7243 /* dest_parent = os.path.dirname(dest) */
7244 wcscpy(dest_parent, dest);
7245 _dirnameW(dest_parent);
7246 /* src_resolved = os.path.join(dest_parent, src) */
7247 _joinW(src_resolved, dest_parent, src);
7248 return (
7249 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7250 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7251 );
7252}
7253
Victor Stinner31b3b922013-06-05 01:49:17 +02007254/* Return True if the path at src relative to dest is a directory */
7255static int
7256_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007257{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007258 WIN32_FILE_ATTRIBUTE_DATA src_info;
7259 char dest_parent[MAX_PATH];
7260 char src_resolved[MAX_PATH] = "";
7261
7262 /* dest_parent = os.path.dirname(dest) */
7263 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007264 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007265 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007266 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007267 return (
7268 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7269 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7270 );
7271}
7272
Larry Hastings9cf065c2012-06-22 16:30:09 -07007273#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007274
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007275static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007276posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007277{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278 path_t src;
7279 path_t dst;
7280 int dir_fd = DEFAULT_DIR_FD;
7281 int target_is_directory = 0;
7282 static char *keywords[] = {"src", "dst", "target_is_directory",
7283 "dir_fd", NULL};
7284 PyObject *return_value;
7285#ifdef MS_WINDOWS
7286 DWORD result;
7287#else
7288 int result;
7289#endif
7290
7291 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007292 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007293 src.argument_name = "src";
7294 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007295 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007296 dst.argument_name = "dst";
7297
7298#ifdef MS_WINDOWS
7299 if (!check_CreateSymbolicLink()) {
7300 PyErr_SetString(PyExc_NotImplementedError,
7301 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007302 return NULL;
7303 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007304 if (!win32_can_symlink) {
7305 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007306 return NULL;
7307 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007308#endif
7309
7310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7311 keywords,
7312 path_converter, &src,
7313 path_converter, &dst,
7314 &target_is_directory,
7315#ifdef HAVE_SYMLINKAT
7316 dir_fd_converter, &dir_fd
7317#else
7318 dir_fd_unavailable, &dir_fd
7319#endif
7320 ))
7321 return NULL;
7322
7323 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7324 PyErr_SetString(PyExc_ValueError,
7325 "symlink: src and dst must be the same type");
7326 return_value = NULL;
7327 goto exit;
7328 }
7329
7330#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007331
Larry Hastings9cf065c2012-06-22 16:30:09 -07007332 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 if (dst.wide) {
7334 /* if src is a directory, ensure target_is_directory==1 */
7335 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007336 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7337 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007338 }
7339 else {
7340 /* if src is a directory, ensure target_is_directory==1 */
7341 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7343 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007344 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007345 Py_END_ALLOW_THREADS
7346
7347 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007348 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349 goto exit;
7350 }
7351
7352#else
7353
7354 Py_BEGIN_ALLOW_THREADS
7355#if HAVE_SYMLINKAT
7356 if (dir_fd != DEFAULT_DIR_FD)
7357 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7358 else
7359#endif
7360 result = symlink(src.narrow, dst.narrow);
7361 Py_END_ALLOW_THREADS
7362
7363 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007364 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007365 goto exit;
7366 }
7367#endif
7368
7369 return_value = Py_None;
7370 Py_INCREF(Py_None);
7371 goto exit; /* silence "unused label" warning */
7372exit:
7373 path_cleanup(&src);
7374 path_cleanup(&dst);
7375 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007376}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007378#endif /* HAVE_SYMLINK */
7379
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380
Brian Curtind40e6f72010-07-08 21:39:08 +00007381#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7382
Brian Curtind40e6f72010-07-08 21:39:08 +00007383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007384win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007385{
7386 wchar_t *path;
7387 DWORD n_bytes_returned;
7388 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007389 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007390 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007391 HANDLE reparse_point_handle;
7392
7393 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7394 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7395 wchar_t *print_name;
7396
Larry Hastings9cf065c2012-06-22 16:30:09 -07007397 static char *keywords[] = {"path", "dir_fd", NULL};
7398
7399 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7400 &po,
7401 dir_fd_unavailable, &dir_fd
7402 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007403 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007404
Victor Stinnereb5657a2011-09-30 01:44:27 +02007405 path = PyUnicode_AsUnicode(po);
7406 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007407 return NULL;
7408
7409 /* First get a handle to the reparse point */
7410 Py_BEGIN_ALLOW_THREADS
7411 reparse_point_handle = CreateFileW(
7412 path,
7413 0,
7414 0,
7415 0,
7416 OPEN_EXISTING,
7417 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7418 0);
7419 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007420
Brian Curtind40e6f72010-07-08 21:39:08 +00007421 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007422 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007423
Brian Curtind40e6f72010-07-08 21:39:08 +00007424 Py_BEGIN_ALLOW_THREADS
7425 /* New call DeviceIoControl to read the reparse point */
7426 io_result = DeviceIoControl(
7427 reparse_point_handle,
7428 FSCTL_GET_REPARSE_POINT,
7429 0, 0, /* in buffer */
7430 target_buffer, sizeof(target_buffer),
7431 &n_bytes_returned,
7432 0 /* we're not using OVERLAPPED_IO */
7433 );
7434 CloseHandle(reparse_point_handle);
7435 Py_END_ALLOW_THREADS
7436
7437 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007438 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007439
7440 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7441 {
7442 PyErr_SetString(PyExc_ValueError,
7443 "not a symbolic link");
7444 return NULL;
7445 }
Brian Curtin74e45612010-07-09 15:58:59 +00007446 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7447 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7448
7449 result = PyUnicode_FromWideChar(print_name,
7450 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007451 return result;
7452}
7453
7454#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7455
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007456
Larry Hastings605a62d2012-06-24 04:33:36 -07007457static PyStructSequence_Field times_result_fields[] = {
7458 {"user", "user time"},
7459 {"system", "system time"},
7460 {"children_user", "user time of children"},
7461 {"children_system", "system time of children"},
7462 {"elapsed", "elapsed time since an arbitrary point in the past"},
7463 {NULL}
7464};
7465
7466PyDoc_STRVAR(times_result__doc__,
7467"times_result: Result from os.times().\n\n\
7468This object may be accessed either as a tuple of\n\
7469 (user, system, children_user, children_system, elapsed),\n\
7470or via the attributes user, system, children_user, children_system,\n\
7471and elapsed.\n\
7472\n\
7473See os.times for more information.");
7474
7475static PyStructSequence_Desc times_result_desc = {
7476 "times_result", /* name */
7477 times_result__doc__, /* doc */
7478 times_result_fields,
7479 5
7480};
7481
7482static PyTypeObject TimesResultType;
7483
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007484#ifdef MS_WINDOWS
7485#define HAVE_TIMES /* mandatory, for the method table */
7486#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007487
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007488#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007489
7490static PyObject *
7491build_times_result(double user, double system,
7492 double children_user, double children_system,
7493 double elapsed)
7494{
7495 PyObject *value = PyStructSequence_New(&TimesResultType);
7496 if (value == NULL)
7497 return NULL;
7498
7499#define SET(i, field) \
7500 { \
7501 PyObject *o = PyFloat_FromDouble(field); \
7502 if (!o) { \
7503 Py_DECREF(value); \
7504 return NULL; \
7505 } \
7506 PyStructSequence_SET_ITEM(value, i, o); \
7507 } \
7508
7509 SET(0, user);
7510 SET(1, system);
7511 SET(2, children_user);
7512 SET(3, children_system);
7513 SET(4, elapsed);
7514
7515#undef SET
7516
7517 return value;
7518}
7519
7520PyDoc_STRVAR(posix_times__doc__,
7521"times() -> times_result\n\n\
7522Return an object containing floating point numbers indicating process\n\
7523times. The object behaves like a named tuple with these fields:\n\
7524 (utime, stime, cutime, cstime, elapsed_time)");
7525
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007526#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007527static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007528posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007529{
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 FILETIME create, exit, kernel, user;
7531 HANDLE hProc;
7532 hProc = GetCurrentProcess();
7533 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7534 /* The fields of a FILETIME structure are the hi and lo part
7535 of a 64-bit value expressed in 100 nanosecond units.
7536 1e7 is one second in such units; 1e-7 the inverse.
7537 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7538 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007539 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 (double)(user.dwHighDateTime*429.4967296 +
7541 user.dwLowDateTime*1e-7),
7542 (double)(kernel.dwHighDateTime*429.4967296 +
7543 kernel.dwLowDateTime*1e-7),
7544 (double)0,
7545 (double)0,
7546 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007547}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007548#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007549#define NEED_TICKS_PER_SECOND
7550static long ticks_per_second = -1;
7551static PyObject *
7552posix_times(PyObject *self, PyObject *noargs)
7553{
7554 struct tms t;
7555 clock_t c;
7556 errno = 0;
7557 c = times(&t);
7558 if (c == (clock_t) -1)
7559 return posix_error();
7560 return build_times_result(
7561 (double)t.tms_utime / ticks_per_second,
7562 (double)t.tms_stime / ticks_per_second,
7563 (double)t.tms_cutime / ticks_per_second,
7564 (double)t.tms_cstime / ticks_per_second,
7565 (double)c / ticks_per_second);
7566}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007567#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007568
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007569#endif /* HAVE_TIMES */
7570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007571
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007572#ifdef HAVE_GETSID
7573PyDoc_STRVAR(posix_getsid__doc__,
7574"getsid(pid) -> sid\n\n\
7575Call the system call getsid().");
7576
7577static PyObject *
7578posix_getsid(PyObject *self, PyObject *args)
7579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 pid_t pid;
7581 int sid;
7582 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7583 return NULL;
7584 sid = getsid(pid);
7585 if (sid < 0)
7586 return posix_error();
7587 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007588}
7589#endif /* HAVE_GETSID */
7590
7591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007594"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007595Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007596
Barry Warsaw53699e91996-12-10 23:23:01 +00007597static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007598posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 if (setsid() < 0)
7601 return posix_error();
7602 Py_INCREF(Py_None);
7603 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007604}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007605#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007606
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007608PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007609"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007610Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007611
Barry Warsaw53699e91996-12-10 23:23:01 +00007612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007613posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007614{
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 pid_t pid;
7616 int pgrp;
7617 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7618 return NULL;
7619 if (setpgid(pid, pgrp) < 0)
7620 return posix_error();
7621 Py_INCREF(Py_None);
7622 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007623}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007624#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007626
Guido van Rossumb6775db1994-08-01 11:34:53 +00007627#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007628PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007629"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007630Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Barry Warsaw53699e91996-12-10 23:23:01 +00007632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007633posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007634{
Victor Stinner8c62be82010-05-06 00:08:46 +00007635 int fd;
7636 pid_t pgid;
7637 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7638 return NULL;
7639 pgid = tcgetpgrp(fd);
7640 if (pgid < 0)
7641 return posix_error();
7642 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007643}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007646
Guido van Rossumb6775db1994-08-01 11:34:53 +00007647#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007648PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007649"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007650Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007651
Barry Warsaw53699e91996-12-10 23:23:01 +00007652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007653posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007654{
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 int fd;
7656 pid_t pgid;
7657 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7658 return NULL;
7659 if (tcsetpgrp(fd, pgid) < 0)
7660 return posix_error();
7661 Py_INCREF(Py_None);
7662 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007663}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007664#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007665
Guido van Rossum687dd131993-05-17 08:34:16 +00007666/* Functions acting on file descriptors */
7667
Victor Stinnerdaf45552013-08-28 00:53:59 +02007668#ifdef O_CLOEXEC
7669extern int _Py_open_cloexec_works;
7670#endif
7671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007672PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007673"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7674Open a file for low level IO. Returns a file handle (integer).\n\
7675\n\
7676If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7677 and path should be relative; path will then be relative to that directory.\n\
7678dir_fd may not be implemented on your platform.\n\
7679 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007680
Barry Warsaw53699e91996-12-10 23:23:01 +00007681static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007682posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007683{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007684 path_t path;
7685 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007687 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007689 PyObject *return_value = NULL;
7690 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007691#ifdef O_CLOEXEC
7692 int *atomic_flag_works = &_Py_open_cloexec_works;
7693#elif !defined(MS_WINDOWS)
7694 int *atomic_flag_works = NULL;
7695#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007696
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007698 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007699 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7700 path_converter, &path,
7701 &flags, &mode,
7702#ifdef HAVE_OPENAT
7703 dir_fd_converter, &dir_fd
7704#else
7705 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007706#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707 ))
7708 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007709
Victor Stinnerdaf45552013-08-28 00:53:59 +02007710#ifdef MS_WINDOWS
7711 flags |= O_NOINHERIT;
7712#elif defined(O_CLOEXEC)
7713 flags |= O_CLOEXEC;
7714#endif
7715
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007717#ifdef MS_WINDOWS
7718 if (path.wide)
7719 fd = _wopen(path.wide, flags, mode);
7720 else
7721#endif
7722#ifdef HAVE_OPENAT
7723 if (dir_fd != DEFAULT_DIR_FD)
7724 fd = openat(dir_fd, path.narrow, flags, mode);
7725 else
7726#endif
7727 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007729
Larry Hastings9cf065c2012-06-22 16:30:09 -07007730 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007731 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007732 goto exit;
7733 }
7734
Victor Stinnerdaf45552013-08-28 00:53:59 +02007735#ifndef MS_WINDOWS
7736 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7737 close(fd);
7738 goto exit;
7739 }
7740#endif
7741
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742 return_value = PyLong_FromLong((long)fd);
7743
7744exit:
7745 path_cleanup(&path);
7746 return return_value;
7747}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007749PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007750"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007751Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007752
Barry Warsaw53699e91996-12-10 23:23:01 +00007753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007754posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007755{
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 int fd, res;
7757 if (!PyArg_ParseTuple(args, "i:close", &fd))
7758 return NULL;
7759 if (!_PyVerify_fd(fd))
7760 return posix_error();
7761 Py_BEGIN_ALLOW_THREADS
7762 res = close(fd);
7763 Py_END_ALLOW_THREADS
7764 if (res < 0)
7765 return posix_error();
7766 Py_INCREF(Py_None);
7767 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007768}
7769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007770
Victor Stinner8c62be82010-05-06 00:08:46 +00007771PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007772"closerange(fd_low, fd_high)\n\n\
7773Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7774
7775static PyObject *
7776posix_closerange(PyObject *self, PyObject *args)
7777{
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 int fd_from, fd_to, i;
7779 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7780 return NULL;
7781 Py_BEGIN_ALLOW_THREADS
7782 for (i = fd_from; i < fd_to; i++)
7783 if (_PyVerify_fd(i))
7784 close(i);
7785 Py_END_ALLOW_THREADS
7786 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007787}
7788
7789
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007790PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007791"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007792Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007793
Barry Warsaw53699e91996-12-10 23:23:01 +00007794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007795posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007796{
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007798
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7800 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007801
Victor Stinnerdaf45552013-08-28 00:53:59 +02007802 fd = _Py_dup(fd);
7803 if (fd == -1)
7804 return NULL;
7805
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007807}
7808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007810PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007811"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007812Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007813
Barry Warsaw53699e91996-12-10 23:23:01 +00007814static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007815posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007816{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007817 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7818 int fd, fd2;
7819 int inheritable = 1;
7820 int res;
7821#if defined(HAVE_DUP3) && \
7822 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7823 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7824 int dup3_works = -1;
7825#endif
7826
7827 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7828 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007830
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 if (!_PyVerify_fd_dup2(fd, fd2))
7832 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007833
7834#ifdef MS_WINDOWS
7835 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007837 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 if (res < 0)
7839 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840
7841 /* Character files like console cannot be make non-inheritable */
7842 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7843 close(fd2);
7844 return NULL;
7845 }
7846
7847#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7848 Py_BEGIN_ALLOW_THREADS
7849 if (!inheritable)
7850 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7851 else
7852 res = dup2(fd, fd2);
7853 Py_END_ALLOW_THREADS
7854 if (res < 0)
7855 return posix_error();
7856
7857#else
7858
7859#ifdef HAVE_DUP3
7860 if (!inheritable && dup3_works != 0) {
7861 Py_BEGIN_ALLOW_THREADS
7862 res = dup3(fd, fd2, O_CLOEXEC);
7863 Py_END_ALLOW_THREADS
7864 if (res < 0) {
7865 if (dup3_works == -1)
7866 dup3_works = (errno != ENOSYS);
7867 if (dup3_works)
7868 return posix_error();
7869 }
7870 }
7871
7872 if (inheritable || dup3_works == 0)
7873 {
7874#endif
7875 Py_BEGIN_ALLOW_THREADS
7876 res = dup2(fd, fd2);
7877 Py_END_ALLOW_THREADS
7878 if (res < 0)
7879 return posix_error();
7880
7881 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7882 close(fd2);
7883 return NULL;
7884 }
7885#ifdef HAVE_DUP3
7886 }
7887#endif
7888
7889#endif
7890
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 Py_INCREF(Py_None);
7892 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007893}
7894
Ross Lagerwall7807c352011-03-17 20:20:30 +02007895#ifdef HAVE_LOCKF
7896PyDoc_STRVAR(posix_lockf__doc__,
7897"lockf(fd, cmd, len)\n\n\
7898Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7899fd is an open file descriptor.\n\
7900cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7901F_TEST.\n\
7902len specifies the section of the file to lock.");
7903
7904static PyObject *
7905posix_lockf(PyObject *self, PyObject *args)
7906{
7907 int fd, cmd, res;
7908 off_t len;
7909 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7910 &fd, &cmd, _parse_off_t, &len))
7911 return NULL;
7912
7913 Py_BEGIN_ALLOW_THREADS
7914 res = lockf(fd, cmd, len);
7915 Py_END_ALLOW_THREADS
7916
7917 if (res < 0)
7918 return posix_error();
7919
7920 Py_RETURN_NONE;
7921}
7922#endif
7923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007925PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007926"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007927Set the current position of a file descriptor.\n\
7928Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007929
Barry Warsaw53699e91996-12-10 23:23:01 +00007930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007931posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007932{
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007934#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007936#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007938#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007939 PyObject *posobj;
7940 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007941 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007942#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7944 switch (how) {
7945 case 0: how = SEEK_SET; break;
7946 case 1: how = SEEK_CUR; break;
7947 case 2: how = SEEK_END; break;
7948 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007949#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007950
Ross Lagerwall8e749672011-03-17 21:54:07 +02007951#if !defined(HAVE_LARGEFILE_SUPPORT)
7952 pos = PyLong_AsLong(posobj);
7953#else
7954 pos = PyLong_AsLongLong(posobj);
7955#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 if (PyErr_Occurred())
7957 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007958
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 if (!_PyVerify_fd(fd))
7960 return posix_error();
7961 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007964#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007966#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 Py_END_ALLOW_THREADS
7968 if (res < 0)
7969 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007970
7971#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007975#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007976}
7977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007979PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007980"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007981Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007982
Barry Warsaw53699e91996-12-10 23:23:01 +00007983static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007984posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007985{
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 int fd, size;
7987 Py_ssize_t n;
7988 PyObject *buffer;
7989 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7990 return NULL;
7991 if (size < 0) {
7992 errno = EINVAL;
7993 return posix_error();
7994 }
7995 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7996 if (buffer == NULL)
7997 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007998 if (!_PyVerify_fd(fd)) {
7999 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 Py_BEGIN_ALLOW_THREADS
8003 n = read(fd, PyBytes_AS_STRING(buffer), size);
8004 Py_END_ALLOW_THREADS
8005 if (n < 0) {
8006 Py_DECREF(buffer);
8007 return posix_error();
8008 }
8009 if (n != size)
8010 _PyBytes_Resize(&buffer, n);
8011 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008012}
8013
Ross Lagerwall7807c352011-03-17 20:20:30 +02008014#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8015 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008016static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008017iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8018{
8019 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008020 Py_ssize_t blen, total = 0;
8021
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008022 *iov = PyMem_New(struct iovec, cnt);
8023 if (*iov == NULL) {
8024 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008025 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008026 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008027
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008028 *buf = PyMem_New(Py_buffer, cnt);
8029 if (*buf == NULL) {
8030 PyMem_Del(*iov);
8031 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008032 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008033 }
8034
8035 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008036 PyObject *item = PySequence_GetItem(seq, i);
8037 if (item == NULL)
8038 goto fail;
8039 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8040 Py_DECREF(item);
8041 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008043 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008044 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008045 blen = (*buf)[i].len;
8046 (*iov)[i].iov_len = blen;
8047 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008049 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008050
8051fail:
8052 PyMem_Del(*iov);
8053 for (j = 0; j < i; j++) {
8054 PyBuffer_Release(&(*buf)[j]);
8055 }
8056 PyMem_Del(*buf);
8057 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058}
8059
8060static void
8061iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8062{
8063 int i;
8064 PyMem_Del(iov);
8065 for (i = 0; i < cnt; i++) {
8066 PyBuffer_Release(&buf[i]);
8067 }
8068 PyMem_Del(buf);
8069}
8070#endif
8071
Ross Lagerwall7807c352011-03-17 20:20:30 +02008072#ifdef HAVE_READV
8073PyDoc_STRVAR(posix_readv__doc__,
8074"readv(fd, buffers) -> bytesread\n\n\
8075Read from a file descriptor into a number of writable buffers. buffers\n\
8076is an arbitrary sequence of writable buffers.\n\
8077Returns the total number of bytes read.");
8078
8079static PyObject *
8080posix_readv(PyObject *self, PyObject *args)
8081{
8082 int fd, cnt;
8083 Py_ssize_t n;
8084 PyObject *seq;
8085 struct iovec *iov;
8086 Py_buffer *buf;
8087
8088 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8089 return NULL;
8090 if (!PySequence_Check(seq)) {
8091 PyErr_SetString(PyExc_TypeError,
8092 "readv() arg 2 must be a sequence");
8093 return NULL;
8094 }
8095 cnt = PySequence_Size(seq);
8096
8097 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8098 return NULL;
8099
8100 Py_BEGIN_ALLOW_THREADS
8101 n = readv(fd, iov, cnt);
8102 Py_END_ALLOW_THREADS
8103
8104 iov_cleanup(iov, buf, cnt);
8105 return PyLong_FromSsize_t(n);
8106}
8107#endif
8108
8109#ifdef HAVE_PREAD
8110PyDoc_STRVAR(posix_pread__doc__,
8111"pread(fd, buffersize, offset) -> string\n\n\
8112Read from a file descriptor, fd, at a position of offset. It will read up\n\
8113to buffersize number of bytes. The file offset remains unchanged.");
8114
8115static PyObject *
8116posix_pread(PyObject *self, PyObject *args)
8117{
8118 int fd, size;
8119 off_t offset;
8120 Py_ssize_t n;
8121 PyObject *buffer;
8122 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8123 return NULL;
8124
8125 if (size < 0) {
8126 errno = EINVAL;
8127 return posix_error();
8128 }
8129 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8130 if (buffer == NULL)
8131 return NULL;
8132 if (!_PyVerify_fd(fd)) {
8133 Py_DECREF(buffer);
8134 return posix_error();
8135 }
8136 Py_BEGIN_ALLOW_THREADS
8137 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8138 Py_END_ALLOW_THREADS
8139 if (n < 0) {
8140 Py_DECREF(buffer);
8141 return posix_error();
8142 }
8143 if (n != size)
8144 _PyBytes_Resize(&buffer, n);
8145 return buffer;
8146}
8147#endif
8148
8149PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008150"write(fd, data) -> byteswritten\n\n\
8151Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008152
8153static PyObject *
8154posix_write(PyObject *self, PyObject *args)
8155{
8156 Py_buffer pbuf;
8157 int fd;
8158 Py_ssize_t size, len;
8159
8160 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8161 return NULL;
8162 if (!_PyVerify_fd(fd)) {
8163 PyBuffer_Release(&pbuf);
8164 return posix_error();
8165 }
8166 len = pbuf.len;
8167 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008168#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169 if (len > INT_MAX)
8170 len = INT_MAX;
8171 size = write(fd, pbuf.buf, (int)len);
8172#else
8173 size = write(fd, pbuf.buf, len);
8174#endif
8175 Py_END_ALLOW_THREADS
8176 PyBuffer_Release(&pbuf);
8177 if (size < 0)
8178 return posix_error();
8179 return PyLong_FromSsize_t(size);
8180}
8181
8182#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008183PyDoc_STRVAR(posix_sendfile__doc__,
8184"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8185sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8186 -> byteswritten\n\
8187Copy nbytes bytes from file descriptor in to file descriptor out.");
8188
8189static PyObject *
8190posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8191{
8192 int in, out;
8193 Py_ssize_t ret;
8194 off_t offset;
8195
8196#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8197#ifndef __APPLE__
8198 Py_ssize_t len;
8199#endif
8200 PyObject *headers = NULL, *trailers = NULL;
8201 Py_buffer *hbuf, *tbuf;
8202 off_t sbytes;
8203 struct sf_hdtr sf;
8204 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008205 static char *keywords[] = {"out", "in",
8206 "offset", "count",
8207 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008208
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008209 sf.headers = NULL;
8210 sf.trailers = NULL;
8211
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008212#ifdef __APPLE__
8213 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008214 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008215#else
8216 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008217 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218#endif
8219 &headers, &trailers, &flags))
8220 return NULL;
8221 if (headers != NULL) {
8222 if (!PySequence_Check(headers)) {
8223 PyErr_SetString(PyExc_TypeError,
8224 "sendfile() headers must be a sequence or None");
8225 return NULL;
8226 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008227 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008228 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008229 if (sf.hdr_cnt > 0 &&
8230 !(i = iov_setup(&(sf.headers), &hbuf,
8231 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008232 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008233#ifdef __APPLE__
8234 sbytes += i;
8235#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008236 }
8237 }
8238 if (trailers != NULL) {
8239 if (!PySequence_Check(trailers)) {
8240 PyErr_SetString(PyExc_TypeError,
8241 "sendfile() trailers must be a sequence or None");
8242 return NULL;
8243 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008244 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008246 if (sf.trl_cnt > 0 &&
8247 !(i = iov_setup(&(sf.trailers), &tbuf,
8248 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008249 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008250#ifdef __APPLE__
8251 sbytes += i;
8252#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008253 }
8254 }
8255
8256 Py_BEGIN_ALLOW_THREADS
8257#ifdef __APPLE__
8258 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8259#else
8260 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8261#endif
8262 Py_END_ALLOW_THREADS
8263
8264 if (sf.headers != NULL)
8265 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8266 if (sf.trailers != NULL)
8267 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8268
8269 if (ret < 0) {
8270 if ((errno == EAGAIN) || (errno == EBUSY)) {
8271 if (sbytes != 0) {
8272 // some data has been sent
8273 goto done;
8274 }
8275 else {
8276 // no data has been sent; upper application is supposed
8277 // to retry on EAGAIN or EBUSY
8278 return posix_error();
8279 }
8280 }
8281 return posix_error();
8282 }
8283 goto done;
8284
8285done:
8286 #if !defined(HAVE_LARGEFILE_SUPPORT)
8287 return Py_BuildValue("l", sbytes);
8288 #else
8289 return Py_BuildValue("L", sbytes);
8290 #endif
8291
8292#else
8293 Py_ssize_t count;
8294 PyObject *offobj;
8295 static char *keywords[] = {"out", "in",
8296 "offset", "count", NULL};
8297 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8298 keywords, &out, &in, &offobj, &count))
8299 return NULL;
8300#ifdef linux
8301 if (offobj == Py_None) {
8302 Py_BEGIN_ALLOW_THREADS
8303 ret = sendfile(out, in, NULL, count);
8304 Py_END_ALLOW_THREADS
8305 if (ret < 0)
8306 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008307 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308 }
8309#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008310 if (!_parse_off_t(offobj, &offset))
8311 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008312 Py_BEGIN_ALLOW_THREADS
8313 ret = sendfile(out, in, &offset, count);
8314 Py_END_ALLOW_THREADS
8315 if (ret < 0)
8316 return posix_error();
8317 return Py_BuildValue("n", ret);
8318#endif
8319}
8320#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008322PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008323"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008324Like stat(), but for an open file descriptor.\n\
8325Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008326
Barry Warsaw53699e91996-12-10 23:23:01 +00008327static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008328posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008329{
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 int fd;
8331 STRUCT_STAT st;
8332 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008333 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008334 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008335#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008336 /* on OpenVMS we must ensure that all bytes are written to the file */
8337 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008338#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 Py_BEGIN_ALLOW_THREADS
8340 res = FSTAT(fd, &st);
8341 Py_END_ALLOW_THREADS
8342 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008343#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008344 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008345#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008347#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 }
Tim Peters5aa91602002-01-30 05:46:57 +00008349
Victor Stinner4195b5c2012-02-08 23:03:19 +01008350 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008351}
8352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008353PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008354"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008355Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008356connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008357
8358static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008359posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008360{
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 int fd;
8362 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8363 return NULL;
8364 if (!_PyVerify_fd(fd))
8365 return PyBool_FromLong(0);
8366 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008367}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008368
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008369#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008370PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008371"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008372Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008373
Barry Warsaw53699e91996-12-10 23:23:01 +00008374static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008375posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008376{
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008378#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008380 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008382#else
8383 int res;
8384#endif
8385
8386#ifdef MS_WINDOWS
8387 attr.nLength = sizeof(attr);
8388 attr.lpSecurityDescriptor = NULL;
8389 attr.bInheritHandle = FALSE;
8390
8391 Py_BEGIN_ALLOW_THREADS
8392 ok = CreatePipe(&read, &write, &attr, 0);
8393 if (ok) {
8394 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8395 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8396 if (fds[0] == -1 || fds[1] == -1) {
8397 CloseHandle(read);
8398 CloseHandle(write);
8399 ok = 0;
8400 }
8401 }
8402 Py_END_ALLOW_THREADS
8403
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008405 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008406#else
8407
8408#ifdef HAVE_PIPE2
8409 Py_BEGIN_ALLOW_THREADS
8410 res = pipe2(fds, O_CLOEXEC);
8411 Py_END_ALLOW_THREADS
8412
8413 if (res != 0 && errno == ENOSYS)
8414 {
8415#endif
8416 Py_BEGIN_ALLOW_THREADS
8417 res = pipe(fds);
8418 Py_END_ALLOW_THREADS
8419
8420 if (res == 0) {
8421 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8422 close(fds[0]);
8423 close(fds[1]);
8424 return NULL;
8425 }
8426 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8427 close(fds[0]);
8428 close(fds[1]);
8429 return NULL;
8430 }
8431 }
8432#ifdef HAVE_PIPE2
8433 }
8434#endif
8435
8436 if (res != 0)
8437 return PyErr_SetFromErrno(PyExc_OSError);
8438#endif /* !MS_WINDOWS */
8439 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008440}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008441#endif /* HAVE_PIPE */
8442
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008443#ifdef HAVE_PIPE2
8444PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008445"pipe2(flags) -> (read_end, write_end)\n\n\
8446Create a pipe with flags set atomically.\n\
8447flags can be constructed by ORing together one or more of these values:\n\
8448O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008449");
8450
8451static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008452posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008453{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008454 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008455 int fds[2];
8456 int res;
8457
Serhiy Storchaka78980432013-01-15 01:12:17 +02008458 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008459 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008460 return NULL;
8461
8462 res = pipe2(fds, flags);
8463 if (res != 0)
8464 return posix_error();
8465 return Py_BuildValue("(ii)", fds[0], fds[1]);
8466}
8467#endif /* HAVE_PIPE2 */
8468
Ross Lagerwall7807c352011-03-17 20:20:30 +02008469#ifdef HAVE_WRITEV
8470PyDoc_STRVAR(posix_writev__doc__,
8471"writev(fd, buffers) -> byteswritten\n\n\
8472Write the contents of buffers to a file descriptor, where buffers is an\n\
8473arbitrary sequence of buffers.\n\
8474Returns the total bytes written.");
8475
8476static PyObject *
8477posix_writev(PyObject *self, PyObject *args)
8478{
8479 int fd, cnt;
8480 Py_ssize_t res;
8481 PyObject *seq;
8482 struct iovec *iov;
8483 Py_buffer *buf;
8484 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8485 return NULL;
8486 if (!PySequence_Check(seq)) {
8487 PyErr_SetString(PyExc_TypeError,
8488 "writev() arg 2 must be a sequence");
8489 return NULL;
8490 }
8491 cnt = PySequence_Size(seq);
8492
8493 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8494 return NULL;
8495 }
8496
8497 Py_BEGIN_ALLOW_THREADS
8498 res = writev(fd, iov, cnt);
8499 Py_END_ALLOW_THREADS
8500
8501 iov_cleanup(iov, buf, cnt);
8502 return PyLong_FromSsize_t(res);
8503}
8504#endif
8505
8506#ifdef HAVE_PWRITE
8507PyDoc_STRVAR(posix_pwrite__doc__,
8508"pwrite(fd, string, offset) -> byteswritten\n\n\
8509Write string to a file descriptor, fd, from offset, leaving the file\n\
8510offset unchanged.");
8511
8512static PyObject *
8513posix_pwrite(PyObject *self, PyObject *args)
8514{
8515 Py_buffer pbuf;
8516 int fd;
8517 off_t offset;
8518 Py_ssize_t size;
8519
8520 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8521 return NULL;
8522
8523 if (!_PyVerify_fd(fd)) {
8524 PyBuffer_Release(&pbuf);
8525 return posix_error();
8526 }
8527 Py_BEGIN_ALLOW_THREADS
8528 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8529 Py_END_ALLOW_THREADS
8530 PyBuffer_Release(&pbuf);
8531 if (size < 0)
8532 return posix_error();
8533 return PyLong_FromSsize_t(size);
8534}
8535#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008536
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008537#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008538PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008539"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8540Create a FIFO (a POSIX named pipe).\n\
8541\n\
8542If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8543 and path should be relative; path will then be relative to that directory.\n\
8544dir_fd may not be implemented on your platform.\n\
8545 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008546
Barry Warsaw53699e91996-12-10 23:23:01 +00008547static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008548posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008549{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008550 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008552 int dir_fd = DEFAULT_DIR_FD;
8553 int result;
8554 PyObject *return_value = NULL;
8555 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8556
8557 memset(&path, 0, sizeof(path));
8558 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8559 path_converter, &path,
8560 &mode,
8561#ifdef HAVE_MKFIFOAT
8562 dir_fd_converter, &dir_fd
8563#else
8564 dir_fd_unavailable, &dir_fd
8565#endif
8566 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008568
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008570#ifdef HAVE_MKFIFOAT
8571 if (dir_fd != DEFAULT_DIR_FD)
8572 result = mkfifoat(dir_fd, path.narrow, mode);
8573 else
8574#endif
8575 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008577
8578 if (result < 0) {
8579 return_value = posix_error();
8580 goto exit;
8581 }
8582
8583 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008585
8586exit:
8587 path_cleanup(&path);
8588 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008589}
8590#endif
8591
Neal Norwitz11690112002-07-30 01:08:28 +00008592#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008593PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008594"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008595Create a filesystem node (file, device special file or named pipe)\n\
8596named filename. mode specifies both the permissions to use and the\n\
8597type of node to be created, being combined (bitwise OR) with one of\n\
8598S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008599device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008600os.makedev()), otherwise it is ignored.\n\
8601\n\
8602If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8603 and path should be relative; path will then be relative to that directory.\n\
8604dir_fd may not be implemented on your platform.\n\
8605 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008606
8607
8608static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008609posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008610{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008611 path_t path;
8612 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008613 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008614 int dir_fd = DEFAULT_DIR_FD;
8615 int result;
8616 PyObject *return_value = NULL;
8617 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8618
8619 memset(&path, 0, sizeof(path));
8620 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8621 path_converter, &path,
8622 &mode, &device,
8623#ifdef HAVE_MKNODAT
8624 dir_fd_converter, &dir_fd
8625#else
8626 dir_fd_unavailable, &dir_fd
8627#endif
8628 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008629 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008630
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008632#ifdef HAVE_MKNODAT
8633 if (dir_fd != DEFAULT_DIR_FD)
8634 result = mknodat(dir_fd, path.narrow, mode, device);
8635 else
8636#endif
8637 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008639
8640 if (result < 0) {
8641 return_value = posix_error();
8642 goto exit;
8643 }
8644
8645 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008647
Larry Hastings9cf065c2012-06-22 16:30:09 -07008648exit:
8649 path_cleanup(&path);
8650 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008651}
8652#endif
8653
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008654#ifdef HAVE_DEVICE_MACROS
8655PyDoc_STRVAR(posix_major__doc__,
8656"major(device) -> major number\n\
8657Extracts a device major number from a raw device number.");
8658
8659static PyObject *
8660posix_major(PyObject *self, PyObject *args)
8661{
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 int device;
8663 if (!PyArg_ParseTuple(args, "i:major", &device))
8664 return NULL;
8665 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008666}
8667
8668PyDoc_STRVAR(posix_minor__doc__,
8669"minor(device) -> minor number\n\
8670Extracts a device minor number from a raw device number.");
8671
8672static PyObject *
8673posix_minor(PyObject *self, PyObject *args)
8674{
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 int device;
8676 if (!PyArg_ParseTuple(args, "i:minor", &device))
8677 return NULL;
8678 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008679}
8680
8681PyDoc_STRVAR(posix_makedev__doc__,
8682"makedev(major, minor) -> device number\n\
8683Composes a raw device number from the major and minor device numbers.");
8684
8685static PyObject *
8686posix_makedev(PyObject *self, PyObject *args)
8687{
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 int major, minor;
8689 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8690 return NULL;
8691 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008692}
8693#endif /* device macros */
8694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008695
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008696#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008697PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008698"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008699Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008700
Barry Warsaw53699e91996-12-10 23:23:01 +00008701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008702posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008703{
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 int fd;
8705 off_t length;
8706 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008707
Ross Lagerwall7807c352011-03-17 20:20:30 +02008708 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008710
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 Py_BEGIN_ALLOW_THREADS
8712 res = ftruncate(fd, length);
8713 Py_END_ALLOW_THREADS
8714 if (res < 0)
8715 return posix_error();
8716 Py_INCREF(Py_None);
8717 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008718}
8719#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008720
Ross Lagerwall7807c352011-03-17 20:20:30 +02008721#ifdef HAVE_TRUNCATE
8722PyDoc_STRVAR(posix_truncate__doc__,
8723"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008724Truncate the file given by path to length bytes.\n\
8725On some platforms, path may also be specified as an open file descriptor.\n\
8726 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008727
8728static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008729posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008730{
Georg Brandl306336b2012-06-24 12:55:33 +02008731 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008732 off_t length;
8733 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008734 PyObject *result = NULL;
8735 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008736
Georg Brandl306336b2012-06-24 12:55:33 +02008737 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008738 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008739#ifdef HAVE_FTRUNCATE
8740 path.allow_fd = 1;
8741#endif
8742 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8743 path_converter, &path,
8744 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008745 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008746
8747 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008748#ifdef HAVE_FTRUNCATE
8749 if (path.fd != -1)
8750 res = ftruncate(path.fd, length);
8751 else
8752#endif
8753 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008754 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008755 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008756 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008757 else {
8758 Py_INCREF(Py_None);
8759 result = Py_None;
8760 }
8761 path_cleanup(&path);
8762 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008763}
8764#endif
8765
8766#ifdef HAVE_POSIX_FALLOCATE
8767PyDoc_STRVAR(posix_posix_fallocate__doc__,
8768"posix_fallocate(fd, offset, len)\n\n\
8769Ensures that enough disk space is allocated for the file specified by fd\n\
8770starting from offset and continuing for len bytes.");
8771
8772static PyObject *
8773posix_posix_fallocate(PyObject *self, PyObject *args)
8774{
8775 off_t len, offset;
8776 int res, fd;
8777
8778 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8779 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8780 return NULL;
8781
8782 Py_BEGIN_ALLOW_THREADS
8783 res = posix_fallocate(fd, offset, len);
8784 Py_END_ALLOW_THREADS
8785 if (res != 0) {
8786 errno = res;
8787 return posix_error();
8788 }
8789 Py_RETURN_NONE;
8790}
8791#endif
8792
8793#ifdef HAVE_POSIX_FADVISE
8794PyDoc_STRVAR(posix_posix_fadvise__doc__,
8795"posix_fadvise(fd, offset, len, advice)\n\n\
8796Announces an intention to access data in a specific pattern thus allowing\n\
8797the kernel to make optimizations.\n\
8798The advice applies to the region of the file specified by fd starting at\n\
8799offset and continuing for len bytes.\n\
8800advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8801POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8802POSIX_FADV_DONTNEED.");
8803
8804static PyObject *
8805posix_posix_fadvise(PyObject *self, PyObject *args)
8806{
8807 off_t len, offset;
8808 int res, fd, advice;
8809
8810 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8811 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8812 return NULL;
8813
8814 Py_BEGIN_ALLOW_THREADS
8815 res = posix_fadvise(fd, offset, len, advice);
8816 Py_END_ALLOW_THREADS
8817 if (res != 0) {
8818 errno = res;
8819 return posix_error();
8820 }
8821 Py_RETURN_NONE;
8822}
8823#endif
8824
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008825#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008826PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008827"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008828Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008829
Fred Drake762e2061999-08-26 17:23:54 +00008830/* Save putenv() parameters as values here, so we can collect them when they
8831 * get re-set with another call for the same key. */
8832static PyObject *posix_putenv_garbage;
8833
Tim Peters5aa91602002-01-30 05:46:57 +00008834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008835posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008836{
Victor Stinner84ae1182010-05-06 22:05:07 +00008837 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008838#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008839 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008840 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008841
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008843 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008844 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008846
Victor Stinner65170952011-11-22 22:16:17 +01008847 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008848 if (newstr == NULL) {
8849 PyErr_NoMemory();
8850 goto error;
8851 }
Victor Stinner65170952011-11-22 22:16:17 +01008852 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8853 PyErr_Format(PyExc_ValueError,
8854 "the environment variable is longer than %u characters",
8855 _MAX_ENV);
8856 goto error;
8857 }
8858
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008860 if (newenv == NULL)
8861 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008864 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008866#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008867 PyObject *os1, *os2;
8868 char *s1, *s2;
8869 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008870
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008871 if (!PyArg_ParseTuple(args,
8872 "O&O&:putenv",
8873 PyUnicode_FSConverter, &os1,
8874 PyUnicode_FSConverter, &os2))
8875 return NULL;
8876 s1 = PyBytes_AsString(os1);
8877 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008878
Victor Stinner65170952011-11-22 22:16:17 +01008879 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008880 if (newstr == NULL) {
8881 PyErr_NoMemory();
8882 goto error;
8883 }
8884
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008888 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008890#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008891
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 /* Install the first arg and newstr in posix_putenv_garbage;
8893 * this will cause previous value to be collected. This has to
8894 * happen after the real putenv() call because the old value
8895 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008896 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 /* really not much we can do; just leak */
8898 PyErr_Clear();
8899 }
8900 else {
8901 Py_DECREF(newstr);
8902 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008903
Martin v. Löwis011e8422009-05-05 04:43:17 +00008904#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 Py_DECREF(os1);
8906 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008907#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008908 Py_RETURN_NONE;
8909
8910error:
8911#ifndef MS_WINDOWS
8912 Py_DECREF(os1);
8913 Py_DECREF(os2);
8914#endif
8915 Py_XDECREF(newstr);
8916 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008917}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008918#endif /* putenv */
8919
Guido van Rossumc524d952001-10-19 01:31:59 +00008920#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008921PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008922"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008923Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008924
8925static PyObject *
8926posix_unsetenv(PyObject *self, PyObject *args)
8927{
Victor Stinner65170952011-11-22 22:16:17 +01008928 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008929#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008930 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008931#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008932
8933 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008934
Victor Stinner65170952011-11-22 22:16:17 +01008935 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008936 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008937
Victor Stinner984890f2011-11-24 13:53:38 +01008938#ifdef HAVE_BROKEN_UNSETENV
8939 unsetenv(PyBytes_AS_STRING(name));
8940#else
Victor Stinner65170952011-11-22 22:16:17 +01008941 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008942 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008943 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008944 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008945 }
Victor Stinner984890f2011-11-24 13:53:38 +01008946#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008947
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 /* Remove the key from posix_putenv_garbage;
8949 * this will cause it to be collected. This has to
8950 * happen after the real unsetenv() call because the
8951 * old value was still accessible until then.
8952 */
Victor Stinner65170952011-11-22 22:16:17 +01008953 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 /* really not much we can do; just leak */
8955 PyErr_Clear();
8956 }
Victor Stinner65170952011-11-22 22:16:17 +01008957 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008958 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008959}
8960#endif /* unsetenv */
8961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008962PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008963"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008964Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008965
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008967posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008968{
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 int code;
8970 char *message;
8971 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8972 return NULL;
8973 message = strerror(code);
8974 if (message == NULL) {
8975 PyErr_SetString(PyExc_ValueError,
8976 "strerror() argument out of range");
8977 return NULL;
8978 }
Victor Stinner1b579672011-12-17 05:47:23 +01008979 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008980}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008981
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008982
Guido van Rossumc9641791998-08-04 15:26:23 +00008983#ifdef HAVE_SYS_WAIT_H
8984
Fred Drake106c1a02002-04-23 15:58:02 +00008985#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008986PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008987"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008988Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008989
8990static PyObject *
8991posix_WCOREDUMP(PyObject *self, PyObject *args)
8992{
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 WAIT_TYPE status;
8994 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008995
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8997 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008998
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009000}
9001#endif /* WCOREDUMP */
9002
9003#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009004PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009005"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009006Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009007job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009008
9009static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009010posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009011{
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 WAIT_TYPE status;
9013 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009014
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9016 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009017
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009019}
9020#endif /* WIFCONTINUED */
9021
Guido van Rossumc9641791998-08-04 15:26:23 +00009022#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009023PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009024"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009025Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009026
9027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009028posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009029{
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 WAIT_TYPE status;
9031 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009032
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9034 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009035
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009037}
9038#endif /* WIFSTOPPED */
9039
9040#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009041PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009042"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009043Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009044
9045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009046posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009047{
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 WAIT_TYPE status;
9049 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009050
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9052 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009053
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009055}
9056#endif /* WIFSIGNALED */
9057
9058#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009059PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009060"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009061Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009062system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009063
9064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009065posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009066{
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 WAIT_TYPE status;
9068 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009069
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9071 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009072
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009074}
9075#endif /* WIFEXITED */
9076
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009077#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009078PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009079"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009080Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009081
9082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009083posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009084{
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 WAIT_TYPE status;
9086 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009087
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9089 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009090
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009092}
9093#endif /* WEXITSTATUS */
9094
9095#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009096PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009097"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009098Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009099value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009100
9101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009102posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009103{
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 WAIT_TYPE status;
9105 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009106
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9108 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009109
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009111}
9112#endif /* WTERMSIG */
9113
9114#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009115PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009116"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009117Return the signal that stopped the process that provided\n\
9118the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009119
9120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009121posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009122{
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 WAIT_TYPE status;
9124 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9127 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009128
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009130}
9131#endif /* WSTOPSIG */
9132
9133#endif /* HAVE_SYS_WAIT_H */
9134
9135
Thomas Wouters477c8d52006-05-27 19:21:47 +00009136#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009137#ifdef _SCO_DS
9138/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9139 needed definitions in sys/statvfs.h */
9140#define _SVID3
9141#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009142#include <sys/statvfs.h>
9143
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009144static PyObject*
9145_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9147 if (v == NULL)
9148 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009149
9150#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009151 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9152 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9153 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9154 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9155 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9156 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9157 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9158 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9159 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9160 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009161#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9163 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9164 PyStructSequence_SET_ITEM(v, 2,
9165 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9166 PyStructSequence_SET_ITEM(v, 3,
9167 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9168 PyStructSequence_SET_ITEM(v, 4,
9169 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9170 PyStructSequence_SET_ITEM(v, 5,
9171 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9172 PyStructSequence_SET_ITEM(v, 6,
9173 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9174 PyStructSequence_SET_ITEM(v, 7,
9175 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9176 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9177 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009178#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009179 if (PyErr_Occurred()) {
9180 Py_DECREF(v);
9181 return NULL;
9182 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009183
Victor Stinner8c62be82010-05-06 00:08:46 +00009184 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009185}
9186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009187PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009188"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009189Perform an fstatvfs system call on the given fd.\n\
9190Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009191
9192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009193posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009194{
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 int fd, res;
9196 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009197
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9199 return NULL;
9200 Py_BEGIN_ALLOW_THREADS
9201 res = fstatvfs(fd, &st);
9202 Py_END_ALLOW_THREADS
9203 if (res != 0)
9204 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009205
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009207}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009208#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009209
9210
Thomas Wouters477c8d52006-05-27 19:21:47 +00009211#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009212#include <sys/statvfs.h>
9213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009214PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009215"statvfs(path)\n\n\
9216Perform a statvfs system call on the given path.\n\
9217\n\
9218path may always be specified as a string.\n\
9219On some platforms, path may also be specified as an open file descriptor.\n\
9220 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009221
9222static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009223posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009224{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009225 static char *keywords[] = {"path", NULL};
9226 path_t path;
9227 int result;
9228 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009230
Larry Hastings9cf065c2012-06-22 16:30:09 -07009231 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009232 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009233#ifdef HAVE_FSTATVFS
9234 path.allow_fd = 1;
9235#endif
9236 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9237 path_converter, &path
9238 ))
9239 return NULL;
9240
9241 Py_BEGIN_ALLOW_THREADS
9242#ifdef HAVE_FSTATVFS
9243 if (path.fd != -1) {
9244#ifdef __APPLE__
9245 /* handle weak-linking on Mac OS X 10.3 */
9246 if (fstatvfs == NULL) {
9247 fd_specified("statvfs", path.fd);
9248 goto exit;
9249 }
9250#endif
9251 result = fstatvfs(path.fd, &st);
9252 }
9253 else
9254#endif
9255 result = statvfs(path.narrow, &st);
9256 Py_END_ALLOW_THREADS
9257
9258 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009259 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009260 goto exit;
9261 }
9262
9263 return_value = _pystatvfs_fromstructstatvfs(st);
9264
9265exit:
9266 path_cleanup(&path);
9267 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009268}
9269#endif /* HAVE_STATVFS */
9270
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009271#ifdef MS_WINDOWS
9272PyDoc_STRVAR(win32__getdiskusage__doc__,
9273"_getdiskusage(path) -> (total, free)\n\n\
9274Return disk usage statistics about the given path as (total, free) tuple.");
9275
9276static PyObject *
9277win32__getdiskusage(PyObject *self, PyObject *args)
9278{
9279 BOOL retval;
9280 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009281 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009282
Victor Stinner6139c1b2011-11-09 22:14:14 +01009283 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009284 return NULL;
9285
9286 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009287 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009288 Py_END_ALLOW_THREADS
9289 if (retval == 0)
9290 return PyErr_SetFromWindowsErr(0);
9291
9292 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9293}
9294#endif
9295
9296
Fred Drakec9680921999-12-13 16:37:25 +00009297/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9298 * It maps strings representing configuration variable names to
9299 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009300 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009301 * rarely-used constants. There are three separate tables that use
9302 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009303 *
9304 * This code is always included, even if none of the interfaces that
9305 * need it are included. The #if hackery needed to avoid it would be
9306 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009307 */
9308struct constdef {
9309 char *name;
9310 long value;
9311};
9312
Fred Drake12c6e2d1999-12-14 21:25:03 +00009313static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009314conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009315 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009316{
Christian Heimes217cfd12007-12-02 14:31:20 +00009317 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009318 *valuep = PyLong_AS_LONG(arg);
9319 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009320 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009321 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009322 /* look up the value in the table using a binary search */
9323 size_t lo = 0;
9324 size_t mid;
9325 size_t hi = tablesize;
9326 int cmp;
9327 const char *confname;
9328 if (!PyUnicode_Check(arg)) {
9329 PyErr_SetString(PyExc_TypeError,
9330 "configuration names must be strings or integers");
9331 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009333 confname = _PyUnicode_AsString(arg);
9334 if (confname == NULL)
9335 return 0;
9336 while (lo < hi) {
9337 mid = (lo + hi) / 2;
9338 cmp = strcmp(confname, table[mid].name);
9339 if (cmp < 0)
9340 hi = mid;
9341 else if (cmp > 0)
9342 lo = mid + 1;
9343 else {
9344 *valuep = table[mid].value;
9345 return 1;
9346 }
9347 }
9348 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9349 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009351}
9352
9353
9354#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9355static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009356#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009358#endif
9359#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009361#endif
Fred Drakec9680921999-12-13 16:37:25 +00009362#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
9404#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009407#ifdef _PC_ACL_ENABLED
9408 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9409#endif
9410#ifdef _PC_MIN_HOLE_SIZE
9411 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9412#endif
9413#ifdef _PC_ALLOC_SIZE_MIN
9414 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9415#endif
9416#ifdef _PC_REC_INCR_XFER_SIZE
9417 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9418#endif
9419#ifdef _PC_REC_MAX_XFER_SIZE
9420 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9421#endif
9422#ifdef _PC_REC_MIN_XFER_SIZE
9423 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9424#endif
9425#ifdef _PC_REC_XFER_ALIGN
9426 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9427#endif
9428#ifdef _PC_SYMLINK_MAX
9429 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9430#endif
9431#ifdef _PC_XATTR_ENABLED
9432 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9433#endif
9434#ifdef _PC_XATTR_EXISTS
9435 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9436#endif
9437#ifdef _PC_TIMESTAMP_RESOLUTION
9438 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9439#endif
Fred Drakec9680921999-12-13 16:37:25 +00009440};
9441
Fred Drakec9680921999-12-13 16:37:25 +00009442static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009443conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009444{
9445 return conv_confname(arg, valuep, posix_constants_pathconf,
9446 sizeof(posix_constants_pathconf)
9447 / sizeof(struct constdef));
9448}
9449#endif
9450
9451#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009452PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009453"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009454Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009455If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009456
9457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009458posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009459{
9460 PyObject *result = NULL;
9461 int name, fd;
9462
Fred Drake12c6e2d1999-12-14 21:25:03 +00009463 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9464 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009465 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009466
Stefan Krah0e803b32010-11-26 16:16:47 +00009467 errno = 0;
9468 limit = fpathconf(fd, name);
9469 if (limit == -1 && errno != 0)
9470 posix_error();
9471 else
9472 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009473 }
9474 return result;
9475}
9476#endif
9477
9478
9479#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009480PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009481"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009482Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009483If there is no limit, return -1.\n\
9484On some platforms, path may also be specified as an open file descriptor.\n\
9485 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009486
9487static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009488posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009489{
Georg Brandl306336b2012-06-24 12:55:33 +02009490 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009491 PyObject *result = NULL;
9492 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009493 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009494
Georg Brandl306336b2012-06-24 12:55:33 +02009495 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009496 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009497#ifdef HAVE_FPATHCONF
9498 path.allow_fd = 1;
9499#endif
9500 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9501 path_converter, &path,
9502 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009504
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009506#ifdef HAVE_FPATHCONF
9507 if (path.fd != -1)
9508 limit = fpathconf(path.fd, name);
9509 else
9510#endif
9511 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 if (limit == -1 && errno != 0) {
9513 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009514 /* could be a path or name problem */
9515 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009516 else
Victor Stinner292c8352012-10-30 02:17:38 +01009517 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 }
9519 else
9520 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009521 }
Georg Brandl306336b2012-06-24 12:55:33 +02009522 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009523 return result;
9524}
9525#endif
9526
9527#ifdef HAVE_CONFSTR
9528static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009529#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009531#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009532#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009534#endif
9535#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009537#endif
Fred Draked86ed291999-12-15 15:34:33 +00009538#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009540#endif
9541#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009543#endif
9544#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009546#endif
9547#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009549#endif
Fred Drakec9680921999-12-13 16:37:25 +00009550#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
Fred Draked86ed291999-12-15 15:34:33 +00009574#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009576#endif
Fred Drakec9680921999-12-13 16:37:25 +00009577#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
Fred Draked86ed291999-12-15 15:34:33 +00009580#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009582#endif
9583#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009585#endif
9586#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009588#endif
9589#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009591#endif
Fred Drakec9680921999-12-13 16:37:25 +00009592#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
9625#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
9637#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
Fred Draked86ed291999-12-15 15:34:33 +00009640#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009642#endif
9643#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009645#endif
9646#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009648#endif
9649#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
9652#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
9655#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009657#endif
9658#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
9661#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009663#endif
9664#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009666#endif
9667#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
9670#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009672#endif
9673#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009675#endif
9676#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009678#endif
Fred Drakec9680921999-12-13 16:37:25 +00009679};
9680
9681static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009682conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009683{
9684 return conv_confname(arg, valuep, posix_constants_confstr,
9685 sizeof(posix_constants_confstr)
9686 / sizeof(struct constdef));
9687}
9688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009689PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009690"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009691Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009692
9693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009694posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009695{
9696 PyObject *result = NULL;
9697 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009698 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009699 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009700
Victor Stinnercb043522010-09-10 23:49:04 +00009701 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9702 return NULL;
9703
9704 errno = 0;
9705 len = confstr(name, buffer, sizeof(buffer));
9706 if (len == 0) {
9707 if (errno) {
9708 posix_error();
9709 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009710 }
9711 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009712 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009713 }
9714 }
Victor Stinnercb043522010-09-10 23:49:04 +00009715
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009716 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009717 char *buf = PyMem_Malloc(len);
9718 if (buf == NULL)
9719 return PyErr_NoMemory();
9720 confstr(name, buf, len);
9721 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9722 PyMem_Free(buf);
9723 }
9724 else
9725 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009726 return result;
9727}
9728#endif
9729
9730
9731#ifdef HAVE_SYSCONF
9732static struct constdef posix_constants_sysconf[] = {
9733#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
Fred Draked86ed291999-12-15 15:34:33 +00009763#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009765#endif
9766#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009768#endif
Fred Drakec9680921999-12-13 16:37:25 +00009769#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
Fred Drakec9680921999-12-13 16:37:25 +00009772#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
Fred Draked86ed291999-12-15 15:34:33 +00009787#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009789#endif
Fred Drakec9680921999-12-13 16:37:25 +00009790#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
Fred Draked86ed291999-12-15 15:34:33 +00009805#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009807#endif
Fred Drakec9680921999-12-13 16:37:25 +00009808#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
9841#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
Fred Draked86ed291999-12-15 15:34:33 +00009877#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009879#endif
Fred Drakec9680921999-12-13 16:37:25 +00009880#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
Fred Draked86ed291999-12-15 15:34:33 +00009889#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009891#endif
Fred Drakec9680921999-12-13 16:37:25 +00009892#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
Fred Draked86ed291999-12-15 15:34:33 +00009895#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009897#endif
9898#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009900#endif
Fred Drakec9680921999-12-13 16:37:25 +00009901#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
Fred Draked86ed291999-12-15 15:34:33 +00009913#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009915#endif
Fred Drakec9680921999-12-13 16:37:25 +00009916#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
Fred Draked86ed291999-12-15 15:34:33 +00009937#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009939#endif
Fred Drakec9680921999-12-13 16:37:25 +00009940#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
Fred Draked86ed291999-12-15 15:34:33 +00009946#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009948#endif
Fred Drakec9680921999-12-13 16:37:25 +00009949#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
Fred Draked86ed291999-12-15 15:34:33 +00009976#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009978#endif
9979#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009981#endif
Fred Drakec9680921999-12-13 16:37:25 +00009982#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
Fred Draked86ed291999-12-15 15:34:33 +000010087#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010089#endif
Fred Drakec9680921999-12-13 16:37:25 +000010090#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225};
10226
10227static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010228conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010229{
10230 return conv_confname(arg, valuep, posix_constants_sysconf,
10231 sizeof(posix_constants_sysconf)
10232 / sizeof(struct constdef));
10233}
10234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010235PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010236"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010237Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010238
10239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010240posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010241{
10242 PyObject *result = NULL;
10243 int name;
10244
10245 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010246 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010247
10248 errno = 0;
10249 value = sysconf(name);
10250 if (value == -1 && errno != 0)
10251 posix_error();
10252 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010253 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010254 }
10255 return result;
10256}
10257#endif
10258
10259
Fred Drakebec628d1999-12-15 18:31:10 +000010260/* This code is used to ensure that the tables of configuration value names
10261 * are in sorted order as required by conv_confname(), and also to build the
10262 * the exported dictionaries that are used to publish information about the
10263 * names available on the host platform.
10264 *
10265 * Sorting the table at runtime ensures that the table is properly ordered
10266 * when used, even for platforms we're not able to test on. It also makes
10267 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010268 */
Fred Drakebec628d1999-12-15 18:31:10 +000010269
10270static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010271cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010272{
10273 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010275 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010277
10278 return strcmp(c1->name, c2->name);
10279}
10280
10281static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010282setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010284{
Fred Drakebec628d1999-12-15 18:31:10 +000010285 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010286 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010287
10288 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10289 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010290 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010292
Barry Warsaw3155db32000-04-13 15:20:40 +000010293 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 PyObject *o = PyLong_FromLong(table[i].value);
10295 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10296 Py_XDECREF(o);
10297 Py_DECREF(d);
10298 return -1;
10299 }
10300 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010301 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010302 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010303}
10304
Fred Drakebec628d1999-12-15 18:31:10 +000010305/* Return -1 on failure, 0 on success. */
10306static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010307setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010308{
10309#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010310 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010311 sizeof(posix_constants_pathconf)
10312 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010313 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010314 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010315#endif
10316#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010317 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010318 sizeof(posix_constants_confstr)
10319 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010320 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010321 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010322#endif
10323#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010324 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010325 sizeof(posix_constants_sysconf)
10326 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010327 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010328 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010329#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010330 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010331}
Fred Draked86ed291999-12-15 15:34:33 +000010332
10333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010334PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010335"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010336Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010337in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338
10339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010340posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010341{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010342 abort();
10343 /*NOTREACHED*/
10344 Py_FatalError("abort() called from Python code didn't abort!");
10345 return NULL;
10346}
Fred Drakebec628d1999-12-15 18:31:10 +000010347
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010348#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010349PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010350"startfile(filepath [, operation]) - Start a file with its associated\n\
10351application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010352\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010353When \"operation\" is not specified or \"open\", this acts like\n\
10354double-clicking the file in Explorer, or giving the file name as an\n\
10355argument to the DOS \"start\" command: the file is opened with whatever\n\
10356application (if any) its extension is associated.\n\
10357When another \"operation\" is given, it specifies what should be done with\n\
10358the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010359\n\
10360startfile returns as soon as the associated application is launched.\n\
10361There is no option to wait for the application to close, and no way\n\
10362to retrieve the application's exit status.\n\
10363\n\
10364The filepath is relative to the current directory. If you want to use\n\
10365an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010366the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010367
10368static PyObject *
10369win32_startfile(PyObject *self, PyObject *args)
10370{
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 PyObject *ofilepath;
10372 char *filepath;
10373 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010374 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010376
Victor Stinnereb5657a2011-09-30 01:44:27 +020010377 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 if (!PyArg_ParseTuple(args, "U|s:startfile",
10379 &unipath, &operation)) {
10380 PyErr_Clear();
10381 goto normal;
10382 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010383
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010385 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010387 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 PyErr_Clear();
10389 operation = NULL;
10390 goto normal;
10391 }
10392 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010393
Victor Stinnereb5657a2011-09-30 01:44:27 +020010394 wpath = PyUnicode_AsUnicode(unipath);
10395 if (wpath == NULL)
10396 goto normal;
10397 if (uoperation) {
10398 woperation = PyUnicode_AsUnicode(uoperation);
10399 if (woperation == NULL)
10400 goto normal;
10401 }
10402 else
10403 woperation = NULL;
10404
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010406 rc = ShellExecuteW((HWND)0, woperation, wpath,
10407 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 Py_END_ALLOW_THREADS
10409
Victor Stinnereb5657a2011-09-30 01:44:27 +020010410 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010412 win32_error_object("startfile", unipath);
10413 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 }
10415 Py_INCREF(Py_None);
10416 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010417
10418normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10420 PyUnicode_FSConverter, &ofilepath,
10421 &operation))
10422 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010423 if (win32_warn_bytes_api()) {
10424 Py_DECREF(ofilepath);
10425 return NULL;
10426 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 filepath = PyBytes_AsString(ofilepath);
10428 Py_BEGIN_ALLOW_THREADS
10429 rc = ShellExecute((HWND)0, operation, filepath,
10430 NULL, NULL, SW_SHOWNORMAL);
10431 Py_END_ALLOW_THREADS
10432 if (rc <= (HINSTANCE)32) {
10433 PyObject *errval = win32_error("startfile", filepath);
10434 Py_DECREF(ofilepath);
10435 return errval;
10436 }
10437 Py_DECREF(ofilepath);
10438 Py_INCREF(Py_None);
10439 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010440}
10441#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010442
Martin v. Löwis438b5342002-12-27 10:16:42 +000010443#ifdef HAVE_GETLOADAVG
10444PyDoc_STRVAR(posix_getloadavg__doc__,
10445"getloadavg() -> (float, float, float)\n\n\
10446Return the number of processes in the system run queue averaged over\n\
10447the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10448was unobtainable");
10449
10450static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010451posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010452{
10453 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010454 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010455 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10456 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010457 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010458 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010459}
10460#endif
10461
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010462PyDoc_STRVAR(device_encoding__doc__,
10463"device_encoding(fd) -> str\n\n\
10464Return a string describing the encoding of the device\n\
10465if the output is a terminal; else return None.");
10466
10467static PyObject *
10468device_encoding(PyObject *self, PyObject *args)
10469{
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010471
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10473 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010474
10475 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010476}
10477
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010478#ifdef HAVE_SETRESUID
10479PyDoc_STRVAR(posix_setresuid__doc__,
10480"setresuid(ruid, euid, suid)\n\n\
10481Set the current process's real, effective, and saved user ids.");
10482
10483static PyObject*
10484posix_setresuid (PyObject *self, PyObject *args)
10485{
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010487 uid_t ruid, euid, suid;
10488 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10489 _Py_Uid_Converter, &ruid,
10490 _Py_Uid_Converter, &euid,
10491 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 return NULL;
10493 if (setresuid(ruid, euid, suid) < 0)
10494 return posix_error();
10495 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010496}
10497#endif
10498
10499#ifdef HAVE_SETRESGID
10500PyDoc_STRVAR(posix_setresgid__doc__,
10501"setresgid(rgid, egid, sgid)\n\n\
10502Set the current process's real, effective, and saved group ids.");
10503
10504static PyObject*
10505posix_setresgid (PyObject *self, PyObject *args)
10506{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010507 gid_t rgid, egid, sgid;
10508 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10509 _Py_Gid_Converter, &rgid,
10510 _Py_Gid_Converter, &egid,
10511 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 return NULL;
10513 if (setresgid(rgid, egid, sgid) < 0)
10514 return posix_error();
10515 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010516}
10517#endif
10518
10519#ifdef HAVE_GETRESUID
10520PyDoc_STRVAR(posix_getresuid__doc__,
10521"getresuid() -> (ruid, euid, suid)\n\n\
10522Get tuple of the current process's real, effective, and saved user ids.");
10523
10524static PyObject*
10525posix_getresuid (PyObject *self, PyObject *noargs)
10526{
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 if (getresuid(&ruid, &euid, &suid) < 0)
10529 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010530 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10531 _PyLong_FromUid(euid),
10532 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010533}
10534#endif
10535
10536#ifdef HAVE_GETRESGID
10537PyDoc_STRVAR(posix_getresgid__doc__,
10538"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010539Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010540
10541static PyObject*
10542posix_getresgid (PyObject *self, PyObject *noargs)
10543{
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 if (getresgid(&rgid, &egid, &sgid) < 0)
10546 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010547 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10548 _PyLong_FromGid(egid),
10549 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010550}
10551#endif
10552
Benjamin Peterson9428d532011-09-14 11:45:52 -040010553#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010554
Benjamin Peterson799bd802011-08-31 22:15:17 -040010555PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010556"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10557Return the value of extended attribute attribute on path.\n\
10558\n\
10559path may be either a string or an open file descriptor.\n\
10560If follow_symlinks is False, and the last element of the path is a symbolic\n\
10561 link, getxattr will examine the symbolic link itself instead of the file\n\
10562 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563
10564static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010565posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010566{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010567 path_t path;
10568 path_t attribute;
10569 int follow_symlinks = 1;
10570 PyObject *buffer = NULL;
10571 int i;
10572 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010573
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574 memset(&path, 0, sizeof(path));
10575 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010576 path.function_name = "getxattr";
10577 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010578 path.allow_fd = 1;
10579 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10580 path_converter, &path,
10581 path_converter, &attribute,
10582 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010584
Larry Hastings9cf065c2012-06-22 16:30:09 -070010585 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10586 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010587
Larry Hastings9cf065c2012-06-22 16:30:09 -070010588 for (i = 0; ; i++) {
10589 void *ptr;
10590 ssize_t result;
10591 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10592 Py_ssize_t buffer_size = buffer_sizes[i];
10593 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010594 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 goto exit;
10596 }
10597 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10598 if (!buffer)
10599 goto exit;
10600 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010601
Larry Hastings9cf065c2012-06-22 16:30:09 -070010602 Py_BEGIN_ALLOW_THREADS;
10603 if (path.fd >= 0)
10604 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10605 else if (follow_symlinks)
10606 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10607 else
10608 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10609 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010610
Larry Hastings9cf065c2012-06-22 16:30:09 -070010611 if (result < 0) {
10612 Py_DECREF(buffer);
10613 buffer = NULL;
10614 if (errno == ERANGE)
10615 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010616 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010617 goto exit;
10618 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619
Larry Hastings9cf065c2012-06-22 16:30:09 -070010620 if (result != buffer_size) {
10621 /* Can only shrink. */
10622 _PyBytes_Resize(&buffer, result);
10623 }
10624 break;
10625 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626
Larry Hastings9cf065c2012-06-22 16:30:09 -070010627exit:
10628 path_cleanup(&path);
10629 path_cleanup(&attribute);
10630 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010631}
10632
10633PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10635Set extended attribute attribute on path to value.\n\
10636path may be either a string or an open file descriptor.\n\
10637If follow_symlinks is False, and the last element of the path is a symbolic\n\
10638 link, setxattr will modify the symbolic link itself instead of the file\n\
10639 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010640
10641static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010642posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010643{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010644 path_t path;
10645 path_t attribute;
10646 Py_buffer value;
10647 int flags = 0;
10648 int follow_symlinks = 1;
10649 int result;
10650 PyObject *return_value = NULL;
10651 static char *keywords[] = {"path", "attribute", "value",
10652 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010653
Larry Hastings9cf065c2012-06-22 16:30:09 -070010654 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010655 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010656 path.allow_fd = 1;
10657 memset(&attribute, 0, sizeof(attribute));
10658 memset(&value, 0, sizeof(value));
10659 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10660 keywords,
10661 path_converter, &path,
10662 path_converter, &attribute,
10663 &value, &flags,
10664 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010665 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666
10667 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10668 goto exit;
10669
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010671 if (path.fd > -1)
10672 result = fsetxattr(path.fd, attribute.narrow,
10673 value.buf, value.len, flags);
10674 else if (follow_symlinks)
10675 result = setxattr(path.narrow, attribute.narrow,
10676 value.buf, value.len, flags);
10677 else
10678 result = lsetxattr(path.narrow, attribute.narrow,
10679 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010681
Larry Hastings9cf065c2012-06-22 16:30:09 -070010682 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010683 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 goto exit;
10685 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010686
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687 return_value = Py_None;
10688 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010689
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690exit:
10691 path_cleanup(&path);
10692 path_cleanup(&attribute);
10693 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010694
Larry Hastings9cf065c2012-06-22 16:30:09 -070010695 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696}
10697
10698PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010699"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10700Remove extended attribute attribute on path.\n\
10701path may be either a string or an open file descriptor.\n\
10702If follow_symlinks is False, and the last element of the path is a symbolic\n\
10703 link, removexattr will modify the symbolic link itself instead of the file\n\
10704 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010705
10706static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010707posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010708{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010709 path_t path;
10710 path_t attribute;
10711 int follow_symlinks = 1;
10712 int result;
10713 PyObject *return_value = NULL;
10714 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010715
Larry Hastings9cf065c2012-06-22 16:30:09 -070010716 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010717 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010719 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010720 path.allow_fd = 1;
10721 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10722 keywords,
10723 path_converter, &path,
10724 path_converter, &attribute,
10725 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010726 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727
10728 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10729 goto exit;
10730
Benjamin Peterson799bd802011-08-31 22:15:17 -040010731 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 if (path.fd > -1)
10733 result = fremovexattr(path.fd, attribute.narrow);
10734 else if (follow_symlinks)
10735 result = removexattr(path.narrow, attribute.narrow);
10736 else
10737 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010738 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010739
Larry Hastings9cf065c2012-06-22 16:30:09 -070010740 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010741 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010744
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 return_value = Py_None;
10746 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010747
Larry Hastings9cf065c2012-06-22 16:30:09 -070010748exit:
10749 path_cleanup(&path);
10750 path_cleanup(&attribute);
10751
10752 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010753}
10754
10755PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756"listxattr(path='.', *, follow_symlinks=True)\n\n\
10757Return a list of extended attributes on path.\n\
10758\n\
10759path may be either None, a string, or an open file descriptor.\n\
10760if path is None, listxattr will examine the current directory.\n\
10761If follow_symlinks is False, and the last element of the path is a symbolic\n\
10762 link, listxattr will examine the symbolic link itself instead of the file\n\
10763 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010764
10765static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010767{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 path_t path;
10769 int follow_symlinks = 1;
10770 Py_ssize_t i;
10771 PyObject *result = NULL;
10772 char *buffer = NULL;
10773 char *name;
10774 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010775
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010777 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 path.allow_fd = 1;
10779 path.fd = -1;
10780 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10781 path_converter, &path,
10782 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10786 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 name = path.narrow ? path.narrow : ".";
10789 for (i = 0; ; i++) {
10790 char *start, *trace, *end;
10791 ssize_t length;
10792 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10793 Py_ssize_t buffer_size = buffer_sizes[i];
10794 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010795 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010796 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010797 break;
10798 }
10799 buffer = PyMem_MALLOC(buffer_size);
10800 if (!buffer) {
10801 PyErr_NoMemory();
10802 break;
10803 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804
Larry Hastings9cf065c2012-06-22 16:30:09 -070010805 Py_BEGIN_ALLOW_THREADS;
10806 if (path.fd > -1)
10807 length = flistxattr(path.fd, buffer, buffer_size);
10808 else if (follow_symlinks)
10809 length = listxattr(name, buffer, buffer_size);
10810 else
10811 length = llistxattr(name, buffer, buffer_size);
10812 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010815 if (errno == ERANGE) {
10816 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010817 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010819 }
Victor Stinner292c8352012-10-30 02:17:38 +010010820 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 break;
10822 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 result = PyList_New(0);
10825 if (!result) {
10826 goto exit;
10827 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010828
Larry Hastings9cf065c2012-06-22 16:30:09 -070010829 end = buffer + length;
10830 for (trace = start = buffer; trace != end; trace++) {
10831 if (!*trace) {
10832 int error;
10833 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10834 trace - start);
10835 if (!attribute) {
10836 Py_DECREF(result);
10837 result = NULL;
10838 goto exit;
10839 }
10840 error = PyList_Append(result, attribute);
10841 Py_DECREF(attribute);
10842 if (error) {
10843 Py_DECREF(result);
10844 result = NULL;
10845 goto exit;
10846 }
10847 start = trace + 1;
10848 }
10849 }
10850 break;
10851 }
10852exit:
10853 path_cleanup(&path);
10854 if (buffer)
10855 PyMem_FREE(buffer);
10856 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010857}
10858
Benjamin Peterson9428d532011-09-14 11:45:52 -040010859#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010861
Georg Brandl2fb477c2012-02-21 00:33:36 +010010862PyDoc_STRVAR(posix_urandom__doc__,
10863"urandom(n) -> str\n\n\
10864Return n random bytes suitable for cryptographic use.");
10865
10866static PyObject *
10867posix_urandom(PyObject *self, PyObject *args)
10868{
10869 Py_ssize_t size;
10870 PyObject *result;
10871 int ret;
10872
10873 /* Read arguments */
10874 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10875 return NULL;
10876 if (size < 0)
10877 return PyErr_Format(PyExc_ValueError,
10878 "negative argument not allowed");
10879 result = PyBytes_FromStringAndSize(NULL, size);
10880 if (result == NULL)
10881 return NULL;
10882
10883 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10884 PyBytes_GET_SIZE(result));
10885 if (ret == -1) {
10886 Py_DECREF(result);
10887 return NULL;
10888 }
10889 return result;
10890}
10891
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010892/* Terminal size querying */
10893
10894static PyTypeObject TerminalSizeType;
10895
10896PyDoc_STRVAR(TerminalSize_docstring,
10897 "A tuple of (columns, lines) for holding terminal window size");
10898
10899static PyStructSequence_Field TerminalSize_fields[] = {
10900 {"columns", "width of the terminal window in characters"},
10901 {"lines", "height of the terminal window in characters"},
10902 {NULL, NULL}
10903};
10904
10905static PyStructSequence_Desc TerminalSize_desc = {
10906 "os.terminal_size",
10907 TerminalSize_docstring,
10908 TerminalSize_fields,
10909 2,
10910};
10911
10912#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10913PyDoc_STRVAR(termsize__doc__,
10914 "Return the size of the terminal window as (columns, lines).\n" \
10915 "\n" \
10916 "The optional argument fd (default standard output) specifies\n" \
10917 "which file descriptor should be queried.\n" \
10918 "\n" \
10919 "If the file descriptor is not connected to a terminal, an OSError\n" \
10920 "is thrown.\n" \
10921 "\n" \
10922 "This function will only be defined if an implementation is\n" \
10923 "available for this system.\n" \
10924 "\n" \
10925 "shutil.get_terminal_size is the high-level function which should \n" \
10926 "normally be used, os.get_terminal_size is the low-level implementation.");
10927
10928static PyObject*
10929get_terminal_size(PyObject *self, PyObject *args)
10930{
10931 int columns, lines;
10932 PyObject *termsize;
10933
10934 int fd = fileno(stdout);
10935 /* Under some conditions stdout may not be connected and
10936 * fileno(stdout) may point to an invalid file descriptor. For example
10937 * GUI apps don't have valid standard streams by default.
10938 *
10939 * If this happens, and the optional fd argument is not present,
10940 * the ioctl below will fail returning EBADF. This is what we want.
10941 */
10942
10943 if (!PyArg_ParseTuple(args, "|i", &fd))
10944 return NULL;
10945
10946#ifdef TERMSIZE_USE_IOCTL
10947 {
10948 struct winsize w;
10949 if (ioctl(fd, TIOCGWINSZ, &w))
10950 return PyErr_SetFromErrno(PyExc_OSError);
10951 columns = w.ws_col;
10952 lines = w.ws_row;
10953 }
10954#endif /* TERMSIZE_USE_IOCTL */
10955
10956#ifdef TERMSIZE_USE_CONIO
10957 {
10958 DWORD nhandle;
10959 HANDLE handle;
10960 CONSOLE_SCREEN_BUFFER_INFO csbi;
10961 switch (fd) {
10962 case 0: nhandle = STD_INPUT_HANDLE;
10963 break;
10964 case 1: nhandle = STD_OUTPUT_HANDLE;
10965 break;
10966 case 2: nhandle = STD_ERROR_HANDLE;
10967 break;
10968 default:
10969 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10970 }
10971 handle = GetStdHandle(nhandle);
10972 if (handle == NULL)
10973 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10974 if (handle == INVALID_HANDLE_VALUE)
10975 return PyErr_SetFromWindowsErr(0);
10976
10977 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10978 return PyErr_SetFromWindowsErr(0);
10979
10980 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10981 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10982 }
10983#endif /* TERMSIZE_USE_CONIO */
10984
10985 termsize = PyStructSequence_New(&TerminalSizeType);
10986 if (termsize == NULL)
10987 return NULL;
10988 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10989 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10990 if (PyErr_Occurred()) {
10991 Py_DECREF(termsize);
10992 return NULL;
10993 }
10994 return termsize;
10995}
10996#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10997
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010998PyDoc_STRVAR(posix_cpu_count__doc__,
10999"cpu_count() -> integer\n\n\
11000Return the number of CPUs in the system, or None if this value cannot be\n\
11001established.");
11002
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011003static PyObject *
11004posix_cpu_count(PyObject *self)
11005{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011006 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011007#ifdef MS_WINDOWS
11008 SYSTEM_INFO sysinfo;
11009 GetSystemInfo(&sysinfo);
11010 ncpu = sysinfo.dwNumberOfProcessors;
11011#elif defined(__hpux)
11012 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11013#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11014 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011015#elif defined(__DragonFly__) || \
11016 defined(__OpenBSD__) || \
11017 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011018 defined(__NetBSD__) || \
11019 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011020 int mib[2];
11021 size_t len = sizeof(ncpu);
11022 mib[0] = CTL_HW;
11023 mib[1] = HW_NCPU;
11024 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11025 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011026#endif
11027 if (ncpu >= 1)
11028 return PyLong_FromLong(ncpu);
11029 else
11030 Py_RETURN_NONE;
11031}
11032
Victor Stinnerdaf45552013-08-28 00:53:59 +020011033PyDoc_STRVAR(get_inheritable__doc__,
11034 "get_inheritable(fd) -> bool\n" \
11035 "\n" \
11036 "Get the close-on-exe flag of the specified file descriptor.");
11037
11038static PyObject*
11039posix_get_inheritable(PyObject *self, PyObject *args)
11040{
11041 int fd;
11042 int inheritable;
11043
11044 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11045 return NULL;
11046
11047 if (!_PyVerify_fd(fd))
11048 return posix_error();
11049
11050 inheritable = _Py_get_inheritable(fd);
11051 if (inheritable < 0)
11052 return NULL;
11053 return PyBool_FromLong(inheritable);
11054}
11055
11056PyDoc_STRVAR(set_inheritable__doc__,
11057 "set_inheritable(fd, inheritable)\n" \
11058 "\n" \
11059 "Set the inheritable flag of the specified file descriptor.");
11060
11061static PyObject*
11062posix_set_inheritable(PyObject *self, PyObject *args)
11063{
11064 int fd, inheritable;
11065
11066 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11067 return NULL;
11068
11069 if (!_PyVerify_fd(fd))
11070 return posix_error();
11071
11072 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11073 return NULL;
11074 Py_RETURN_NONE;
11075}
11076
11077
11078#ifdef MS_WINDOWS
11079PyDoc_STRVAR(get_handle_inheritable__doc__,
11080 "get_handle_inheritable(fd) -> bool\n" \
11081 "\n" \
11082 "Get the close-on-exe flag of the specified file descriptor.");
11083
11084static PyObject*
11085posix_get_handle_inheritable(PyObject *self, PyObject *args)
11086{
11087 Py_intptr_t handle;
11088 DWORD flags;
11089
11090 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11091 return NULL;
11092
11093 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11094 PyErr_SetFromWindowsErr(0);
11095 return NULL;
11096 }
11097
11098 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11099}
11100
11101PyDoc_STRVAR(set_handle_inheritable__doc__,
11102 "set_handle_inheritable(fd, inheritable)\n" \
11103 "\n" \
11104 "Set the inheritable flag of the specified handle.");
11105
11106static PyObject*
11107posix_set_handle_inheritable(PyObject *self, PyObject *args)
11108{
11109 int inheritable = 1;
11110 Py_intptr_t handle;
11111 DWORD flags;
11112
11113 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11114 &handle, &inheritable))
11115 return NULL;
11116
11117 if (inheritable)
11118 flags = HANDLE_FLAG_INHERIT;
11119 else
11120 flags = 0;
11121 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11122 PyErr_SetFromWindowsErr(0);
11123 return NULL;
11124 }
11125 Py_RETURN_NONE;
11126}
11127#endif /* MS_WINDOWS */
11128
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011129
Larry Hastings31826802013-10-19 00:09:25 -070011130
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011131static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011132
11133 OS_STAT_METHODDEF
11134 OS_ACCESS_METHODDEF
11135 OS_TTYNAME_METHODDEF
11136
Larry Hastings9cf065c2012-06-22 16:30:09 -070011137 {"chdir", (PyCFunction)posix_chdir,
11138 METH_VARARGS | METH_KEYWORDS,
11139 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011140#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 {"chflags", (PyCFunction)posix_chflags,
11142 METH_VARARGS | METH_KEYWORDS,
11143 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011144#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011145 {"chmod", (PyCFunction)posix_chmod,
11146 METH_VARARGS | METH_KEYWORDS,
11147 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011148#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011150#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011151#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011152 {"chown", (PyCFunction)posix_chown,
11153 METH_VARARGS | METH_KEYWORDS,
11154 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011155#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011156#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011158#endif /* HAVE_LCHMOD */
11159#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011161#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011162#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011164#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011165#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011167#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011168#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011170#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011171#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011173#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11175 METH_NOARGS, posix_getcwd__doc__},
11176 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11177 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011178#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11179 {"link", (PyCFunction)posix_link,
11180 METH_VARARGS | METH_KEYWORDS,
11181 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011182#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011183 {"listdir", (PyCFunction)posix_listdir,
11184 METH_VARARGS | METH_KEYWORDS,
11185 posix_listdir__doc__},
11186 {"lstat", (PyCFunction)posix_lstat,
11187 METH_VARARGS | METH_KEYWORDS,
11188 posix_lstat__doc__},
11189 {"mkdir", (PyCFunction)posix_mkdir,
11190 METH_VARARGS | METH_KEYWORDS,
11191 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011192#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011194#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011195#ifdef HAVE_GETPRIORITY
11196 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11197#endif /* HAVE_GETPRIORITY */
11198#ifdef HAVE_SETPRIORITY
11199 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11200#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011201#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011202 {"readlink", (PyCFunction)posix_readlink,
11203 METH_VARARGS | METH_KEYWORDS,
11204 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011205#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011206#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011207 {"readlink", (PyCFunction)win_readlink,
11208 METH_VARARGS | METH_KEYWORDS,
11209 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011210#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011211 {"rename", (PyCFunction)posix_rename,
11212 METH_VARARGS | METH_KEYWORDS,
11213 posix_rename__doc__},
11214 {"replace", (PyCFunction)posix_replace,
11215 METH_VARARGS | METH_KEYWORDS,
11216 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011217 {"rmdir", (PyCFunction)posix_rmdir,
11218 METH_VARARGS | METH_KEYWORDS,
11219 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011221#if defined(HAVE_SYMLINK)
11222 {"symlink", (PyCFunction)posix_symlink,
11223 METH_VARARGS | METH_KEYWORDS,
11224 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011225#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011226#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011228#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011230#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011232#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011233 {"unlink", (PyCFunction)posix_unlink,
11234 METH_VARARGS | METH_KEYWORDS,
11235 posix_unlink__doc__},
11236 {"remove", (PyCFunction)posix_unlink,
11237 METH_VARARGS | METH_KEYWORDS,
11238 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011239 {"utime", (PyCFunction)posix_utime,
11240 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011241#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011243#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011245#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011247 {"execve", (PyCFunction)posix_execve,
11248 METH_VARARGS | METH_KEYWORDS,
11249 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011250#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011251#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11253 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011254#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011255#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011257#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011258#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011260#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011261#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011262#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011263 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11264 {"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 +020011265#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011266#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011267 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011268#endif
11269#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011270 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011271#endif
11272#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011273 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011274#endif
11275#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011276 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011277#endif
11278#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011279 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011280#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011281 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011282#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011283 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11284 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11285#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011286#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011287#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011289#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011290#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011292#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011293#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011295#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011296#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011298#endif /* HAVE_GETEUID */
11299#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011301#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011302#ifdef HAVE_GETGROUPLIST
11303 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11304#endif
Fred Drakec9680921999-12-13 16:37:25 +000011305#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011307#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011309#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011311#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011312#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011314#endif /* HAVE_GETPPID */
11315#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011317#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011318#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011320#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011321#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011323#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011324#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011326#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011327#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011329#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011330#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11332 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011333#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011334#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011336#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011337#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011339#endif /* HAVE_SETEUID */
11340#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011342#endif /* HAVE_SETEGID */
11343#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011345#endif /* HAVE_SETREUID */
11346#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011348#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011349#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011351#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011352#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011354#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011355#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011357#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011358#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011360#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011361#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011363#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011364#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011366#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011367#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011368 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011369#endif /* HAVE_WAIT3 */
11370#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011371 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011372#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011373#if defined(HAVE_WAITID) && !defined(__APPLE__)
11374 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11375#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011376#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011378#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011379#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011381#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011382#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011384#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011385#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011387#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011388#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011390#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011391#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011393#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011394 {"open", (PyCFunction)posix_open,\
11395 METH_VARARGS | METH_KEYWORDS,
11396 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11398 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11399 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11400 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011401 {"dup2", (PyCFunction)posix_dup2,
11402 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011403#ifdef HAVE_LOCKF
11404 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11405#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11407 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011408#ifdef HAVE_READV
11409 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11410#endif
11411#ifdef HAVE_PREAD
11412 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11413#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011415#ifdef HAVE_WRITEV
11416 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11417#endif
11418#ifdef HAVE_PWRITE
11419 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11420#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011421#ifdef HAVE_SENDFILE
11422 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11423 posix_sendfile__doc__},
11424#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011425 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011427#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011428 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011429#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011430#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011431 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011432#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011433#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011434 {"mkfifo", (PyCFunction)posix_mkfifo,
11435 METH_VARARGS | METH_KEYWORDS,
11436 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011437#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011438#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011439 {"mknod", (PyCFunction)posix_mknod,
11440 METH_VARARGS | METH_KEYWORDS,
11441 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011442#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011443#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11445 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11446 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011447#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011448#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011450#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011451#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011452 {"truncate", (PyCFunction)posix_truncate,
11453 METH_VARARGS | METH_KEYWORDS,
11454 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011455#endif
11456#ifdef HAVE_POSIX_FALLOCATE
11457 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11458#endif
11459#ifdef HAVE_POSIX_FADVISE
11460 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11461#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011462#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011464#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011465#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011467#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011469#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011471#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011472#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011474#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011475#ifdef HAVE_SYNC
11476 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11477#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011478#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011480#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011481#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011482#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011484#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011485#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011487#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011488#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011490#endif /* WIFSTOPPED */
11491#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011493#endif /* WIFSIGNALED */
11494#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011496#endif /* WIFEXITED */
11497#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011499#endif /* WEXITSTATUS */
11500#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011502#endif /* WTERMSIG */
11503#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011505#endif /* WSTOPSIG */
11506#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011507#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011509#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011510#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011511 {"statvfs", (PyCFunction)posix_statvfs,
11512 METH_VARARGS | METH_KEYWORDS,
11513 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011514#endif
Fred Drakec9680921999-12-13 16:37:25 +000011515#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011517#endif
11518#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011520#endif
11521#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011523#endif
11524#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011525 {"pathconf", (PyCFunction)posix_pathconf,
11526 METH_VARARGS | METH_KEYWORDS,
11527 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011528#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011530#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011532 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011533 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011534 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011535 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011536#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011537#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011539#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011540 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011541#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011543#endif
11544#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011546#endif
11547#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011549#endif
11550#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011552#endif
11553
Benjamin Peterson9428d532011-09-14 11:45:52 -040011554#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011555 {"setxattr", (PyCFunction)posix_setxattr,
11556 METH_VARARGS | METH_KEYWORDS,
11557 posix_setxattr__doc__},
11558 {"getxattr", (PyCFunction)posix_getxattr,
11559 METH_VARARGS | METH_KEYWORDS,
11560 posix_getxattr__doc__},
11561 {"removexattr", (PyCFunction)posix_removexattr,
11562 METH_VARARGS | METH_KEYWORDS,
11563 posix_removexattr__doc__},
11564 {"listxattr", (PyCFunction)posix_listxattr,
11565 METH_VARARGS | METH_KEYWORDS,
11566 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011567#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011568#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11569 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11570#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011571 {"cpu_count", (PyCFunction)posix_cpu_count,
11572 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011573 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11574 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11575#ifdef MS_WINDOWS
11576 {"get_handle_inheritable", posix_get_handle_inheritable,
11577 METH_VARARGS, get_handle_inheritable__doc__},
11578 {"set_handle_inheritable", posix_set_handle_inheritable,
11579 METH_VARARGS, set_handle_inheritable__doc__},
11580#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011581 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011582};
11583
11584
Brian Curtin52173d42010-12-02 18:29:18 +000011585#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011586static int
Brian Curtin52173d42010-12-02 18:29:18 +000011587enable_symlink()
11588{
11589 HANDLE tok;
11590 TOKEN_PRIVILEGES tok_priv;
11591 LUID luid;
11592 int meth_idx = 0;
11593
11594 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011595 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011596
11597 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011598 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011599
11600 tok_priv.PrivilegeCount = 1;
11601 tok_priv.Privileges[0].Luid = luid;
11602 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11603
11604 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11605 sizeof(TOKEN_PRIVILEGES),
11606 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011607 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011608
Brian Curtin3b4499c2010-12-28 14:31:47 +000011609 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11610 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011611}
11612#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11613
Barry Warsaw4a342091996-12-19 23:50:02 +000011614static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011615all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011616{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011617#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011618 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011620#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011621 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011623#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011624 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011625#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011626#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011627 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011628#endif
Fred Drakec9680921999-12-13 16:37:25 +000011629#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011630 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011631#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011632#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011633 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011634#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011635#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011636 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011637#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011638#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011639 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011640#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011641#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011642 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011643#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011644#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011645 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011646#endif
11647#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011648 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011649#endif
11650#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011651 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011652#endif
11653#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011654 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011655#endif
11656#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011657 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011658#endif
11659#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011660 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011661#endif
11662#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011663 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011664#endif
11665#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011666 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011667#endif
11668#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011669 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011670#endif
11671#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011672 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011673#endif
11674#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011675 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011676#endif
11677#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011678 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011679#endif
11680#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011681 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011682#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011683#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011684 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011685#endif
11686#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011687 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011688#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011689#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011690 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011691#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011692#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011693 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011694#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011695#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011696 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011697#endif
11698#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011699 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011700#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011701#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011702 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011703#endif
11704#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011705 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011706#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011707#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011708 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011709#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011710#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011711 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011712#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011713#ifdef O_TMPFILE
11714 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11715#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011716#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011717 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011718#endif
11719#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011720 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011721#endif
11722#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011723 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011724#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011725#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011726 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011727#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011728#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011729 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011730#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011731
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011732
Jesus Cea94363612012-06-22 18:32:07 +020011733#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011734 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011735#endif
11736#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011737 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011738#endif
11739
Tim Peters5aa91602002-01-30 05:46:57 +000011740/* MS Windows */
11741#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011742 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011743 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011744#endif
11745#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 /* Optimize for short life (keep in memory). */
11747 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011748 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011749#endif
11750#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011751 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011752 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011753#endif
11754#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011755 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011756 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011757#endif
11758#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011759 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011760 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011761#endif
11762
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011763/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011764#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 /* Send a SIGIO signal whenever input or output
11766 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011767 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011768#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011769#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011771 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011772#endif
11773#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011774 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011775 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011776#endif
11777#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011778 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011779 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011780#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011781#ifdef O_NOLINKS
11782 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011783 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011784#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011785#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011786 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011787 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011788#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011789
Victor Stinner8c62be82010-05-06 00:08:46 +000011790 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011791#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011792 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011793#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011794#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011795 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011796#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011797#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011798 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011799#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011800#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011801 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011802#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011803#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011804 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011805#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011806#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011807 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011808#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011809#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011810 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011811#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011812#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011813 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011814#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011815#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011816 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011817#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011818#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011819 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011820#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011821#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011822 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011823#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011824#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011825 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011826#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011827#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011828 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011829#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011830#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011831 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011832#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011833#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011834 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011835#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011836#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011837 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011838#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011839#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011840 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011841#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011842
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011843 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011844#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011845 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011846#endif /* ST_RDONLY */
11847#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011848 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011849#endif /* ST_NOSUID */
11850
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011851 /* FreeBSD sendfile() constants */
11852#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011853 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011854#endif
11855#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011856 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011857#endif
11858#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011859 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011860#endif
11861
Ross Lagerwall7807c352011-03-17 20:20:30 +020011862 /* constants for posix_fadvise */
11863#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011864 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011865#endif
11866#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011867 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011868#endif
11869#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011870 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011871#endif
11872#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011873 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011874#endif
11875#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011876 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011877#endif
11878#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011879 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011880#endif
11881
11882 /* constants for waitid */
11883#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011884 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11885 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11886 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011887#endif
11888#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011889 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011890#endif
11891#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011892 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011893#endif
11894#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011895 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011896#endif
11897#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011898 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011899#endif
11900#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011901 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011902#endif
11903#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011904 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011905#endif
11906#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011907 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011908#endif
11909
11910 /* constants for lockf */
11911#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011912 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011913#endif
11914#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011915 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011916#endif
11917#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011918 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011919#endif
11920#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011921 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011922#endif
11923
Guido van Rossum246bc171999-02-01 23:54:31 +000011924#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011925 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11926 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11927 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11928 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11929 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011930#endif
11931
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011932#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011933 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11934 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11935 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011936#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011937 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011938#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011939#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011940 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011941#endif
11942#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011943 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011944#endif
11945#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011946 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011947#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011948#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011949 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011950#endif
11951#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011952 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011953#endif
11954#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011955 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011956#endif
11957#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011958 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011959#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011960#endif
11961
Benjamin Peterson9428d532011-09-14 11:45:52 -040011962#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011963 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11964 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11965 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011966#endif
11967
Victor Stinner8b905bd2011-10-25 13:34:04 +020011968#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011969 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011970#endif
11971#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011972 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011973#endif
11974#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011975 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011976#endif
11977#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011979#endif
11980#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011982#endif
11983#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011985#endif
11986#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011988#endif
11989
Victor Stinner8c62be82010-05-06 00:08:46 +000011990 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011991}
11992
11993
Tim Peters5aa91602002-01-30 05:46:57 +000011994#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011995#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011996#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011997
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011998#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011999#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012000#define MODNAME "posix"
12001#endif
12002
Martin v. Löwis1a214512008-06-11 05:26:20 +000012003static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012004 PyModuleDef_HEAD_INIT,
12005 MODNAME,
12006 posix__doc__,
12007 -1,
12008 posix_methods,
12009 NULL,
12010 NULL,
12011 NULL,
12012 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012013};
12014
12015
Larry Hastings9cf065c2012-06-22 16:30:09 -070012016static char *have_functions[] = {
12017
12018#ifdef HAVE_FACCESSAT
12019 "HAVE_FACCESSAT",
12020#endif
12021
12022#ifdef HAVE_FCHDIR
12023 "HAVE_FCHDIR",
12024#endif
12025
12026#ifdef HAVE_FCHMOD
12027 "HAVE_FCHMOD",
12028#endif
12029
12030#ifdef HAVE_FCHMODAT
12031 "HAVE_FCHMODAT",
12032#endif
12033
12034#ifdef HAVE_FCHOWN
12035 "HAVE_FCHOWN",
12036#endif
12037
Larry Hastings00964ed2013-08-12 13:49:30 -040012038#ifdef HAVE_FCHOWNAT
12039 "HAVE_FCHOWNAT",
12040#endif
12041
Larry Hastings9cf065c2012-06-22 16:30:09 -070012042#ifdef HAVE_FEXECVE
12043 "HAVE_FEXECVE",
12044#endif
12045
12046#ifdef HAVE_FDOPENDIR
12047 "HAVE_FDOPENDIR",
12048#endif
12049
Georg Brandl306336b2012-06-24 12:55:33 +020012050#ifdef HAVE_FPATHCONF
12051 "HAVE_FPATHCONF",
12052#endif
12053
Larry Hastings9cf065c2012-06-22 16:30:09 -070012054#ifdef HAVE_FSTATAT
12055 "HAVE_FSTATAT",
12056#endif
12057
12058#ifdef HAVE_FSTATVFS
12059 "HAVE_FSTATVFS",
12060#endif
12061
Georg Brandl306336b2012-06-24 12:55:33 +020012062#ifdef HAVE_FTRUNCATE
12063 "HAVE_FTRUNCATE",
12064#endif
12065
Larry Hastings9cf065c2012-06-22 16:30:09 -070012066#ifdef HAVE_FUTIMENS
12067 "HAVE_FUTIMENS",
12068#endif
12069
12070#ifdef HAVE_FUTIMES
12071 "HAVE_FUTIMES",
12072#endif
12073
12074#ifdef HAVE_FUTIMESAT
12075 "HAVE_FUTIMESAT",
12076#endif
12077
12078#ifdef HAVE_LINKAT
12079 "HAVE_LINKAT",
12080#endif
12081
12082#ifdef HAVE_LCHFLAGS
12083 "HAVE_LCHFLAGS",
12084#endif
12085
12086#ifdef HAVE_LCHMOD
12087 "HAVE_LCHMOD",
12088#endif
12089
12090#ifdef HAVE_LCHOWN
12091 "HAVE_LCHOWN",
12092#endif
12093
12094#ifdef HAVE_LSTAT
12095 "HAVE_LSTAT",
12096#endif
12097
12098#ifdef HAVE_LUTIMES
12099 "HAVE_LUTIMES",
12100#endif
12101
12102#ifdef HAVE_MKDIRAT
12103 "HAVE_MKDIRAT",
12104#endif
12105
12106#ifdef HAVE_MKFIFOAT
12107 "HAVE_MKFIFOAT",
12108#endif
12109
12110#ifdef HAVE_MKNODAT
12111 "HAVE_MKNODAT",
12112#endif
12113
12114#ifdef HAVE_OPENAT
12115 "HAVE_OPENAT",
12116#endif
12117
12118#ifdef HAVE_READLINKAT
12119 "HAVE_READLINKAT",
12120#endif
12121
12122#ifdef HAVE_RENAMEAT
12123 "HAVE_RENAMEAT",
12124#endif
12125
12126#ifdef HAVE_SYMLINKAT
12127 "HAVE_SYMLINKAT",
12128#endif
12129
12130#ifdef HAVE_UNLINKAT
12131 "HAVE_UNLINKAT",
12132#endif
12133
12134#ifdef HAVE_UTIMENSAT
12135 "HAVE_UTIMENSAT",
12136#endif
12137
12138#ifdef MS_WINDOWS
12139 "MS_WINDOWS",
12140#endif
12141
12142 NULL
12143};
12144
12145
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012146PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012147INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012148{
Victor Stinner8c62be82010-05-06 00:08:46 +000012149 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012150 PyObject *list;
12151 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012152
Brian Curtin52173d42010-12-02 18:29:18 +000012153#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012154 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012155#endif
12156
Victor Stinner8c62be82010-05-06 00:08:46 +000012157 m = PyModule_Create(&posixmodule);
12158 if (m == NULL)
12159 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012160
Victor Stinner8c62be82010-05-06 00:08:46 +000012161 /* Initialize environ dictionary */
12162 v = convertenviron();
12163 Py_XINCREF(v);
12164 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12165 return NULL;
12166 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012167
Victor Stinner8c62be82010-05-06 00:08:46 +000012168 if (all_ins(m))
12169 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012170
Victor Stinner8c62be82010-05-06 00:08:46 +000012171 if (setup_confname_tables(m))
12172 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012173
Victor Stinner8c62be82010-05-06 00:08:46 +000012174 Py_INCREF(PyExc_OSError);
12175 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012176
Guido van Rossumb3d39562000-01-31 18:41:26 +000012177#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012178 if (posix_putenv_garbage == NULL)
12179 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012180#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012181
Victor Stinner8c62be82010-05-06 00:08:46 +000012182 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012183#if defined(HAVE_WAITID) && !defined(__APPLE__)
12184 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012185 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12186 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012187#endif
12188
Christian Heimes25827622013-10-12 01:27:08 +020012189 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012190 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12191 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12192 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012193 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12194 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012195 structseq_new = StatResultType.tp_new;
12196 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012197
Christian Heimes25827622013-10-12 01:27:08 +020012198 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012199 if (PyStructSequence_InitType2(&StatVFSResultType,
12200 &statvfs_result_desc) < 0)
12201 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012202#ifdef NEED_TICKS_PER_SECOND
12203# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012204 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012205# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012206 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012207# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012208 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012209# endif
12210#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012211
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012212#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012213 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012214 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12215 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012216 SchedParamType.tp_new = sched_param_new;
12217#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012218
12219 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012220 if (PyStructSequence_InitType2(&TerminalSizeType,
12221 &TerminalSize_desc) < 0)
12222 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012223 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012224#if defined(HAVE_WAITID) && !defined(__APPLE__)
12225 Py_INCREF((PyObject*) &WaitidResultType);
12226 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12227#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012228 Py_INCREF((PyObject*) &StatResultType);
12229 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12230 Py_INCREF((PyObject*) &StatVFSResultType);
12231 PyModule_AddObject(m, "statvfs_result",
12232 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012233
12234#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012235 Py_INCREF(&SchedParamType);
12236 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012237#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012238
Larry Hastings605a62d2012-06-24 04:33:36 -070012239 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012240 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12241 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012242 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12243
12244 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012245 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12246 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012247 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12248
Thomas Wouters477c8d52006-05-27 19:21:47 +000012249#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012250 /*
12251 * Step 2 of weak-linking support on Mac OS X.
12252 *
12253 * The code below removes functions that are not available on the
12254 * currently active platform.
12255 *
12256 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012257 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012258 * OSX 10.4.
12259 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012260#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012261 if (fstatvfs == NULL) {
12262 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12263 return NULL;
12264 }
12265 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012266#endif /* HAVE_FSTATVFS */
12267
12268#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012269 if (statvfs == NULL) {
12270 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12271 return NULL;
12272 }
12273 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012274#endif /* HAVE_STATVFS */
12275
12276# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012277 if (lchown == NULL) {
12278 if (PyObject_DelAttrString(m, "lchown") == -1) {
12279 return NULL;
12280 }
12281 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012282#endif /* HAVE_LCHOWN */
12283
12284
12285#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012286
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012287 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012288 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12289
Larry Hastings6fe20b32012-04-19 15:07:49 -070012290 billion = PyLong_FromLong(1000000000);
12291 if (!billion)
12292 return NULL;
12293
Larry Hastings9cf065c2012-06-22 16:30:09 -070012294 /* suppress "function not used" warnings */
12295 {
12296 int ignored;
12297 fd_specified("", -1);
12298 follow_symlinks_specified("", 1);
12299 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12300 dir_fd_converter(Py_None, &ignored);
12301 dir_fd_unavailable(Py_None, &ignored);
12302 }
12303
12304 /*
12305 * provide list of locally available functions
12306 * so os.py can populate support_* lists
12307 */
12308 list = PyList_New(0);
12309 if (!list)
12310 return NULL;
12311 for (trace = have_functions; *trace; trace++) {
12312 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12313 if (!unicode)
12314 return NULL;
12315 if (PyList_Append(list, unicode))
12316 return NULL;
12317 Py_DECREF(unicode);
12318 }
12319 PyModule_AddObject(m, "_have_functions", list);
12320
12321 initialized = 1;
12322
Victor Stinner8c62be82010-05-06 00:08:46 +000012323 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012324}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012325
12326#ifdef __cplusplus
12327}
12328#endif