blob: 789bf27bc4d151b5f99ab5e71573664693e9bd68 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020028#ifndef MS_WINDOWS
29#include "posixmodule.h"
30#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020033# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Ross Lagerwall4d076da2011-03-18 06:56:53 +020048#ifdef HAVE_SYS_UIO_H
49#include <sys/uio.h>
50#endif
51
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054#endif /* HAVE_SYS_TYPES_H */
55
56#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000057#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000059
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000061#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000062#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000065#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000067
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#ifdef HAVE_FCNTL_H
69#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000070#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000071
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072#ifdef HAVE_GRP_H
73#include <grp.h>
74#endif
75
Barry Warsaw5676bd12003-01-07 20:57:09 +000076#ifdef HAVE_SYSEXITS_H
77#include <sysexits.h>
78#endif /* HAVE_SYSEXITS_H */
79
Anthony Baxter8a560de2004-10-13 15:30:56 +000080#ifdef HAVE_SYS_LOADAVG_H
81#include <sys/loadavg.h>
82#endif
83
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000084#ifdef HAVE_LANGINFO_H
85#include <langinfo.h>
86#endif
87
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000088#ifdef HAVE_SYS_SENDFILE_H
89#include <sys/sendfile.h>
90#endif
91
Benjamin Peterson94b580d2011-08-02 17:30:04 -050092#ifdef HAVE_SCHED_H
93#include <sched.h>
94#endif
95
Benjamin Peterson2dbda072012-03-16 10:12:55 -050096#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050097#undef HAVE_SCHED_SETAFFINITY
98#endif
99
Benjamin Peterson9428d532011-09-14 11:45:52 -0400100#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
101#define USE_XATTRS
102#endif
103
104#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400105#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
109#ifdef HAVE_SYS_SOCKET_H
110#include <sys/socket.h>
111#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#endif
113
Victor Stinner8b905bd2011-10-25 13:34:04 +0200114#ifdef HAVE_DLFCN_H
115#include <dlfcn.h>
116#endif
117
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200118#ifdef __hpux
119#include <sys/mpctl.h>
120#endif
121
122#if defined(__DragonFly__) || \
123 defined(__OpenBSD__) || \
124 defined(__FreeBSD__) || \
125 defined(__NetBSD__) || \
126 defined(__APPLE__)
127#include <sys/sysctl.h>
128#endif
129
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100130#if defined(MS_WINDOWS)
131# define TERMSIZE_USE_CONIO
132#elif defined(HAVE_SYS_IOCTL_H)
133# include <sys/ioctl.h>
134# if defined(HAVE_TERMIOS_H)
135# include <termios.h>
136# endif
137# if defined(TIOCGWINSZ)
138# define TERMSIZE_USE_IOCTL
139# endif
140#endif /* MS_WINDOWS */
141
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000143/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000146#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_OPENDIR 1
152#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_WAIT 1
155#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000156#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000157#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000158#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#define HAVE_SYSTEM 1
163#define HAVE_CWAIT 1
164#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000165#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000166#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200167#if defined(__VMS)
168/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170/* Unix functions that the configure script doesn't check for */
171#define HAVE_EXECV 1
172#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000173#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000174#define HAVE_FORK1 1
175#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#define HAVE_GETEGID 1
177#define HAVE_GETEUID 1
178#define HAVE_GETGID 1
179#define HAVE_GETPPID 1
180#define HAVE_GETUID 1
181#define HAVE_KILL 1
182#define HAVE_OPENDIR 1
183#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000186#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200187#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#endif /* _MSC_VER */
189#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000190#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000191
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
193
194
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000196
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000197#if defined(__sgi)&&_COMPILER_VERSION>=700
198/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
199 (default) */
200extern char *ctermid_r(char *);
201#endif
202
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000203#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000207#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000212#endif
213#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int chdir(char *);
215extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chdir(const char *);
218extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000220#ifdef __BORLANDC__
221extern int chmod(const char *, int);
222#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000223extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000224#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000225/*#ifdef HAVE_FCHMOD
226extern int fchmod(int, mode_t);
227#endif*/
228/*#ifdef HAVE_LCHMOD
229extern int lchmod(const char *, mode_t);
230#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chown(const char *, uid_t, gid_t);
232extern char *getcwd(char *, int);
233extern char *strerror(int);
234extern int link(const char *, const char *);
235extern int rename(const char *, const char *);
236extern int stat(const char *, struct stat *);
237extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000239extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000240#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000243#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000245
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_UTIME_H
249#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000252#ifdef HAVE_SYS_UTIME_H
253#include <sys/utime.h>
254#define HAVE_UTIME_H /* pretend we do for the rest of this file */
255#endif /* HAVE_SYS_UTIME_H */
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_SYS_TIMES_H
258#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_PARAM_H
262#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_UTSNAME_H
266#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#include <direct.h>
275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
295#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
304#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000311#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000312#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000313#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000314#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000315#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
316#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000317static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000318#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000319#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000322#if defined(PATH_MAX) && PATH_MAX > 1024
323#define MAXPATHLEN PATH_MAX
324#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#endif /* MAXPATHLEN */
328
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000329#ifdef UNION_WAIT
330/* Emulate some macros on systems that have a union instead of macros */
331
332#ifndef WIFEXITED
333#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
334#endif
335
336#ifndef WEXITSTATUS
337#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
338#endif
339
340#ifndef WTERMSIG
341#define WTERMSIG(u_wait) ((u_wait).w_termsig)
342#endif
343
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000344#define WAIT_TYPE union wait
345#define WAIT_STATUS_INT(s) (s.w_status)
346
347#else /* !UNION_WAIT */
348#define WAIT_TYPE int
349#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000350#endif /* UNION_WAIT */
351
Greg Wardb48bc172000-03-01 21:51:56 +0000352/* Don't use the "_r" form if we don't need it (also, won't have a
353 prototype for it, at least on Solaris -- maybe others as well?). */
354#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
355#define USE_CTERMID_R
356#endif
357
Fred Drake699f3522000-06-29 21:12:41 +0000358/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000359#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000360#undef FSTAT
361#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200362#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000363# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700364# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define FSTAT win32_fstat
366# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000367#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700369# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000370# define FSTAT fstat
371# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000372#endif
373
Tim Peters11b23062003-04-23 02:39:17 +0000374#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000375#include <sys/mkdev.h>
376#else
377#if defined(MAJOR_IN_SYSMACROS)
378#include <sys/sysmacros.h>
379#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000380#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
381#include <sys/mkdev.h>
382#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#endif
Fred Drake699f3522000-06-29 21:12:41 +0000384
Larry Hastings9cf065c2012-06-22 16:30:09 -0700385
386#ifdef MS_WINDOWS
387static int
388win32_warn_bytes_api()
389{
390 return PyErr_WarnEx(PyExc_DeprecationWarning,
391 "The Windows bytes API has been deprecated, "
392 "use Unicode filenames instead",
393 1);
394}
395#endif
396
397
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200398#ifndef MS_WINDOWS
399PyObject *
400_PyLong_FromUid(uid_t uid)
401{
402 if (uid == (uid_t)-1)
403 return PyLong_FromLong(-1);
404 return PyLong_FromUnsignedLong(uid);
405}
406
407PyObject *
408_PyLong_FromGid(gid_t gid)
409{
410 if (gid == (gid_t)-1)
411 return PyLong_FromLong(-1);
412 return PyLong_FromUnsignedLong(gid);
413}
414
415int
416_Py_Uid_Converter(PyObject *obj, void *p)
417{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 uid_t uid;
419 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200421 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700422 unsigned long uresult;
423
424 index = PyNumber_Index(obj);
425 if (index == NULL) {
426 PyErr_Format(PyExc_TypeError,
427 "uid should be integer, not %.200s",
428 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200429 return 0;
430 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700431
432 /*
433 * Handling uid_t is complicated for two reasons:
434 * * Although uid_t is (always?) unsigned, it still
435 * accepts -1.
436 * * We don't know its size in advance--it may be
437 * bigger than an int, or it may be smaller than
438 * a long.
439 *
440 * So a bit of defensive programming is in order.
441 * Start with interpreting the value passed
442 * in as a signed long and see if it works.
443 */
444
445 result = PyLong_AsLongAndOverflow(index, &overflow);
446
447 if (!overflow) {
448 uid = (uid_t)result;
449
450 if (result == -1) {
451 if (PyErr_Occurred())
452 goto fail;
453 /* It's a legitimate -1, we're done. */
454 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200455 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700456
457 /* Any other negative number is disallowed. */
458 if (result < 0)
459 goto underflow;
460
461 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463 (long)uid != result)
464 goto underflow;
465 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200466 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700467
468 if (overflow < 0)
469 goto underflow;
470
471 /*
472 * Okay, the value overflowed a signed long. If it
473 * fits in an *unsigned* long, it may still be okay,
474 * as uid_t may be unsigned long on this platform.
475 */
476 uresult = PyLong_AsUnsignedLong(index);
477 if (PyErr_Occurred()) {
478 if (PyErr_ExceptionMatches(PyExc_OverflowError))
479 goto overflow;
480 goto fail;
481 }
482
483 uid = (uid_t)uresult;
484
485 /*
486 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
487 * but this value would get interpreted as (uid_t)-1 by chown
488 * and its siblings. That's not what the user meant! So we
489 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100490 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700491 */
492 if (uid == (uid_t)-1)
493 goto overflow;
494
495 /* Ensure the value wasn't truncated. */
496 if (sizeof(uid_t) < sizeof(long) &&
497 (unsigned long)uid != uresult)
498 goto overflow;
499 /* fallthrough */
500
501success:
502 Py_DECREF(index);
503 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200504 return 1;
505
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700506underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200507 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700508 "uid is less than minimum");
509 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is greater than maximum");
514 /* fallthrough */
515
516fail:
517 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200518 return 0;
519}
520
521int
522_Py_Gid_Converter(PyObject *obj, void *p)
523{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 gid_t gid;
525 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200527 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 unsigned long uresult;
529
530 index = PyNumber_Index(obj);
531 if (index == NULL) {
532 PyErr_Format(PyExc_TypeError,
533 "gid should be integer, not %.200s",
534 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200535 return 0;
536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /*
539 * Handling gid_t is complicated for two reasons:
540 * * Although gid_t is (always?) unsigned, it still
541 * accepts -1.
542 * * We don't know its size in advance--it may be
543 * bigger than an int, or it may be smaller than
544 * a long.
545 *
546 * So a bit of defensive programming is in order.
547 * Start with interpreting the value passed
548 * in as a signed long and see if it works.
549 */
550
551 result = PyLong_AsLongAndOverflow(index, &overflow);
552
553 if (!overflow) {
554 gid = (gid_t)result;
555
556 if (result == -1) {
557 if (PyErr_Occurred())
558 goto fail;
559 /* It's a legitimate -1, we're done. */
560 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200561 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562
563 /* Any other negative number is disallowed. */
564 if (result < 0) {
565 goto underflow;
566 }
567
568 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570 (long)gid != result)
571 goto underflow;
572 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200573 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700574
575 if (overflow < 0)
576 goto underflow;
577
578 /*
579 * Okay, the value overflowed a signed long. If it
580 * fits in an *unsigned* long, it may still be okay,
581 * as gid_t may be unsigned long on this platform.
582 */
583 uresult = PyLong_AsUnsignedLong(index);
584 if (PyErr_Occurred()) {
585 if (PyErr_ExceptionMatches(PyExc_OverflowError))
586 goto overflow;
587 goto fail;
588 }
589
590 gid = (gid_t)uresult;
591
592 /*
593 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
594 * but this value would get interpreted as (gid_t)-1 by chown
595 * and its siblings. That's not what the user meant! So we
596 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100597 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700598 */
599 if (gid == (gid_t)-1)
600 goto overflow;
601
602 /* Ensure the value wasn't truncated. */
603 if (sizeof(gid_t) < sizeof(long) &&
604 (unsigned long)gid != uresult)
605 goto overflow;
606 /* fallthrough */
607
608success:
609 Py_DECREF(index);
610 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200611 return 1;
612
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615 "gid is less than minimum");
616 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is greater than maximum");
621 /* fallthrough */
622
623fail:
624 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200625 return 0;
626}
627#endif /* MS_WINDOWS */
628
629
Larry Hastings9cf065c2012-06-22 16:30:09 -0700630#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400631/*
632 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
633 * without the int cast, the value gets interpreted as uint (4291925331),
634 * which doesn't play nicely with all the initializer lines in this file that
635 * look like this:
636 * int dir_fd = DEFAULT_DIR_FD;
637 */
638#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700639#else
640#define DEFAULT_DIR_FD (-100)
641#endif
642
643static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200644_fd_converter(PyObject *o, int *p, const char *allowed)
645{
646 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647 long long_value;
648
649 PyObject *index = PyNumber_Index(o);
650 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200651 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652 "argument should be %s, not %.200s",
653 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700654 return 0;
655 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700656
657 long_value = PyLong_AsLongAndOverflow(index, &overflow);
658 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200659 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700661 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700662 return 0;
663 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200664 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700665 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667 return 0;
668 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700669
Larry Hastings9cf065c2012-06-22 16:30:09 -0700670 *p = (int)long_value;
671 return 1;
672}
673
674static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200675dir_fd_converter(PyObject *o, void *p)
676{
677 if (o == Py_None) {
678 *(int *)p = DEFAULT_DIR_FD;
679 return 1;
680 }
681 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682}
683
684
685
686/*
687 * A PyArg_ParseTuple "converter" function
688 * that handles filesystem paths in the manner
689 * preferred by the os module.
690 *
691 * path_converter accepts (Unicode) strings and their
692 * subclasses, and bytes and their subclasses. What
693 * it does with the argument depends on the platform:
694 *
695 * * On Windows, if we get a (Unicode) string we
696 * extract the wchar_t * and return it; if we get
697 * bytes we extract the char * and return that.
698 *
699 * * On all other platforms, strings are encoded
700 * to bytes using PyUnicode_FSConverter, then we
701 * extract the char * from the bytes object and
702 * return that.
703 *
704 * path_converter also optionally accepts signed
705 * integers (representing open file descriptors) instead
706 * of path strings.
707 *
708 * Input fields:
709 * path.nullable
710 * If nonzero, the path is permitted to be None.
711 * path.allow_fd
712 * If nonzero, the path is permitted to be a file handle
713 * (a signed int) instead of a string.
714 * path.function_name
715 * If non-NULL, path_converter will use that as the name
716 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700717 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700718 * path.argument_name
719 * If non-NULL, path_converter will use that as the name
720 * of the parameter in error messages.
721 * (If path.argument_name is NULL it uses "path".)
722 *
723 * Output fields:
724 * path.wide
725 * Points to the path if it was expressed as Unicode
726 * and was not encoded. (Only used on Windows.)
727 * path.narrow
728 * Points to the path if it was expressed as bytes,
729 * or it was Unicode and was encoded to bytes.
730 * path.fd
731 * Contains a file descriptor if path.accept_fd was true
732 * and the caller provided a signed integer instead of any
733 * sort of string.
734 *
735 * WARNING: if your "path" parameter is optional, and is
736 * unspecified, path_converter will never get called.
737 * So if you set allow_fd, you *MUST* initialize path.fd = -1
738 * yourself!
739 * path.length
740 * The length of the path in characters, if specified as
741 * a string.
742 * path.object
743 * The original object passed in.
744 * path.cleanup
745 * For internal use only. May point to a temporary object.
746 * (Pay no attention to the man behind the curtain.)
747 *
748 * At most one of path.wide or path.narrow will be non-NULL.
749 * If path was None and path.nullable was set,
750 * or if path was an integer and path.allow_fd was set,
751 * both path.wide and path.narrow will be NULL
752 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200753 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700754 * path_converter takes care to not write to the path_t
755 * unless it's successful. However it must reset the
756 * "cleanup" field each time it's called.
757 *
758 * Use as follows:
759 * path_t path;
760 * memset(&path, 0, sizeof(path));
761 * PyArg_ParseTuple(args, "O&", path_converter, &path);
762 * // ... use values from path ...
763 * path_cleanup(&path);
764 *
765 * (Note that if PyArg_Parse fails you don't need to call
766 * path_cleanup(). However it is safe to do so.)
767 */
768typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100769 const char *function_name;
770 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700771 int nullable;
772 int allow_fd;
773 wchar_t *wide;
774 char *narrow;
775 int fd;
776 Py_ssize_t length;
777 PyObject *object;
778 PyObject *cleanup;
779} path_t;
780
Larry Hastings31826802013-10-19 00:09:25 -0700781#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
782 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
783
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784static void
785path_cleanup(path_t *path) {
786 if (path->cleanup) {
787 Py_DECREF(path->cleanup);
788 path->cleanup = NULL;
789 }
790}
791
792static int
793path_converter(PyObject *o, void *p) {
794 path_t *path = (path_t *)p;
795 PyObject *unicode, *bytes;
796 Py_ssize_t length;
797 char *narrow;
798
799#define FORMAT_EXCEPTION(exc, fmt) \
800 PyErr_Format(exc, "%s%s" fmt, \
801 path->function_name ? path->function_name : "", \
802 path->function_name ? ": " : "", \
803 path->argument_name ? path->argument_name : "path")
804
805 /* Py_CLEANUP_SUPPORTED support */
806 if (o == NULL) {
807 path_cleanup(path);
808 return 1;
809 }
810
811 /* ensure it's always safe to call path_cleanup() */
812 path->cleanup = NULL;
813
814 if (o == Py_None) {
815 if (!path->nullable) {
816 FORMAT_EXCEPTION(PyExc_TypeError,
817 "can't specify None for %s argument");
818 return 0;
819 }
820 path->wide = NULL;
821 path->narrow = NULL;
822 path->length = 0;
823 path->object = o;
824 path->fd = -1;
825 return 1;
826 }
827
828 unicode = PyUnicode_FromObject(o);
829 if (unicode) {
830#ifdef MS_WINDOWS
831 wchar_t *wide;
832 length = PyUnicode_GET_SIZE(unicode);
833 if (length > 32767) {
834 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
835 Py_DECREF(unicode);
836 return 0;
837 }
838
839 wide = PyUnicode_AsUnicode(unicode);
840 if (!wide) {
841 Py_DECREF(unicode);
842 return 0;
843 }
844
845 path->wide = wide;
846 path->narrow = NULL;
847 path->length = length;
848 path->object = o;
849 path->fd = -1;
850 path->cleanup = unicode;
851 return Py_CLEANUP_SUPPORTED;
852#else
853 int converted = PyUnicode_FSConverter(unicode, &bytes);
854 Py_DECREF(unicode);
855 if (!converted)
856 bytes = NULL;
857#endif
858 }
859 else {
860 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200861 if (PyObject_CheckBuffer(o))
862 bytes = PyBytes_FromObject(o);
863 else
864 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700865 if (!bytes) {
866 PyErr_Clear();
867 if (path->allow_fd) {
868 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200869 int result = _fd_converter(o, &fd,
870 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 if (result) {
872 path->wide = NULL;
873 path->narrow = NULL;
874 path->length = 0;
875 path->object = o;
876 path->fd = fd;
877 return result;
878 }
879 }
880 }
881 }
882
883 if (!bytes) {
884 if (!PyErr_Occurred())
885 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
886 return 0;
887 }
888
889#ifdef MS_WINDOWS
890 if (win32_warn_bytes_api()) {
891 Py_DECREF(bytes);
892 return 0;
893 }
894#endif
895
896 length = PyBytes_GET_SIZE(bytes);
897#ifdef MS_WINDOWS
898 if (length > MAX_PATH) {
899 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
900 Py_DECREF(bytes);
901 return 0;
902 }
903#endif
904
905 narrow = PyBytes_AS_STRING(bytes);
906 if (length != strlen(narrow)) {
907 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
908 Py_DECREF(bytes);
909 return 0;
910 }
911
912 path->wide = NULL;
913 path->narrow = narrow;
914 path->length = length;
915 path->object = o;
916 path->fd = -1;
917 path->cleanup = bytes;
918 return Py_CLEANUP_SUPPORTED;
919}
920
921static void
922argument_unavailable_error(char *function_name, char *argument_name) {
923 PyErr_Format(PyExc_NotImplementedError,
924 "%s%s%s unavailable on this platform",
925 (function_name != NULL) ? function_name : "",
926 (function_name != NULL) ? ": ": "",
927 argument_name);
928}
929
930static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200931dir_fd_unavailable(PyObject *o, void *p)
932{
933 int dir_fd;
934 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200936 if (dir_fd != DEFAULT_DIR_FD) {
937 argument_unavailable_error(NULL, "dir_fd");
938 return 0;
939 }
940 *(int *)p = dir_fd;
941 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942}
943
944static int
945fd_specified(char *function_name, int fd) {
946 if (fd == -1)
947 return 0;
948
949 argument_unavailable_error(function_name, "fd");
950 return 1;
951}
952
953static int
954follow_symlinks_specified(char *function_name, int follow_symlinks) {
955 if (follow_symlinks)
956 return 0;
957
958 argument_unavailable_error(function_name, "follow_symlinks");
959 return 1;
960}
961
962static int
963path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
964 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
965 PyErr_Format(PyExc_ValueError,
966 "%s: can't specify dir_fd without matching path",
967 function_name);
968 return 1;
969 }
970 return 0;
971}
972
973static int
974dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
975 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
976 PyErr_Format(PyExc_ValueError,
977 "%s: can't specify both dir_fd and fd",
978 function_name);
979 return 1;
980 }
981 return 0;
982}
983
984static int
985fd_and_follow_symlinks_invalid(char *function_name, int fd,
986 int follow_symlinks) {
987 if ((fd > 0) && (!follow_symlinks)) {
988 PyErr_Format(PyExc_ValueError,
989 "%s: cannot use fd and follow_symlinks together",
990 function_name);
991 return 1;
992 }
993 return 0;
994}
995
996static int
997dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
998 int follow_symlinks) {
999 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1000 PyErr_Format(PyExc_ValueError,
1001 "%s: cannot use dir_fd and follow_symlinks together",
1002 function_name);
1003 return 1;
1004 }
1005 return 0;
1006}
1007
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001008/* A helper used by a number of POSIX-only functions */
1009#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001010static int
1011_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001012{
1013#if !defined(HAVE_LARGEFILE_SUPPORT)
1014 *((off_t*)addr) = PyLong_AsLong(arg);
1015#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001016 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001017#endif
1018 if (PyErr_Occurred())
1019 return 0;
1020 return 1;
1021}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001022#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001023
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001024#if defined _MSC_VER && _MSC_VER >= 1400
1025/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001026 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001027 * Normally, an invalid fd is likely to be a C program error and therefore
1028 * an assertion can be useful, but it does contradict the POSIX standard
1029 * which for write(2) states:
1030 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1031 * "[EBADF] The fildes argument is not a valid file descriptor open for
1032 * writing."
1033 * Furthermore, python allows the user to enter any old integer
1034 * as a fd and should merely raise a python exception on error.
1035 * The Microsoft CRT doesn't provide an official way to check for the
1036 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001038 * internal structures involved.
1039 * The structures below must be updated for each version of visual studio
1040 * according to the file internal.h in the CRT source, until MS comes
1041 * up with a less hacky way to do this.
1042 * (all of this is to avoid globally modifying the CRT behaviour using
1043 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1044 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001045/* The actual size of the structure is determined at runtime.
1046 * Only the first items must be present.
1047 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001048typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001049 intptr_t osfhnd;
1050 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001051} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001052
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001053extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001054#define IOINFO_L2E 5
1055#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1056#define IOINFO_ARRAYS 64
1057#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1058#define FOPEN 0x01
1059#define _NO_CONSOLE_FILENO (intptr_t)-2
1060
1061/* This function emulates what the windows CRT does to validate file handles */
1062int
1063_PyVerify_fd(int fd)
1064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 const int i1 = fd >> IOINFO_L2E;
1066 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001067
Antoine Pitrou22e41552010-08-15 18:07:50 +00001068 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001069
Victor Stinner8c62be82010-05-06 00:08:46 +00001070 /* Determine the actual size of the ioinfo structure,
1071 * as used by the CRT loaded in memory
1072 */
1073 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1074 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1075 }
1076 if (sizeof_ioinfo == 0) {
1077 /* This should not happen... */
1078 goto fail;
1079 }
1080
1081 /* See that it isn't a special CLEAR fileno */
1082 if (fd != _NO_CONSOLE_FILENO) {
1083 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1084 * we check pointer validity and other info
1085 */
1086 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1087 /* finally, check that the file is open */
1088 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1089 if (info->osfile & FOPEN) {
1090 return 1;
1091 }
1092 }
1093 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001094 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 errno = EBADF;
1096 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001097}
1098
1099/* the special case of checking dup2. The target fd must be in a sensible range */
1100static int
1101_PyVerify_fd_dup2(int fd1, int fd2)
1102{
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 if (!_PyVerify_fd(fd1))
1104 return 0;
1105 if (fd2 == _NO_CONSOLE_FILENO)
1106 return 0;
1107 if ((unsigned)fd2 < _NHANDLE_)
1108 return 1;
1109 else
1110 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001111}
1112#else
1113/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1114#define _PyVerify_fd_dup2(A, B) (1)
1115#endif
1116
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001117#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001118/* The following structure was copied from
1119 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1120 include doesn't seem to be present in the Windows SDK (at least as included
1121 with Visual Studio Express). */
1122typedef struct _REPARSE_DATA_BUFFER {
1123 ULONG ReparseTag;
1124 USHORT ReparseDataLength;
1125 USHORT Reserved;
1126 union {
1127 struct {
1128 USHORT SubstituteNameOffset;
1129 USHORT SubstituteNameLength;
1130 USHORT PrintNameOffset;
1131 USHORT PrintNameLength;
1132 ULONG Flags;
1133 WCHAR PathBuffer[1];
1134 } SymbolicLinkReparseBuffer;
1135
1136 struct {
1137 USHORT SubstituteNameOffset;
1138 USHORT SubstituteNameLength;
1139 USHORT PrintNameOffset;
1140 USHORT PrintNameLength;
1141 WCHAR PathBuffer[1];
1142 } MountPointReparseBuffer;
1143
1144 struct {
1145 UCHAR DataBuffer[1];
1146 } GenericReparseBuffer;
1147 };
1148} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1149
1150#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1151 GenericReparseBuffer)
1152#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1153
1154static int
Brian Curtind25aef52011-06-13 15:16:04 -05001155win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001156{
1157 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1158 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1159 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001160
1161 if (0 == DeviceIoControl(
1162 reparse_point_handle,
1163 FSCTL_GET_REPARSE_POINT,
1164 NULL, 0, /* in buffer */
1165 target_buffer, sizeof(target_buffer),
1166 &n_bytes_returned,
1167 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001168 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169
1170 if (reparse_tag)
1171 *reparse_tag = rdb->ReparseTag;
1172
Brian Curtind25aef52011-06-13 15:16:04 -05001173 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001174}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001175
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001176#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001179#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001180/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001181** environ directly, we must obtain it with _NSGetEnviron(). See also
1182** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001183*/
1184#include <crt_externs.h>
1185static char **environ;
1186#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001188#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189
Barry Warsaw53699e91996-12-10 23:23:01 +00001190static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001191convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001192{
Victor Stinner8c62be82010-05-06 00:08:46 +00001193 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001194#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001196#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001198#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001199
Victor Stinner8c62be82010-05-06 00:08:46 +00001200 d = PyDict_New();
1201 if (d == NULL)
1202 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001203#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 if (environ == NULL)
1205 environ = *_NSGetEnviron();
1206#endif
1207#ifdef MS_WINDOWS
1208 /* _wenviron must be initialized in this way if the program is started
1209 through main() instead of wmain(). */
1210 _wgetenv(L"");
1211 if (_wenviron == NULL)
1212 return d;
1213 /* This part ignores errors */
1214 for (e = _wenviron; *e != NULL; e++) {
1215 PyObject *k;
1216 PyObject *v;
1217 wchar_t *p = wcschr(*e, L'=');
1218 if (p == NULL)
1219 continue;
1220 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1221 if (k == NULL) {
1222 PyErr_Clear();
1223 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001224 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1226 if (v == NULL) {
1227 PyErr_Clear();
1228 Py_DECREF(k);
1229 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001230 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 if (PyDict_GetItem(d, k) == NULL) {
1232 if (PyDict_SetItem(d, k, v) != 0)
1233 PyErr_Clear();
1234 }
1235 Py_DECREF(k);
1236 Py_DECREF(v);
1237 }
1238#else
1239 if (environ == NULL)
1240 return d;
1241 /* This part ignores errors */
1242 for (e = environ; *e != NULL; e++) {
1243 PyObject *k;
1244 PyObject *v;
1245 char *p = strchr(*e, '=');
1246 if (p == NULL)
1247 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001248 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 if (k == NULL) {
1250 PyErr_Clear();
1251 continue;
1252 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001253 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 if (v == NULL) {
1255 PyErr_Clear();
1256 Py_DECREF(k);
1257 continue;
1258 }
1259 if (PyDict_GetItem(d, k) == NULL) {
1260 if (PyDict_SetItem(d, k, v) != 0)
1261 PyErr_Clear();
1262 }
1263 Py_DECREF(k);
1264 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001265 }
1266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001267 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001268}
1269
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001270/* Set a POSIX-specific error from errno, and return NULL */
1271
Barry Warsawd58d7641998-07-23 16:14:40 +00001272static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001273posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001274{
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001276}
Mark Hammondef8b6542001-05-13 08:04:26 +00001277
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001278#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001279static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001280win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001281{
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 /* XXX We should pass the function name along in the future.
1283 (winreg.c also wants to pass the function name.)
1284 This would however require an additional param to the
1285 Windows error object, which is non-trivial.
1286 */
1287 errno = GetLastError();
1288 if (filename)
1289 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1290 else
1291 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001292}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001293
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001294static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001295win32_error_object(char* function, PyObject* filename)
1296{
1297 /* XXX - see win32_error for comments on 'function' */
1298 errno = GetLastError();
1299 if (filename)
1300 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001301 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001302 errno,
1303 filename);
1304 else
1305 return PyErr_SetFromWindowsErr(errno);
1306}
1307
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001308#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309
Larry Hastings9cf065c2012-06-22 16:30:09 -07001310static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001311path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001312{
1313#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001314 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1315 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001316#else
Victor Stinner292c8352012-10-30 02:17:38 +01001317 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001318#endif
1319}
1320
Larry Hastings31826802013-10-19 00:09:25 -07001321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322/* POSIX generic methods */
1323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001325posix_fildes(PyObject *fdobj, int (*func)(int))
1326{
Victor Stinner8c62be82010-05-06 00:08:46 +00001327 int fd;
1328 int res;
1329 fd = PyObject_AsFileDescriptor(fdobj);
1330 if (fd < 0)
1331 return NULL;
1332 if (!_PyVerify_fd(fd))
1333 return posix_error();
1334 Py_BEGIN_ALLOW_THREADS
1335 res = (*func)(fd);
1336 Py_END_ALLOW_THREADS
1337 if (res < 0)
1338 return posix_error();
1339 Py_INCREF(Py_None);
1340 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001341}
Guido van Rossum21142a01999-01-08 21:05:37 +00001342
1343static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001344posix_1str(const char *func_name, PyObject *args, char *format,
1345 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346{
Victor Stinner292c8352012-10-30 02:17:38 +01001347 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001349 memset(&path, 0, sizeof(path));
1350 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001352 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001355 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001357 if (res < 0) {
1358 path_error(&path);
1359 path_cleanup(&path);
1360 return NULL;
1361 }
1362 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 Py_INCREF(Py_None);
1364 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001367
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001368#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369/* This is a reimplementation of the C library's chdir function,
1370 but one that produces Win32 errors instead of DOS error codes.
1371 chdir is essentially a wrapper around SetCurrentDirectory; however,
1372 it also needs to set "magic" environment variables indicating
1373 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001374static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375win32_chdir(LPCSTR path)
1376{
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 char new_path[MAX_PATH+1];
1378 int result;
1379 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 if(!SetCurrentDirectoryA(path))
1382 return FALSE;
1383 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1384 if (!result)
1385 return FALSE;
1386 /* In the ANSI API, there should not be any paths longer
1387 than MAX_PATH. */
1388 assert(result <= MAX_PATH+1);
1389 if (strncmp(new_path, "\\\\", 2) == 0 ||
1390 strncmp(new_path, "//", 2) == 0)
1391 /* UNC path, nothing to do. */
1392 return TRUE;
1393 env[1] = new_path[0];
1394 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395}
1396
1397/* The Unicode version differs from the ANSI version
1398 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001399static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400win32_wchdir(LPCWSTR path)
1401{
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1403 int result;
1404 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 if(!SetCurrentDirectoryW(path))
1407 return FALSE;
1408 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1409 if (!result)
1410 return FALSE;
1411 if (result > MAX_PATH+1) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001412 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if (!new_path) {
1414 SetLastError(ERROR_OUTOFMEMORY);
1415 return FALSE;
1416 }
1417 result = GetCurrentDirectoryW(result, new_path);
1418 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001419 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 return FALSE;
1421 }
1422 }
1423 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1424 wcsncmp(new_path, L"//", 2) == 0)
1425 /* UNC path, nothing to do. */
1426 return TRUE;
1427 env[1] = new_path[0];
1428 result = SetEnvironmentVariableW(env, new_path);
1429 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001430 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001432}
1433#endif
1434
Martin v. Löwis14694662006-02-03 12:54:16 +00001435#ifdef MS_WINDOWS
1436/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1437 - time stamps are restricted to second resolution
1438 - file modification times suffer from forth-and-back conversions between
1439 UTC and local time
1440 Therefore, we implement our own stat, based on the Win32 API directly.
1441*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001442#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001443
1444struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001445 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001446 __int64 st_ino;
1447 unsigned short st_mode;
1448 int st_nlink;
1449 int st_uid;
1450 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001451 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001453 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001454 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001455 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001456 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001457 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001458 int st_ctime_nsec;
1459};
1460
1461static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1462
1463static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001464FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1467 /* Cannot simply cast and dereference in_ptr,
1468 since it might not be aligned properly */
1469 __int64 in;
1470 memcpy(&in, in_ptr, sizeof(in));
1471 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001472 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001473}
1474
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001476time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477{
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 /* XXX endianness */
1479 __int64 out;
1480 out = time_in + secs_between_epochs;
1481 out = out * 10000000 + nsec_in / 100;
1482 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001483}
1484
Martin v. Löwis14694662006-02-03 12:54:16 +00001485/* Below, we *know* that ugo+r is 0444 */
1486#if _S_IREAD != 0400
1487#error Unsupported C library
1488#endif
1489static int
1490attributes_to_mode(DWORD attr)
1491{
Victor Stinner8c62be82010-05-06 00:08:46 +00001492 int m = 0;
1493 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1494 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1495 else
1496 m |= _S_IFREG;
1497 if (attr & FILE_ATTRIBUTE_READONLY)
1498 m |= 0444;
1499 else
1500 m |= 0666;
1501 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001502}
1503
1504static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001505attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001506{
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 memset(result, 0, sizeof(*result));
1508 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1509 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001510 result->st_dev = info->dwVolumeSerialNumber;
1511 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001512 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1513 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1514 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001516 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1518 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001519 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001520 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001521 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001522 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001523
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001525}
1526
Guido van Rossumd8faa362007-04-27 19:54:29 +00001527static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001529{
Victor Stinner8c62be82010-05-06 00:08:46 +00001530 HANDLE hFindFile;
1531 WIN32_FIND_DATAA FileData;
1532 hFindFile = FindFirstFileA(pszFile, &FileData);
1533 if (hFindFile == INVALID_HANDLE_VALUE)
1534 return FALSE;
1535 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001537 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 info->dwFileAttributes = FileData.dwFileAttributes;
1539 info->ftCreationTime = FileData.ftCreationTime;
1540 info->ftLastAccessTime = FileData.ftLastAccessTime;
1541 info->ftLastWriteTime = FileData.ftLastWriteTime;
1542 info->nFileSizeHigh = FileData.nFileSizeHigh;
1543 info->nFileSizeLow = FileData.nFileSizeLow;
1544/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001545 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1546 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001548}
1549
1550static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001551attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552{
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 HANDLE hFindFile;
1554 WIN32_FIND_DATAW FileData;
1555 hFindFile = FindFirstFileW(pszFile, &FileData);
1556 if (hFindFile == INVALID_HANDLE_VALUE)
1557 return FALSE;
1558 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001559 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 info->dwFileAttributes = FileData.dwFileAttributes;
1562 info->ftCreationTime = FileData.ftCreationTime;
1563 info->ftLastAccessTime = FileData.ftLastAccessTime;
1564 info->ftLastWriteTime = FileData.ftLastWriteTime;
1565 info->nFileSizeHigh = FileData.nFileSizeHigh;
1566 info->nFileSizeLow = FileData.nFileSizeLow;
1567/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001568 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1569 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001571}
1572
Brian Curtind25aef52011-06-13 15:16:04 -05001573/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001574static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001575static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1576 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001577static int
Brian Curtind25aef52011-06-13 15:16:04 -05001578check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579{
Brian Curtind25aef52011-06-13 15:16:04 -05001580 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001581 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1582 DWORD);
1583
Brian Curtind25aef52011-06-13 15:16:04 -05001584 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001585 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001586 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001587 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001588 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1589 "GetFinalPathNameByHandleA");
1590 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1591 "GetFinalPathNameByHandleW");
1592 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1593 Py_GetFinalPathNameByHandleW;
1594 }
1595 return has_GetFinalPathNameByHandle;
1596}
1597
1598static BOOL
1599get_target_path(HANDLE hdl, wchar_t **target_path)
1600{
1601 int buf_size, result_length;
1602 wchar_t *buf;
1603
1604 /* We have a good handle to the target, use it to determine
1605 the target path name (then we'll call lstat on it). */
1606 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1607 VOLUME_NAME_DOS);
1608 if(!buf_size)
1609 return FALSE;
1610
Victor Stinnerb6404912013-07-07 16:21:41 +02001611 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001612 if (!buf) {
1613 SetLastError(ERROR_OUTOFMEMORY);
1614 return FALSE;
1615 }
1616
Brian Curtind25aef52011-06-13 15:16:04 -05001617 result_length = Py_GetFinalPathNameByHandleW(hdl,
1618 buf, buf_size, VOLUME_NAME_DOS);
1619
1620 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001621 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001622 return FALSE;
1623 }
1624
1625 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001626 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001627 return FALSE;
1628 }
1629
1630 buf[result_length] = 0;
1631
1632 *target_path = buf;
1633 return TRUE;
1634}
1635
1636static int
1637win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1638 BOOL traverse);
1639static int
1640win32_xstat_impl(const char *path, struct win32_stat *result,
1641 BOOL traverse)
1642{
Victor Stinner26de69d2011-06-17 15:15:38 +02001643 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001644 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001646 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001647 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 const char *dot;
1649
Brian Curtind25aef52011-06-13 15:16:04 -05001650 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001651 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1652 traverse reparse point. */
1653 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001654 }
1655
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656 hFile = CreateFileA(
1657 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001658 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 0, /* share mode */
1660 NULL, /* security attributes */
1661 OPEN_EXISTING,
1662 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001663 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1664 Because of this, calls like GetFinalPathNameByHandle will return
1665 the symlink path agin and not the actual final path. */
1666 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1667 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 NULL);
1669
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671 /* Either the target doesn't exist, or we don't have access to
1672 get a handle to it. If the former, we need to return an error.
1673 If the latter, we can use attributes_from_dir. */
1674 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 return -1;
1676 /* Could not get attributes on open file. Fall back to
1677 reading the directory. */
1678 if (!attributes_from_dir(path, &info, &reparse_tag))
1679 /* Very strange. This should not fail now */
1680 return -1;
1681 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1682 if (traverse) {
1683 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001684 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 } else {
1689 if (!GetFileInformationByHandle(hFile, &info)) {
1690 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001691 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 }
1693 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001694 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1695 return -1;
1696
1697 /* Close the outer open file handle now that we're about to
1698 reopen it with different flags. */
1699 if (!CloseHandle(hFile))
1700 return -1;
1701
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001703 /* In order to call GetFinalPathNameByHandle we need to open
1704 the file without the reparse handling flag set. */
1705 hFile2 = CreateFileA(
1706 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1707 NULL, OPEN_EXISTING,
1708 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1709 NULL);
1710 if (hFile2 == INVALID_HANDLE_VALUE)
1711 return -1;
1712
1713 if (!get_target_path(hFile2, &target_path))
1714 return -1;
1715
1716 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001717 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 return code;
1719 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001720 } else
1721 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724
1725 /* Set S_IEXEC if it is an .exe, .bat, ... */
1726 dot = strrchr(path, '.');
1727 if (dot) {
1728 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1729 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1730 result->st_mode |= 0111;
1731 }
1732 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001733}
1734
1735static int
Brian Curtind25aef52011-06-13 15:16:04 -05001736win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1737 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001738{
1739 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001740 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001741 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001742 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001743 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744 const wchar_t *dot;
1745
Brian Curtind25aef52011-06-13 15:16:04 -05001746 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001747 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1748 traverse reparse point. */
1749 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 }
1751
Brian Curtinf5e76d02010-11-24 13:14:05 +00001752 hFile = CreateFileW(
1753 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001754 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001755 0, /* share mode */
1756 NULL, /* security attributes */
1757 OPEN_EXISTING,
1758 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001759 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1760 Because of this, calls like GetFinalPathNameByHandle will return
1761 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001762 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001763 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001764 NULL);
1765
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001766 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767 /* Either the target doesn't exist, or we don't have access to
1768 get a handle to it. If the former, we need to return an error.
1769 If the latter, we can use attributes_from_dir. */
1770 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001771 return -1;
1772 /* Could not get attributes on open file. Fall back to
1773 reading the directory. */
1774 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1775 /* Very strange. This should not fail now */
1776 return -1;
1777 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1778 if (traverse) {
1779 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001780 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001781 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001782 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001783 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 } else {
1785 if (!GetFileInformationByHandle(hFile, &info)) {
1786 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001787 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 }
1789 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001790 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1791 return -1;
1792
1793 /* Close the outer open file handle now that we're about to
1794 reopen it with different flags. */
1795 if (!CloseHandle(hFile))
1796 return -1;
1797
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001798 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001799 /* In order to call GetFinalPathNameByHandle we need to open
1800 the file without the reparse handling flag set. */
1801 hFile2 = CreateFileW(
1802 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1803 NULL, OPEN_EXISTING,
1804 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1805 NULL);
1806 if (hFile2 == INVALID_HANDLE_VALUE)
1807 return -1;
1808
1809 if (!get_target_path(hFile2, &target_path))
1810 return -1;
1811
1812 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001813 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001814 return code;
1815 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001816 } else
1817 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001819 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001820
1821 /* Set S_IEXEC if it is an .exe, .bat, ... */
1822 dot = wcsrchr(path, '.');
1823 if (dot) {
1824 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1825 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1826 result->st_mode |= 0111;
1827 }
1828 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001829}
1830
1831static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001832win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001833{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001836 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001837 errno = 0;
1838 return code;
1839}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001840
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001841static int
1842win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1843{
1844 /* Protocol violation: we explicitly clear errno, instead of
1845 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001846 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001847 errno = 0;
1848 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001849}
Brian Curtind25aef52011-06-13 15:16:04 -05001850/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001851
1852 In Posix, stat automatically traverses symlinks and returns the stat
1853 structure for the target. In Windows, the equivalent GetFileAttributes by
1854 default does not traverse symlinks and instead returns attributes for
1855 the symlink.
1856
1857 Therefore, win32_lstat will get the attributes traditionally, and
1858 win32_stat will first explicitly resolve the symlink target and then will
1859 call win32_lstat on that result.
1860
Ezio Melotti4969f702011-03-15 05:59:46 +02001861 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001862
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001863static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001864win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001865{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001866 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001867}
1868
Victor Stinner8c62be82010-05-06 00:08:46 +00001869static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001870win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001871{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001873}
1874
1875static int
1876win32_stat(const char* path, struct win32_stat *result)
1877{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001879}
1880
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001881static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001882win32_stat_w(const wchar_t* path, struct win32_stat *result)
1883{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001884 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001885}
1886
1887static int
1888win32_fstat(int file_number, struct win32_stat *result)
1889{
Victor Stinner8c62be82010-05-06 00:08:46 +00001890 BY_HANDLE_FILE_INFORMATION info;
1891 HANDLE h;
1892 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001893
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001894 if (!_PyVerify_fd(file_number))
1895 h = INVALID_HANDLE_VALUE;
1896 else
1897 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001898
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 /* Protocol violation: we explicitly clear errno, instead of
1900 setting it to a POSIX error. Callers should use GetLastError. */
1901 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001902
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 if (h == INVALID_HANDLE_VALUE) {
1904 /* This is really a C library error (invalid file handle).
1905 We set the Win32 error to the closes one matching. */
1906 SetLastError(ERROR_INVALID_HANDLE);
1907 return -1;
1908 }
1909 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001910
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 type = GetFileType(h);
1912 if (type == FILE_TYPE_UNKNOWN) {
1913 DWORD error = GetLastError();
1914 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001915 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 }
1917 /* else: valid but unknown file */
1918 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001919
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 if (type != FILE_TYPE_DISK) {
1921 if (type == FILE_TYPE_CHAR)
1922 result->st_mode = _S_IFCHR;
1923 else if (type == FILE_TYPE_PIPE)
1924 result->st_mode = _S_IFIFO;
1925 return 0;
1926 }
1927
1928 if (!GetFileInformationByHandle(h, &info)) {
1929 return -1;
1930 }
1931
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001932 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1935 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001936}
1937
1938#endif /* MS_WINDOWS */
1939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001940PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001941"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001943 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1945\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001946Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1947or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001950
1951static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 {"st_mode", "protection bits"},
1953 {"st_ino", "inode"},
1954 {"st_dev", "device"},
1955 {"st_nlink", "number of hard links"},
1956 {"st_uid", "user ID of owner"},
1957 {"st_gid", "group ID of owner"},
1958 {"st_size", "total size, in bytes"},
1959 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1960 {NULL, "integer time of last access"},
1961 {NULL, "integer time of last modification"},
1962 {NULL, "integer time of last change"},
1963 {"st_atime", "time of last access"},
1964 {"st_mtime", "time of last modification"},
1965 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001966 {"st_atime_ns", "time of last access in nanoseconds"},
1967 {"st_mtime_ns", "time of last modification in nanoseconds"},
1968 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001971#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001972#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001975#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001978#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001980#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001981#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001983#endif
1984#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001986#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001990#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001991#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001993#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001994#endif
1995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001997#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1998#else
1999#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2000#endif
2001
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002002#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2004#else
2005#define ST_RDEV_IDX ST_BLOCKS_IDX
2006#endif
2007
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002008#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2009#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2010#else
2011#define ST_FLAGS_IDX ST_RDEV_IDX
2012#endif
2013
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002015#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002017#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#endif
2019
2020#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2021#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2022#else
2023#define ST_BIRTHTIME_IDX ST_GEN_IDX
2024#endif
2025
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002026static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 "stat_result", /* name */
2028 stat_result__doc__, /* doc */
2029 stat_result_fields,
2030 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002031};
2032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002034"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2035This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002036 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002037or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002040
2041static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 {"f_bsize", },
2043 {"f_frsize", },
2044 {"f_blocks", },
2045 {"f_bfree", },
2046 {"f_bavail", },
2047 {"f_files", },
2048 {"f_ffree", },
2049 {"f_favail", },
2050 {"f_flag", },
2051 {"f_namemax",},
2052 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002053};
2054
2055static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 "statvfs_result", /* name */
2057 statvfs_result__doc__, /* doc */
2058 statvfs_result_fields,
2059 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060};
2061
Ross Lagerwall7807c352011-03-17 20:20:30 +02002062#if defined(HAVE_WAITID) && !defined(__APPLE__)
2063PyDoc_STRVAR(waitid_result__doc__,
2064"waitid_result: Result from waitid.\n\n\
2065This object may be accessed either as a tuple of\n\
2066 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2067or via the attributes si_pid, si_uid, and so on.\n\
2068\n\
2069See os.waitid for more information.");
2070
2071static PyStructSequence_Field waitid_result_fields[] = {
2072 {"si_pid", },
2073 {"si_uid", },
2074 {"si_signo", },
2075 {"si_status", },
2076 {"si_code", },
2077 {0}
2078};
2079
2080static PyStructSequence_Desc waitid_result_desc = {
2081 "waitid_result", /* name */
2082 waitid_result__doc__, /* doc */
2083 waitid_result_fields,
2084 5
2085};
2086static PyTypeObject WaitidResultType;
2087#endif
2088
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002089static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090static PyTypeObject StatResultType;
2091static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002092#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002093static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002094#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002095static newfunc structseq_new;
2096
2097static PyObject *
2098statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2099{
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 PyStructSequence *result;
2101 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002102
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 result = (PyStructSequence*)structseq_new(type, args, kwds);
2104 if (!result)
2105 return NULL;
2106 /* If we have been initialized from a tuple,
2107 st_?time might be set to None. Initialize it
2108 from the int slots. */
2109 for (i = 7; i <= 9; i++) {
2110 if (result->ob_item[i+3] == Py_None) {
2111 Py_DECREF(Py_None);
2112 Py_INCREF(result->ob_item[i]);
2113 result->ob_item[i+3] = result->ob_item[i];
2114 }
2115 }
2116 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002117}
2118
2119
2120
2121/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002122static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002123
2124PyDoc_STRVAR(stat_float_times__doc__,
2125"stat_float_times([newval]) -> oldval\n\n\
2126Determine whether os.[lf]stat represents time stamps as float objects.\n\
2127If newval is True, future calls to stat() return floats, if it is False,\n\
2128future calls return ints. \n\
2129If newval is omitted, return the current setting.\n");
2130
2131static PyObject*
2132stat_float_times(PyObject* self, PyObject *args)
2133{
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 int newval = -1;
2135 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2136 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002137 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2138 "stat_float_times() is deprecated",
2139 1))
2140 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002141 if (newval == -1)
2142 /* Return old value */
2143 return PyBool_FromLong(_stat_float_times);
2144 _stat_float_times = newval;
2145 Py_INCREF(Py_None);
2146 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002147}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002148
Larry Hastings6fe20b32012-04-19 15:07:49 -07002149static PyObject *billion = NULL;
2150
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002151static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002152fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002153{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002154 PyObject *s = _PyLong_FromTime_t(sec);
2155 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2156 PyObject *s_in_ns = NULL;
2157 PyObject *ns_total = NULL;
2158 PyObject *float_s = NULL;
2159
2160 if (!(s && ns_fractional))
2161 goto exit;
2162
2163 s_in_ns = PyNumber_Multiply(s, billion);
2164 if (!s_in_ns)
2165 goto exit;
2166
2167 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2168 if (!ns_total)
2169 goto exit;
2170
Victor Stinner4195b5c2012-02-08 23:03:19 +01002171 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002172 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2173 if (!float_s)
2174 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002176 else {
2177 float_s = s;
2178 Py_INCREF(float_s);
2179 }
2180
2181 PyStructSequence_SET_ITEM(v, index, s);
2182 PyStructSequence_SET_ITEM(v, index+3, float_s);
2183 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2184 s = NULL;
2185 float_s = NULL;
2186 ns_total = NULL;
2187exit:
2188 Py_XDECREF(s);
2189 Py_XDECREF(ns_fractional);
2190 Py_XDECREF(s_in_ns);
2191 Py_XDECREF(ns_total);
2192 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002193}
2194
Tim Peters5aa91602002-01-30 05:46:57 +00002195/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002196 (used by posix_stat() and posix_fstat()) */
2197static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002198_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002199{
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 unsigned long ansec, mnsec, cnsec;
2201 PyObject *v = PyStructSequence_New(&StatResultType);
2202 if (v == NULL)
2203 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002204
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002206#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 1,
2208 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002209#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002211#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002212#ifdef MS_WINDOWS
2213 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2214#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 2,
2216 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002217#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002218 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002219#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002220 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002221#if defined(MS_WINDOWS)
2222 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2223 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2224#else
2225 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2226 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2227#endif
Fred Drake699f3522000-06-29 21:12:41 +00002228#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002229 PyStructSequence_SET_ITEM(v, 6,
2230 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002231#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002232 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002233#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002234
Martin v. Löwis14694662006-02-03 12:54:16 +00002235#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 ansec = st->st_atim.tv_nsec;
2237 mnsec = st->st_mtim.tv_nsec;
2238 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002239#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 ansec = st->st_atimespec.tv_nsec;
2241 mnsec = st->st_mtimespec.tv_nsec;
2242 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002243#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 ansec = st->st_atime_nsec;
2245 mnsec = st->st_mtime_nsec;
2246 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002249#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002250 fill_time(v, 7, st->st_atime, ansec);
2251 fill_time(v, 8, st->st_mtime, mnsec);
2252 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002253
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002254#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2256 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002257#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002258#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2260 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002261#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002262#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002263 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2264 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002265#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2268 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002269#endif
2270#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002271 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 PyObject *val;
2273 unsigned long bsec,bnsec;
2274 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002276 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002277#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002278 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002280 if (_stat_float_times) {
2281 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2282 } else {
2283 val = PyLong_FromLong((long)bsec);
2284 }
2285 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2286 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002288#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002289#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2291 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002292#endif
Fred Drake699f3522000-06-29 21:12:41 +00002293
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 if (PyErr_Occurred()) {
2295 Py_DECREF(v);
2296 return NULL;
2297 }
Fred Drake699f3522000-06-29 21:12:41 +00002298
Victor Stinner8c62be82010-05-06 00:08:46 +00002299 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002300}
2301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302/* POSIX methods */
2303
Guido van Rossum94f6f721999-01-06 18:42:14 +00002304
2305static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306posix_do_stat(char *function_name, path_t *path,
2307 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002308{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002309 STRUCT_STAT st;
2310 int result;
2311
2312#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2313 if (follow_symlinks_specified(function_name, follow_symlinks))
2314 return NULL;
2315#endif
2316
2317 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2318 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2319 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2320 return NULL;
2321
2322 Py_BEGIN_ALLOW_THREADS
2323 if (path->fd != -1)
2324 result = FSTAT(path->fd, &st);
2325 else
2326#ifdef MS_WINDOWS
2327 if (path->wide) {
2328 if (follow_symlinks)
2329 result = win32_stat_w(path->wide, &st);
2330 else
2331 result = win32_lstat_w(path->wide, &st);
2332 }
2333 else
2334#endif
2335#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2336 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2337 result = LSTAT(path->narrow, &st);
2338 else
2339#endif
2340#ifdef HAVE_FSTATAT
2341 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2342 result = fstatat(dir_fd, path->narrow, &st,
2343 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2344 else
2345#endif
2346 result = STAT(path->narrow, &st);
2347 Py_END_ALLOW_THREADS
2348
Victor Stinner292c8352012-10-30 02:17:38 +01002349 if (result != 0) {
2350 return path_error(path);
2351 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002352
2353 return _pystat_fromstructstat(&st);
2354}
2355
Larry Hastings31826802013-10-19 00:09:25 -07002356#ifdef HAVE_FSTATAT
2357 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2358#else
2359 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2360#endif
2361
2362
2363/*[python]
2364
2365class path_t_converter(CConverter):
2366
2367 type = "path_t"
2368 impl_by_reference = True
2369 parse_by_reference = True
2370
2371 converter = 'path_converter'
2372
2373 def converter_init(self, *, allow_fd=False, nullable=False):
2374 def strify(value):
2375 return str(int(bool(value)))
2376
2377 # right now path_t doesn't support default values.
2378 # to support a default value, you'll need to override initialize().
2379
2380 assert self.default is unspecified
2381
2382 self.nullable = nullable
2383 self.allow_fd = allow_fd
2384
2385 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2386 self.function.name,
2387 strify(nullable),
2388 strify(allow_fd),
2389 )
2390
2391 def cleanup(self):
2392 return "path_cleanup(&" + self.name + ");\n"
2393
2394
2395class dir_fd_converter(CConverter):
2396 type = 'int'
2397 converter = 'OS_STAT_DIR_FD_CONVERTER'
2398
2399 def converter_init(self):
2400 if self.default in (unspecified, None):
2401 self.c_default = 'DEFAULT_DIR_FD'
2402
2403
2404[python]*/
2405/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
2406
2407/*[clinic]
2408module os
2409
2410os.stat -> object(doc_default='stat_result')
2411
2412 path : path_t(allow_fd=True)
2413 Path to be examined; can be string, bytes, or open-file-descriptor int.
2414
2415 *
2416
2417 dir_fd : dir_fd = None
2418 If not None, it should be a file descriptor open to a directory,
2419 and path should be a relative string; path will then be relative to
2420 that directory.
2421
2422 follow_symlinks: bool = True
2423 If False, and the last element of the path is a symbolic link,
2424 stat will examine the symbolic link itself instead of the file
2425 the link points to.
2426
2427Perform a stat system call on the given path.
2428
2429dir_fd and follow_symlinks may not be implemented
2430 on your platform. If they are unavailable, using them will raise a
2431 NotImplementedError.
2432
2433It's an error to use dir_fd or follow_symlinks when specifying path as
2434 an open file descriptor.
2435
2436[clinic]*/
2437
2438PyDoc_STRVAR(os_stat__doc__,
2439"Perform a stat system call on the given path.\n"
2440"\n"
2441"os.stat(path, *, dir_fd=None, follow_symlinks=True) -> stat_result\n"
2442" path\n"
2443" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2444" dir_fd\n"
2445" If not None, it should be a file descriptor open to a directory,\n"
2446" and path should be a relative string; path will then be relative to\n"
2447" that directory.\n"
2448" follow_symlinks\n"
2449" If False, and the last element of the path is a symbolic link,\n"
2450" stat will examine the symbolic link itself instead of the file\n"
2451" the link points to.\n"
2452"\n"
2453"dir_fd and follow_symlinks may not be implemented\n"
2454" on your platform. If they are unavailable, using them will raise a\n"
2455" NotImplementedError.\n"
2456"\n"
2457"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2458" an open file descriptor.");
2459
2460#define OS_STAT_METHODDEF \
2461 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462
2463static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002464os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks);
2465
2466static PyObject *
2467os_stat(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468{
Larry Hastings31826802013-10-19 00:09:25 -07002469 PyObject *return_value = NULL;
2470 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2471 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002472 int dir_fd = DEFAULT_DIR_FD;
2473 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002474
Larry Hastings31826802013-10-19 00:09:25 -07002475 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2476 "O&|$O&p:stat", _keywords,
2477 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2478 goto exit;
2479 return_value = os_stat_impl(self, &path, dir_fd, follow_symlinks);
2480
2481exit:
2482 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002483 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002484
Larry Hastings9cf065c2012-06-22 16:30:09 -07002485 return return_value;
2486}
2487
Larry Hastings31826802013-10-19 00:09:25 -07002488static PyObject *
2489os_stat_impl(PyObject *self, path_t *path, int dir_fd, int follow_symlinks)
2490/*[clinic checksum: 9d9af08e8cfafd12f94e73ea3065eb3056f99515]*/
2491{
2492 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2493}
2494
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495PyDoc_STRVAR(posix_lstat__doc__,
2496"lstat(path, *, dir_fd=None) -> stat result\n\n\
2497Like stat(), but do not follow symbolic links.\n\
2498Equivalent to stat(path, follow_symlinks=False).");
2499
2500static PyObject *
2501posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2502{
2503 static char *keywords[] = {"path", "dir_fd", NULL};
2504 path_t path;
2505 int dir_fd = DEFAULT_DIR_FD;
2506 int follow_symlinks = 0;
2507 PyObject *return_value;
2508
2509 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002510 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2512 path_converter, &path,
2513#ifdef HAVE_FSTATAT
2514 dir_fd_converter, &dir_fd
2515#else
2516 dir_fd_unavailable, &dir_fd
2517#endif
2518 ))
2519 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002520 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 path_cleanup(&path);
2522 return return_value;
2523}
2524
Larry Hastings31826802013-10-19 00:09:25 -07002525
2526#ifdef HAVE_FACCESSAT
2527 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2528#else
2529 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2530#endif
2531/*[clinic]
2532os.access -> object(doc_default='True if granted, False otherwise')
2533
2534 path: path_t(allow_fd=True)
2535 Path to be tested; can be string, bytes, or open-file-descriptor int.
2536
2537 mode: int
2538 Operating-system mode bitfield. Can be F_OK to test existence,
2539 or the inclusive-OR of R_OK, W_OK, and X_OK.
2540
2541 *
2542
2543 dir_fd : dir_fd = None
2544 If not None, it should be a file descriptor open to a directory,
2545 and path should be relative; path will then be relative to that
2546 directory.
2547
2548 effective_ids: bool = False
2549 If True, access will use the effective uid/gid instead of
2550 the real uid/gid.
2551
2552 follow_symlinks: bool = True
2553 If False, and the last element of the path is a symbolic link,
2554 access will examine the symbolic link itself instead of the file
2555 the link points to.
2556
2557Use the real uid/gid to test for access to a path.
2558
2559{parameters}
2560dir_fd, effective_ids, and follow_symlinks may not be implemented
2561 on your platform. If they are unavailable, using them will raise a
2562 NotImplementedError.
2563
2564Note that most operations will use the effective uid/gid, therefore this
2565 routine can be used in a suid/sgid environment to test if the invoking user
2566 has the specified access to the path.
2567
2568[clinic]*/
2569
2570PyDoc_STRVAR(os_access__doc__,
2571"Use the real uid/gid to test for access to a path.\n"
2572"\n"
2573"os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) -> True if granted, False otherwise\n"
2574" path\n"
2575" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2576" mode\n"
2577" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2578" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2579" dir_fd\n"
2580" If not None, it should be a file descriptor open to a directory,\n"
2581" and path should be relative; path will then be relative to that\n"
2582" directory.\n"
2583" effective_ids\n"
2584" If True, access will use the effective uid/gid instead of\n"
2585" the real uid/gid.\n"
2586" follow_symlinks\n"
2587" If False, and the last element of the path is a symbolic link,\n"
2588" access will examine the symbolic link itself instead of the file\n"
2589" the link points to.\n"
2590"\n"
2591"{parameters}\n"
2592"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2593" on your platform. If they are unavailable, using them will raise a\n"
2594" NotImplementedError.\n"
2595"\n"
2596"Note that most operations will use the effective uid/gid, therefore this\n"
2597" routine can be used in a suid/sgid environment to test if the invoking user\n"
2598" has the specified access to the path.");
2599
2600#define OS_ACCESS_METHODDEF \
2601 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602
2603static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002604os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
2605
2606static PyObject *
2607os_access(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608{
Larry Hastings31826802013-10-19 00:09:25 -07002609 PyObject *return_value = NULL;
2610 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2611 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002612 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613 int dir_fd = DEFAULT_DIR_FD;
2614 int effective_ids = 0;
2615 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002616
2617 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2618 "O&i|$O&pp:access", _keywords,
2619 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2620 goto exit;
2621 return_value = os_access_impl(self, &path, mode, dir_fd, effective_ids, follow_symlinks);
2622
2623exit:
2624 /* Cleanup for path */
2625 path_cleanup(&path);
2626
2627 return return_value;
2628}
2629
2630static PyObject *
2631os_access_impl(PyObject *self, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
2632/*[clinic checksum: 0147557eb43243df57ba616cc7c35f232c69bc6a]*/
2633{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002635
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002636#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002638#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642#ifndef HAVE_FACCESSAT
2643 if (follow_symlinks_specified("access", follow_symlinks))
2644 goto exit;
2645
2646 if (effective_ids) {
2647 argument_unavailable_error("access", "effective_ids");
2648 goto exit;
2649 }
2650#endif
2651
2652#ifdef MS_WINDOWS
2653 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002654 if (path->wide != NULL)
2655 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002657 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 Py_END_ALLOW_THREADS
2659
2660 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002661 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662 * * we didn't get a -1, and
2663 * * write access wasn't requested,
2664 * * or the file isn't read-only,
2665 * * or it's a directory.
2666 * (Directories cannot be read-only on Windows.)
2667 */
2668 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002669 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002670 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 !(attr & FILE_ATTRIBUTE_READONLY) ||
2672 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2673#else
2674
2675 Py_BEGIN_ALLOW_THREADS
2676#ifdef HAVE_FACCESSAT
2677 if ((dir_fd != DEFAULT_DIR_FD) ||
2678 effective_ids ||
2679 !follow_symlinks) {
2680 int flags = 0;
2681 if (!follow_symlinks)
2682 flags |= AT_SYMLINK_NOFOLLOW;
2683 if (effective_ids)
2684 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002685 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 }
2687 else
2688#endif
Larry Hastings31826802013-10-19 00:09:25 -07002689 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690 Py_END_ALLOW_THREADS
2691 return_value = PyBool_FromLong(!result);
2692#endif
2693
2694#ifndef HAVE_FACCESSAT
2695exit:
2696#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002698}
2699
Guido van Rossumd371ff11999-01-25 16:12:23 +00002700#ifndef F_OK
2701#define F_OK 0
2702#endif
2703#ifndef R_OK
2704#define R_OK 4
2705#endif
2706#ifndef W_OK
2707#define W_OK 2
2708#endif
2709#ifndef X_OK
2710#define X_OK 1
2711#endif
2712
Larry Hastings31826802013-10-19 00:09:25 -07002713
Guido van Rossumd371ff11999-01-25 16:12:23 +00002714#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002715
2716/*[clinic]
2717os.ttyname -> DecodeFSDefault
2718
2719 fd: int
2720 Integer file descriptor handle.
2721
2722 /
2723
2724Return the name of the terminal device connected to 'fd'.
2725[clinic]*/
2726
2727PyDoc_STRVAR(os_ttyname__doc__,
2728"Return the name of the terminal device connected to \'fd\'.\n"
2729"\n"
2730"os.ttyname(fd)\n"
2731" fd\n"
2732" Integer file descriptor handle.");
2733
2734#define OS_TTYNAME_METHODDEF \
2735 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2736
2737static char *
2738os_ttyname_impl(PyObject *self, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002739
2740static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07002741os_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002742{
Larry Hastings31826802013-10-19 00:09:25 -07002743 PyObject *return_value = NULL;
2744 int fd;
2745 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002746
Larry Hastings31826802013-10-19 00:09:25 -07002747 if (!PyArg_ParseTuple(args,
2748 "i:ttyname",
2749 &fd))
2750 goto exit;
2751 _return_value = os_ttyname_impl(self, fd);
2752 if (_return_value == NULL)
2753 goto exit;
2754 return_value = PyUnicode_DecodeFSDefault(_return_value);
2755
2756exit:
2757 return return_value;
2758}
2759
2760static char *
2761os_ttyname_impl(PyObject *self, int fd)
2762/*[clinic checksum: ea680155d87bb733f542d67653eca732dd0981a8]*/
2763{
2764 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002765
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002766#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002767 /* file descriptor 0 only, the default input device (stdin) */
Larry Hastings31826802013-10-19 00:09:25 -07002768 if (fd == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 ret = ttyname();
2770 }
2771 else {
2772 ret = NULL;
2773 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002774#else
Larry Hastings31826802013-10-19 00:09:25 -07002775 ret = ttyname(fd);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002776#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002778 posix_error();
2779 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002780}
Larry Hastings31826802013-10-19 00:09:25 -07002781#else
2782#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002783#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002784
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002785#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002787"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002789
2790static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002791posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002792{
Victor Stinner8c62be82010-05-06 00:08:46 +00002793 char *ret;
2794 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002795
Greg Wardb48bc172000-03-01 21:51:56 +00002796#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002798#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002800#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 if (ret == NULL)
2802 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002803 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002804}
2805#endif
2806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002807PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002808"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809Change the current working directory to the specified path.\n\
2810\n\
2811path may always be specified as a string.\n\
2812On some platforms, path may also be specified as an open file descriptor.\n\
2813 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002814
Barry Warsaw53699e91996-12-10 23:23:01 +00002815static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 path_t path;
2819 int result;
2820 PyObject *return_value = NULL;
2821 static char *keywords[] = {"path", NULL};
2822
2823 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002824 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825#ifdef HAVE_FCHDIR
2826 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002827#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2829 path_converter, &path
2830 ))
2831 return NULL;
2832
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef MS_WINDOWS
2835 if (path.wide)
2836 result = win32_wchdir(path.wide);
2837 else
2838 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002839 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840#else
2841#ifdef HAVE_FCHDIR
2842 if (path.fd != -1)
2843 result = fchdir(path.fd);
2844 else
2845#endif
2846 result = chdir(path.narrow);
2847#endif
2848 Py_END_ALLOW_THREADS
2849
2850 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002851 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 goto exit;
2853 }
2854
2855 return_value = Py_None;
2856 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002857
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858exit:
2859 path_cleanup(&path);
2860 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002861}
2862
Fred Drake4d1e64b2002-04-15 19:40:07 +00002863#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002864PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865"fchdir(fd)\n\n\
2866Change to the directory of the given file descriptor. fd must be\n\
2867opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002868
2869static PyObject *
2870posix_fchdir(PyObject *self, PyObject *fdobj)
2871{
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002873}
2874#endif /* HAVE_FCHDIR */
2875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2879Change the access permissions of a file.\n\
2880\n\
2881path may always be specified as a string.\n\
2882On some platforms, path may also be specified as an open file descriptor.\n\
2883 If this functionality is unavailable, using it raises an exception.\n\
2884If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2885 and path should be relative; path will then be relative to that directory.\n\
2886If follow_symlinks is False, and the last element of the path is a symbolic\n\
2887 link, chmod will modify the symbolic link itself instead of the file the\n\
2888 link points to.\n\
2889It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2890 an open file descriptor.\n\
2891dir_fd and follow_symlinks may not be implemented on your platform.\n\
2892 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Barry Warsaw53699e91996-12-10 23:23:01 +00002894static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002896{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 path_t path;
2898 int mode;
2899 int dir_fd = DEFAULT_DIR_FD;
2900 int follow_symlinks = 1;
2901 int result;
2902 PyObject *return_value = NULL;
2903 static char *keywords[] = {"path", "mode", "dir_fd",
2904 "follow_symlinks", NULL};
2905
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002906#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002909
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910#ifdef HAVE_FCHMODAT
2911 int fchmodat_nofollow_unsupported = 0;
2912#endif
2913
2914 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002915 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916#ifdef HAVE_FCHMOD
2917 path.allow_fd = 1;
2918#endif
2919 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2920 path_converter, &path,
2921 &mode,
2922#ifdef HAVE_FCHMODAT
2923 dir_fd_converter, &dir_fd,
2924#else
2925 dir_fd_unavailable, &dir_fd,
2926#endif
2927 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929
2930#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2931 if (follow_symlinks_specified("chmod", follow_symlinks))
2932 goto exit;
2933#endif
2934
2935#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937 if (path.wide)
2938 attr = GetFileAttributesW(path.wide);
2939 else
2940 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002941 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942 result = 0;
2943 else {
2944 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002945 attr &= ~FILE_ATTRIBUTE_READONLY;
2946 else
2947 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948 if (path.wide)
2949 result = SetFileAttributesW(path.wide, attr);
2950 else
2951 result = SetFileAttributesA(path.narrow, attr);
2952 }
2953 Py_END_ALLOW_THREADS
2954
2955 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002956 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957 goto exit;
2958 }
2959#else /* MS_WINDOWS */
2960 Py_BEGIN_ALLOW_THREADS
2961#ifdef HAVE_FCHMOD
2962 if (path.fd != -1)
2963 result = fchmod(path.fd, mode);
2964 else
2965#endif
2966#ifdef HAVE_LCHMOD
2967 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2968 result = lchmod(path.narrow, mode);
2969 else
2970#endif
2971#ifdef HAVE_FCHMODAT
2972 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2973 /*
2974 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2975 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002976 * and then says it isn't implemented yet.
2977 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978 *
2979 * Once it is supported, os.chmod will automatically
2980 * support dir_fd and follow_symlinks=False. (Hopefully.)
2981 * Until then, we need to be careful what exception we raise.
2982 */
2983 result = fchmodat(dir_fd, path.narrow, mode,
2984 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2985 /*
2986 * But wait! We can't throw the exception without allowing threads,
2987 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2988 */
2989 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002990 result &&
2991 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2992 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 }
2994 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002995#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996 result = chmod(path.narrow, mode);
2997 Py_END_ALLOW_THREADS
2998
2999 if (result) {
3000#ifdef HAVE_FCHMODAT
3001 if (fchmodat_nofollow_unsupported) {
3002 if (dir_fd != DEFAULT_DIR_FD)
3003 dir_fd_and_follow_symlinks_invalid("chmod",
3004 dir_fd, follow_symlinks);
3005 else
3006 follow_symlinks_specified("chmod", follow_symlinks);
3007 }
3008 else
3009#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003010 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003011 goto exit;
3012 }
3013#endif
3014
3015 Py_INCREF(Py_None);
3016 return_value = Py_None;
3017exit:
3018 path_cleanup(&path);
3019 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003020}
3021
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022
Christian Heimes4e30a842007-11-30 22:12:06 +00003023#ifdef HAVE_FCHMOD
3024PyDoc_STRVAR(posix_fchmod__doc__,
3025"fchmod(fd, mode)\n\n\
3026Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003028
3029static PyObject *
3030posix_fchmod(PyObject *self, PyObject *args)
3031{
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 int fd, mode, res;
3033 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3034 return NULL;
3035 Py_BEGIN_ALLOW_THREADS
3036 res = fchmod(fd, mode);
3037 Py_END_ALLOW_THREADS
3038 if (res < 0)
3039 return posix_error();
3040 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003041}
3042#endif /* HAVE_FCHMOD */
3043
3044#ifdef HAVE_LCHMOD
3045PyDoc_STRVAR(posix_lchmod__doc__,
3046"lchmod(path, mode)\n\n\
3047Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003048affects the link itself rather than the target.\n\
3049Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003050
3051static PyObject *
3052posix_lchmod(PyObject *self, PyObject *args)
3053{
Victor Stinner292c8352012-10-30 02:17:38 +01003054 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 int i;
3056 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003057 memset(&path, 0, sizeof(path));
3058 path.function_name = "lchmod";
3059 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3060 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003062 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003063 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003065 if (res < 0) {
3066 path_error(&path);
3067 path_cleanup(&path);
3068 return NULL;
3069 }
3070 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003071 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003072}
3073#endif /* HAVE_LCHMOD */
3074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
Thomas Wouterscf297e42007-02-23 15:07:44 +00003076#ifdef HAVE_CHFLAGS
3077PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078"chflags(path, flags, *, follow_symlinks=True)\n\n\
3079Set file flags.\n\
3080\n\
3081If follow_symlinks is False, and the last element of the path is a symbolic\n\
3082 link, chflags will change flags on the symbolic link itself instead of the\n\
3083 file the link points to.\n\
3084follow_symlinks may not be implemented on your platform. If it is\n\
3085unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003086
3087static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003089{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 int follow_symlinks = 1;
3093 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003094 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3096
3097 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003098 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003099 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3100 path_converter, &path,
3101 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003102 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103
3104#ifndef HAVE_LCHFLAGS
3105 if (follow_symlinks_specified("chflags", follow_symlinks))
3106 goto exit;
3107#endif
3108
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110#ifdef HAVE_LCHFLAGS
3111 if (!follow_symlinks)
3112 result = lchflags(path.narrow, flags);
3113 else
3114#endif
3115 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117
3118 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003119 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120 goto exit;
3121 }
3122
3123 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003125
3126exit:
3127 path_cleanup(&path);
3128 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003129}
3130#endif /* HAVE_CHFLAGS */
3131
3132#ifdef HAVE_LCHFLAGS
3133PyDoc_STRVAR(posix_lchflags__doc__,
3134"lchflags(path, flags)\n\n\
3135Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136This function will not follow symbolic links.\n\
3137Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003138
3139static PyObject *
3140posix_lchflags(PyObject *self, PyObject *args)
3141{
Victor Stinner292c8352012-10-30 02:17:38 +01003142 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 unsigned long flags;
3144 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003145 memset(&path, 0, sizeof(path));
3146 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003148 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003150 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003151 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003153 if (res < 0) {
3154 path_error(&path);
3155 path_cleanup(&path);
3156 return NULL;
3157 }
3158 path_cleanup(&path);
3159 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003160}
3161#endif /* HAVE_LCHFLAGS */
3162
Martin v. Löwis244edc82001-10-04 22:44:26 +00003163#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003164PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003165"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003166Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003167
3168static PyObject *
3169posix_chroot(PyObject *self, PyObject *args)
3170{
Victor Stinner292c8352012-10-30 02:17:38 +01003171 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003172}
3173#endif
3174
Guido van Rossum21142a01999-01-08 21:05:37 +00003175#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003179
3180static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003181posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003182{
Stefan Krah0e803b32010-11-26 16:16:47 +00003183 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003184}
3185#endif /* HAVE_FSYNC */
3186
Ross Lagerwall7807c352011-03-17 20:20:30 +02003187#ifdef HAVE_SYNC
3188PyDoc_STRVAR(posix_sync__doc__,
3189"sync()\n\n\
3190Force write of everything to disk.");
3191
3192static PyObject *
3193posix_sync(PyObject *self, PyObject *noargs)
3194{
3195 Py_BEGIN_ALLOW_THREADS
3196 sync();
3197 Py_END_ALLOW_THREADS
3198 Py_RETURN_NONE;
3199}
3200#endif
3201
Guido van Rossum21142a01999-01-08 21:05:37 +00003202#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003203
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003204#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003205extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3206#endif
3207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003210force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003211 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003212
3213static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003214posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003215{
Stefan Krah0e803b32010-11-26 16:16:47 +00003216 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003217}
3218#endif /* HAVE_FDATASYNC */
3219
3220
Fredrik Lundh10723342000-07-10 16:38:09 +00003221#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003222PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3224Change the owner and group id of path to the numeric uid and gid.\n\
3225\n\
3226path may always be specified as a string.\n\
3227On some platforms, path may also be specified as an open file descriptor.\n\
3228 If this functionality is unavailable, using it raises an exception.\n\
3229If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3230 and path should be relative; path will then be relative to that directory.\n\
3231If follow_symlinks is False, and the last element of the path is a symbolic\n\
3232 link, chown will modify the symbolic link itself instead of the file the\n\
3233 link points to.\n\
3234It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3235 an open file descriptor.\n\
3236dir_fd and follow_symlinks may not be implemented on your platform.\n\
3237 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
Barry Warsaw53699e91996-12-10 23:23:01 +00003239static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003241{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243 uid_t uid;
3244 gid_t gid;
3245 int dir_fd = DEFAULT_DIR_FD;
3246 int follow_symlinks = 1;
3247 int result;
3248 PyObject *return_value = NULL;
3249 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3250 "follow_symlinks", NULL};
3251
3252 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003253 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254#ifdef HAVE_FCHOWN
3255 path.allow_fd = 1;
3256#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003257 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003259 _Py_Uid_Converter, &uid,
3260 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261#ifdef HAVE_FCHOWNAT
3262 dir_fd_converter, &dir_fd,
3263#else
3264 dir_fd_unavailable, &dir_fd,
3265#endif
3266 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268
3269#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3270 if (follow_symlinks_specified("chown", follow_symlinks))
3271 goto exit;
3272#endif
3273 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3274 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3275 goto exit;
3276
3277#ifdef __APPLE__
3278 /*
3279 * This is for Mac OS X 10.3, which doesn't have lchown.
3280 * (But we still have an lchown symbol because of weak-linking.)
3281 * It doesn't have fchownat either. So there's no possibility
3282 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003283 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003284 if ((!follow_symlinks) && (lchown == NULL)) {
3285 follow_symlinks_specified("chown", follow_symlinks);
3286 goto exit;
3287 }
3288#endif
3289
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291#ifdef HAVE_FCHOWN
3292 if (path.fd != -1)
3293 result = fchown(path.fd, uid, gid);
3294 else
3295#endif
3296#ifdef HAVE_LCHOWN
3297 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3298 result = lchown(path.narrow, uid, gid);
3299 else
3300#endif
3301#ifdef HAVE_FCHOWNAT
3302 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3303 result = fchownat(dir_fd, path.narrow, uid, gid,
3304 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3305 else
3306#endif
3307 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003309
3310 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003311 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312 goto exit;
3313 }
3314
3315 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317
3318exit:
3319 path_cleanup(&path);
3320 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003321}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003322#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003323
Christian Heimes4e30a842007-11-30 22:12:06 +00003324#ifdef HAVE_FCHOWN
3325PyDoc_STRVAR(posix_fchown__doc__,
3326"fchown(fd, uid, gid)\n\n\
3327Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003329
3330static PyObject *
3331posix_fchown(PyObject *self, PyObject *args)
3332{
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003334 uid_t uid;
3335 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003337 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3338 _Py_Uid_Converter, &uid,
3339 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return NULL;
3341 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003342 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 Py_END_ALLOW_THREADS
3344 if (res < 0)
3345 return posix_error();
3346 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003347}
3348#endif /* HAVE_FCHOWN */
3349
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003350#ifdef HAVE_LCHOWN
3351PyDoc_STRVAR(posix_lchown__doc__,
3352"lchown(path, uid, gid)\n\n\
3353Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354This function will not follow symbolic links.\n\
3355Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003356
3357static PyObject *
3358posix_lchown(PyObject *self, PyObject *args)
3359{
Victor Stinner292c8352012-10-30 02:17:38 +01003360 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003361 uid_t uid;
3362 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003364 memset(&path, 0, sizeof(path));
3365 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003366 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003367 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003368 _Py_Uid_Converter, &uid,
3369 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003372 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003374 if (res < 0) {
3375 path_error(&path);
3376 path_cleanup(&path);
3377 return NULL;
3378 }
3379 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 Py_INCREF(Py_None);
3381 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003382}
3383#endif /* HAVE_LCHOWN */
3384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003385
Barry Warsaw53699e91996-12-10 23:23:01 +00003386static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003387posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003388{
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 char buf[1026];
3390 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003391
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003392#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003393 if (!use_bytes) {
3394 wchar_t wbuf[1026];
3395 wchar_t *wbuf2 = wbuf;
3396 PyObject *resobj;
3397 DWORD len;
3398 Py_BEGIN_ALLOW_THREADS
3399 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3400 /* If the buffer is large enough, len does not include the
3401 terminating \0. If the buffer is too small, len includes
3402 the space needed for the terminator. */
3403 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003404 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 if (wbuf2)
3406 len = GetCurrentDirectoryW(len, wbuf2);
3407 }
3408 Py_END_ALLOW_THREADS
3409 if (!wbuf2) {
3410 PyErr_NoMemory();
3411 return NULL;
3412 }
3413 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003414 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003415 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003416 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 }
3418 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003419 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003420 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 return resobj;
3422 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003423
3424 if (win32_warn_bytes_api())
3425 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003426#endif
3427
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 Py_END_ALLOW_THREADS
3431 if (res == NULL)
3432 return posix_error();
3433 if (use_bytes)
3434 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003435 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003436}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003437
3438PyDoc_STRVAR(posix_getcwd__doc__,
3439"getcwd() -> path\n\n\
3440Return a unicode string representing the current working directory.");
3441
3442static PyObject *
3443posix_getcwd_unicode(PyObject *self)
3444{
3445 return posix_getcwd(0);
3446}
3447
3448PyDoc_STRVAR(posix_getcwdb__doc__,
3449"getcwdb() -> path\n\n\
3450Return a bytes string representing the current working directory.");
3451
3452static PyObject *
3453posix_getcwd_bytes(PyObject *self)
3454{
3455 return posix_getcwd(1);
3456}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003457
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3459#define HAVE_LINK 1
3460#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003461
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003463PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3465Create a hard link to a file.\n\
3466\n\
3467If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3468 descriptor open to a directory, and the respective path string (src or dst)\n\
3469 should be relative; the path will then be relative to that directory.\n\
3470If follow_symlinks is False, and the last element of src is a symbolic\n\
3471 link, link will create a link to the symbolic link itself instead of the\n\
3472 file the link points to.\n\
3473src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3474 platform. If they are unavailable, using them will raise a\n\
3475 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Barry Warsaw53699e91996-12-10 23:23:01 +00003477static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003479{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 path_t src, dst;
3481 int src_dir_fd = DEFAULT_DIR_FD;
3482 int dst_dir_fd = DEFAULT_DIR_FD;
3483 int follow_symlinks = 1;
3484 PyObject *return_value = NULL;
3485 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3486 "follow_symlinks", NULL};
3487#ifdef MS_WINDOWS
3488 BOOL result;
3489#else
3490 int result;
3491#endif
3492
3493 memset(&src, 0, sizeof(src));
3494 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003495 src.function_name = "link";
3496 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3498 path_converter, &src,
3499 path_converter, &dst,
3500 dir_fd_converter, &src_dir_fd,
3501 dir_fd_converter, &dst_dir_fd,
3502 &follow_symlinks))
3503 return NULL;
3504
3505#ifndef HAVE_LINKAT
3506 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3507 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3508 goto exit;
3509 }
3510#endif
3511
3512 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3513 PyErr_SetString(PyExc_NotImplementedError,
3514 "link: src and dst must be the same type");
3515 goto exit;
3516 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003517
Brian Curtin1b9df392010-11-24 20:24:31 +00003518#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_BEGIN_ALLOW_THREADS
3520 if (src.wide)
3521 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3522 else
3523 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3524 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003525
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003527 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003529 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530#else
3531 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003532#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3534 (dst_dir_fd != DEFAULT_DIR_FD) ||
3535 (!follow_symlinks))
3536 result = linkat(src_dir_fd, src.narrow,
3537 dst_dir_fd, dst.narrow,
3538 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3539 else
3540#endif
3541 result = link(src.narrow, dst.narrow);
3542 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003543
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003545 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003547 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548#endif
3549
3550 return_value = Py_None;
3551 Py_INCREF(Py_None);
3552
3553exit:
3554 path_cleanup(&src);
3555 path_cleanup(&dst);
3556 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003557}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558#endif
3559
Brian Curtin1b9df392010-11-24 20:24:31 +00003560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003562PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003563"listdir(path='.') -> list_of_filenames\n\n\
3564Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003565The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566entries '.' and '..' even if they are present in the directory.\n\
3567\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003568path can be specified as either str or bytes. If path is bytes,\n\
3569 the filenames returned will also be bytes; in all other circumstances\n\
3570 the filenames returned will be str.\n\
3571On some platforms, path may also be specified as an open file descriptor;\n\
3572 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003574
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003575#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003576static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003577_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 PyObject *v;
3581 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3582 BOOL result;
3583 WIN32_FIND_DATA FileData;
3584 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3585 char *bufptr = namebuf;
3586 /* only claim to have space for MAX_PATH */
3587 Py_ssize_t len = sizeof(namebuf)-5;
3588 PyObject *po = NULL;
3589 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003594
Gregory P. Smith40a21602013-03-20 20:52:50 -07003595 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003596 po_wchars = L".";
3597 len = 1;
3598 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003599 po_wchars = path->wide;
3600 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003601 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003603 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 if (!wnamebuf) {
3605 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003608 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003611 if (wch != SEP && wch != ALTSEP && wch != L':')
3612 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 wcscpy(wnamebuf + len, L"*.*");
3614 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 if ((list = PyList_New(0)) == NULL) {
3616 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003618 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003620 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 if (hFindFile == INVALID_HANDLE_VALUE) {
3622 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 if (error == ERROR_FILE_NOT_FOUND)
3624 goto exit;
3625 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 }
3629 do {
3630 /* Skip over . and .. */
3631 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3632 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 v = PyUnicode_FromWideChar(wFileData.cFileName,
3634 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 Py_DECREF(list);
3637 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 break;
3639 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 Py_DECREF(list);
3643 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 break;
3645 }
3646 Py_DECREF(v);
3647 }
3648 Py_BEGIN_ALLOW_THREADS
3649 result = FindNextFileW(hFindFile, &wFileData);
3650 Py_END_ALLOW_THREADS
3651 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3652 it got to the end of the directory. */
3653 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003655 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 }
3658 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003659
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003662 strcpy(namebuf, path->narrow);
3663 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 if (len > 0) {
3665 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003666 if (ch != '\\' && ch != '/' && ch != ':')
3667 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 strcpy(namebuf + len, "*.*");
3669 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003670
Larry Hastings9cf065c2012-06-22 16:30:09 -07003671 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003673
Antoine Pitroub73caab2010-08-09 23:39:31 +00003674 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003676 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (hFindFile == INVALID_HANDLE_VALUE) {
3678 int error = GetLastError();
3679 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 goto exit;
3681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 do {
3686 /* Skip over . and .. */
3687 if (strcmp(FileData.cFileName, ".") != 0 &&
3688 strcmp(FileData.cFileName, "..") != 0) {
3689 v = PyBytes_FromString(FileData.cFileName);
3690 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 Py_DECREF(list);
3692 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 break;
3694 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 Py_DECREF(list);
3698 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 break;
3700 }
3701 Py_DECREF(v);
3702 }
3703 Py_BEGIN_ALLOW_THREADS
3704 result = FindNextFile(hFindFile, &FileData);
3705 Py_END_ALLOW_THREADS
3706 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3707 it got to the end of the directory. */
3708 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003710 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 }
3713 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003714
Larry Hastings9cf065c2012-06-22 16:30:09 -07003715exit:
3716 if (hFindFile != INVALID_HANDLE_VALUE) {
3717 if (FindClose(hFindFile) == FALSE) {
3718 if (list != NULL) {
3719 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003720 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 }
3722 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003724 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003725
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003727} /* end of _listdir_windows_no_opendir */
3728
3729#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3730
3731static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003732_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003733{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003734 PyObject *v;
3735 DIR *dirp = NULL;
3736 struct dirent *ep;
3737 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003738#ifdef HAVE_FDOPENDIR
3739 int fd = -1;
3740#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003741
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003744 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003746 fd = _Py_dup(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 if (fd == -1) {
3748 list = posix_error();
3749 goto exit;
3750 }
3751
Larry Hastingsfdaea062012-06-25 04:42:23 -07003752 return_str = 1;
3753
Larry Hastings9cf065c2012-06-22 16:30:09 -07003754 Py_BEGIN_ALLOW_THREADS
3755 dirp = fdopendir(fd);
3756 Py_END_ALLOW_THREADS
3757 }
3758 else
3759#endif
3760 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003761 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003762 if (path->narrow) {
3763 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003764 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003765 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003766 }
3767 else {
3768 name = ".";
3769 return_str = 1;
3770 }
3771
Larry Hastings9cf065c2012-06-22 16:30:09 -07003772 Py_BEGIN_ALLOW_THREADS
3773 dirp = opendir(name);
3774 Py_END_ALLOW_THREADS
3775 }
3776
3777 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003778 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003779#ifdef HAVE_FDOPENDIR
3780 if (fd != -1) {
3781 Py_BEGIN_ALLOW_THREADS
3782 close(fd);
3783 Py_END_ALLOW_THREADS
3784 }
3785#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003786 goto exit;
3787 }
3788 if ((list = PyList_New(0)) == NULL) {
3789 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 }
3791 for (;;) {
3792 errno = 0;
3793 Py_BEGIN_ALLOW_THREADS
3794 ep = readdir(dirp);
3795 Py_END_ALLOW_THREADS
3796 if (ep == NULL) {
3797 if (errno == 0) {
3798 break;
3799 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003801 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003803 }
3804 }
3805 if (ep->d_name[0] == '.' &&
3806 (NAMLEN(ep) == 1 ||
3807 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3808 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003809 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003810 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3811 else
3812 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003814 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 break;
3816 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003817 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003819 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 break;
3821 }
3822 Py_DECREF(v);
3823 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003824
Larry Hastings9cf065c2012-06-22 16:30:09 -07003825exit:
3826 if (dirp != NULL) {
3827 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003828#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829 if (fd > -1)
3830 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003831#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 closedir(dirp);
3833 Py_END_ALLOW_THREADS
3834 }
3835
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003837} /* end of _posix_listdir */
3838#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003839
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003840static PyObject *
3841posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3842{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003843 path_t path;
3844 PyObject *list = NULL;
3845 static char *keywords[] = {"path", NULL};
3846 PyObject *return_value;
3847
3848 memset(&path, 0, sizeof(path));
3849 path.function_name = "listdir";
3850 path.nullable = 1;
3851#ifdef HAVE_FDOPENDIR
3852 path.allow_fd = 1;
3853 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003854#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003855
3856 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3857 path_converter, &path)) {
3858 return NULL;
3859 }
3860
3861#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3862 return_value = _listdir_windows_no_opendir(&path, list);
3863#else
3864 return_value = _posix_listdir(&path, list);
3865#endif
3866 path_cleanup(&path);
3867 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003868}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003869
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003870#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003871/* A helper function for abspath on win32 */
3872static PyObject *
3873posix__getfullpathname(PyObject *self, PyObject *args)
3874{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003875 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 char outbuf[MAX_PATH*2];
3877 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003878 PyObject *po;
3879
3880 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3881 {
3882 wchar_t *wpath;
3883 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3884 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 DWORD result;
3886 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003887
3888 wpath = PyUnicode_AsUnicode(po);
3889 if (wpath == NULL)
3890 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003892 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003894 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003895 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (!woutbufp)
3897 return PyErr_NoMemory();
3898 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3899 }
3900 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003901 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003903 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003904 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003905 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 return v;
3907 }
3908 /* Drop the argument parsing error as narrow strings
3909 are also valid. */
3910 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003911
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003912 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3913 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003915 if (win32_warn_bytes_api())
3916 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003917 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 outbuf, &temp)) {
3919 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 return NULL;
3921 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3923 return PyUnicode_Decode(outbuf, strlen(outbuf),
3924 Py_FileSystemDefaultEncoding, NULL);
3925 }
3926 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003927} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003928
Brian Curtind25aef52011-06-13 15:16:04 -05003929
Brian Curtinf5e76d02010-11-24 13:14:05 +00003930
Brian Curtind40e6f72010-07-08 21:39:08 +00003931/* A helper function for samepath on windows */
3932static PyObject *
3933posix__getfinalpathname(PyObject *self, PyObject *args)
3934{
3935 HANDLE hFile;
3936 int buf_size;
3937 wchar_t *target_path;
3938 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003939 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003940 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003941
Victor Stinnereb5657a2011-09-30 01:44:27 +02003942 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003943 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003944 path = PyUnicode_AsUnicode(po);
3945 if (path == NULL)
3946 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003947
3948 if(!check_GetFinalPathNameByHandle()) {
3949 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3950 NotImplementedError. */
3951 return PyErr_Format(PyExc_NotImplementedError,
3952 "GetFinalPathNameByHandle not available on this platform");
3953 }
3954
3955 hFile = CreateFileW(
3956 path,
3957 0, /* desired access */
3958 0, /* share mode */
3959 NULL, /* security attributes */
3960 OPEN_EXISTING,
3961 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3962 FILE_FLAG_BACKUP_SEMANTICS,
3963 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003964
Victor Stinnereb5657a2011-09-30 01:44:27 +02003965 if(hFile == INVALID_HANDLE_VALUE)
3966 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003967
3968 /* We have a good handle to the target, use it to determine the
3969 target path name. */
3970 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3971
3972 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003973 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003974
Victor Stinnerb6404912013-07-07 16:21:41 +02003975 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003976 if(!target_path)
3977 return PyErr_NoMemory();
3978
3979 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3980 buf_size, VOLUME_NAME_DOS);
3981 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003982 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003983
3984 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003985 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003986
3987 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003988 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003989 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003990 return result;
3991
3992} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003993
Brian Curtin95d028f2011-06-09 09:10:38 -05003994PyDoc_STRVAR(posix__isdir__doc__,
3995"Return true if the pathname refers to an existing directory.");
3996
Brian Curtin9c669cc2011-06-08 18:17:18 -05003997static PyObject *
3998posix__isdir(PyObject *self, PyObject *args)
3999{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004000 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004001 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004002 DWORD attributes;
4003
4004 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004005 wchar_t *wpath = PyUnicode_AsUnicode(po);
4006 if (wpath == NULL)
4007 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004008
4009 attributes = GetFileAttributesW(wpath);
4010 if (attributes == INVALID_FILE_ATTRIBUTES)
4011 Py_RETURN_FALSE;
4012 goto check;
4013 }
4014 /* Drop the argument parsing error as narrow strings
4015 are also valid. */
4016 PyErr_Clear();
4017
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004018 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004019 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004020 if (win32_warn_bytes_api())
4021 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004022 attributes = GetFileAttributesA(path);
4023 if (attributes == INVALID_FILE_ATTRIBUTES)
4024 Py_RETURN_FALSE;
4025
4026check:
4027 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4028 Py_RETURN_TRUE;
4029 else
4030 Py_RETURN_FALSE;
4031}
Tim Golden6b528062013-08-01 12:44:00 +01004032
4033PyDoc_STRVAR(posix__getvolumepathname__doc__,
4034"Return volume mount point of the specified path.");
4035
4036/* A helper function for ismount on windows */
4037static PyObject *
4038posix__getvolumepathname(PyObject *self, PyObject *args)
4039{
4040 PyObject *po, *result;
4041 wchar_t *path, *mountpath=NULL;
4042 size_t bufsize;
4043 BOOL ret;
4044
4045 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4046 return NULL;
4047 path = PyUnicode_AsUnicode(po);
4048 if (path == NULL)
4049 return NULL;
4050
4051 /* Volume path should be shorter than entire path */
4052 bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
4053 mountpath = (wchar_t *)PyMem_Malloc(bufsize);
4054 if (mountpath == NULL)
4055 return PyErr_NoMemory();
4056
4057 Py_BEGIN_ALLOW_THREADS
4058 ret = GetVolumePathNameW(path, mountpath, bufsize);
4059 Py_END_ALLOW_THREADS
4060
4061 if (!ret) {
4062 result = win32_error_object("_getvolumepathname", po);
4063 goto exit;
4064 }
4065 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4066
4067exit:
4068 PyMem_Free(mountpath);
4069 return result;
4070}
4071/* end of posix__getvolumepathname */
4072
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004073#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4077Create a directory.\n\
4078\n\
4079If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4080 and path should be relative; path will then be relative to that directory.\n\
4081dir_fd may not be implemented on your platform.\n\
4082 If it is unavailable, using it will raise a NotImplementedError.\n\
4083\n\
4084The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Barry Warsaw53699e91996-12-10 23:23:01 +00004086static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004088{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004090 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 int dir_fd = DEFAULT_DIR_FD;
4092 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4093 PyObject *return_value = NULL;
4094 int result;
4095
4096 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004097 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4099 path_converter, &path, &mode,
4100#ifdef HAVE_MKDIRAT
4101 dir_fd_converter, &dir_fd
4102#else
4103 dir_fd_unavailable, &dir_fd
4104#endif
4105 ))
4106 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004107
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004108#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004110 if (path.wide)
4111 result = CreateDirectoryW(path.wide, NULL);
4112 else
4113 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004115
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004117 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 goto exit;
4119 }
4120#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004121 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122#if HAVE_MKDIRAT
4123 if (dir_fd != DEFAULT_DIR_FD)
4124 result = mkdirat(dir_fd, path.narrow, mode);
4125 else
4126#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004127#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004129#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004132 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004134 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 goto exit;
4136 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138 return_value = Py_None;
4139 Py_INCREF(Py_None);
4140exit:
4141 path_cleanup(&path);
4142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143}
4144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004146/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4147#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004148#include <sys/resource.h>
4149#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004150
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004151
4152#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004153PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004154"nice(inc) -> new_priority\n\n\
4155Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004156
Barry Warsaw53699e91996-12-10 23:23:01 +00004157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004158posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004159{
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004161
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4163 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004164
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 /* There are two flavours of 'nice': one that returns the new
4166 priority (as required by almost all standards out there) and the
4167 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4168 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 If we are of the nice family that returns the new priority, we
4171 need to clear errno before the call, and check if errno is filled
4172 before calling posix_error() on a returnvalue of -1, because the
4173 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004174
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 errno = 0;
4176 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004177#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 if (value == 0)
4179 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004180#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004181 if (value == -1 && errno != 0)
4182 /* either nice() or getpriority() returned an error */
4183 return posix_error();
4184 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004185}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004186#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004187
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004188
4189#ifdef HAVE_GETPRIORITY
4190PyDoc_STRVAR(posix_getpriority__doc__,
4191"getpriority(which, who) -> current_priority\n\n\
4192Get program scheduling priority.");
4193
4194static PyObject *
4195posix_getpriority(PyObject *self, PyObject *args)
4196{
4197 int which, who, retval;
4198
4199 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4200 return NULL;
4201 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004202 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004203 if (errno != 0)
4204 return posix_error();
4205 return PyLong_FromLong((long)retval);
4206}
4207#endif /* HAVE_GETPRIORITY */
4208
4209
4210#ifdef HAVE_SETPRIORITY
4211PyDoc_STRVAR(posix_setpriority__doc__,
4212"setpriority(which, who, prio) -> None\n\n\
4213Set program scheduling priority.");
4214
4215static PyObject *
4216posix_setpriority(PyObject *self, PyObject *args)
4217{
4218 int which, who, prio, retval;
4219
4220 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4221 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004222 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004223 if (retval == -1)
4224 return posix_error();
4225 Py_RETURN_NONE;
4226}
4227#endif /* HAVE_SETPRIORITY */
4228
4229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004232{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233 char *function_name = is_replace ? "replace" : "rename";
4234 path_t src;
4235 path_t dst;
4236 int src_dir_fd = DEFAULT_DIR_FD;
4237 int dst_dir_fd = DEFAULT_DIR_FD;
4238 int dir_fd_specified;
4239 PyObject *return_value = NULL;
4240 char format[24];
4241 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4242
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004243#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004245 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004246#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004247 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004248#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004249
4250 memset(&src, 0, sizeof(src));
4251 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004252 src.function_name = function_name;
4253 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 strcpy(format, "O&O&|$O&O&:");
4255 strcat(format, function_name);
4256 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4257 path_converter, &src,
4258 path_converter, &dst,
4259 dir_fd_converter, &src_dir_fd,
4260 dir_fd_converter, &dst_dir_fd))
4261 return NULL;
4262
4263 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4264 (dst_dir_fd != DEFAULT_DIR_FD);
4265#ifndef HAVE_RENAMEAT
4266 if (dir_fd_specified) {
4267 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4268 goto exit;
4269 }
4270#endif
4271
4272 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4273 PyErr_Format(PyExc_ValueError,
4274 "%s: src and dst must be the same type", function_name);
4275 goto exit;
4276 }
4277
4278#ifdef MS_WINDOWS
4279 Py_BEGIN_ALLOW_THREADS
4280 if (src.wide)
4281 result = MoveFileExW(src.wide, dst.wide, flags);
4282 else
4283 result = MoveFileExA(src.narrow, dst.narrow, flags);
4284 Py_END_ALLOW_THREADS
4285
4286 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004287 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288 goto exit;
4289 }
4290
4291#else
4292 Py_BEGIN_ALLOW_THREADS
4293#ifdef HAVE_RENAMEAT
4294 if (dir_fd_specified)
4295 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4296 else
4297#endif
4298 result = rename(src.narrow, dst.narrow);
4299 Py_END_ALLOW_THREADS
4300
4301 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004302 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303 goto exit;
4304 }
4305#endif
4306
4307 Py_INCREF(Py_None);
4308 return_value = Py_None;
4309exit:
4310 path_cleanup(&src);
4311 path_cleanup(&dst);
4312 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004313}
4314
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004315PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4317Rename a file or directory.\n\
4318\n\
4319If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4320 descriptor open to a directory, and the respective path string (src or dst)\n\
4321 should be relative; the path will then be relative to that directory.\n\
4322src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4323 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004324
4325static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004327{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004328 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004329}
4330
4331PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4333Rename a file or directory, overwriting the destination.\n\
4334\n\
4335If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4336 descriptor open to a directory, and the respective path string (src or dst)\n\
4337 should be relative; the path will then be relative to that directory.\n\
4338src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4339 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004340
4341static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004342posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004343{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004344 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004345}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004347PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004348"rmdir(path, *, dir_fd=None)\n\n\
4349Remove a directory.\n\
4350\n\
4351If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4352 and path should be relative; path will then be relative to that directory.\n\
4353dir_fd may not be implemented on your platform.\n\
4354 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004355
Barry Warsaw53699e91996-12-10 23:23:01 +00004356static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004357posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004358{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004359 path_t path;
4360 int dir_fd = DEFAULT_DIR_FD;
4361 static char *keywords[] = {"path", "dir_fd", NULL};
4362 int result;
4363 PyObject *return_value = NULL;
4364
4365 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004366 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004367 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4368 path_converter, &path,
4369#ifdef HAVE_UNLINKAT
4370 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004371#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004372 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004373#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004374 ))
4375 return NULL;
4376
4377 Py_BEGIN_ALLOW_THREADS
4378#ifdef MS_WINDOWS
4379 if (path.wide)
4380 result = RemoveDirectoryW(path.wide);
4381 else
4382 result = RemoveDirectoryA(path.narrow);
4383 result = !result; /* Windows, success=1, UNIX, success=0 */
4384#else
4385#ifdef HAVE_UNLINKAT
4386 if (dir_fd != DEFAULT_DIR_FD)
4387 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4388 else
4389#endif
4390 result = rmdir(path.narrow);
4391#endif
4392 Py_END_ALLOW_THREADS
4393
4394 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004395 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004396 goto exit;
4397 }
4398
4399 return_value = Py_None;
4400 Py_INCREF(Py_None);
4401
4402exit:
4403 path_cleanup(&path);
4404 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004405}
4406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004408#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004409PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004410"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004411Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Barry Warsaw53699e91996-12-10 23:23:01 +00004413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004414posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415{
Victor Stinner8c62be82010-05-06 00:08:46 +00004416 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004418 wchar_t *command;
4419 if (!PyArg_ParseTuple(args, "u:system", &command))
4420 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004421
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 Py_BEGIN_ALLOW_THREADS
4423 sts = _wsystem(command);
4424 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004425#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 PyObject *command_obj;
4427 char *command;
4428 if (!PyArg_ParseTuple(args, "O&:system",
4429 PyUnicode_FSConverter, &command_obj))
4430 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004431
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 command = PyBytes_AsString(command_obj);
4433 Py_BEGIN_ALLOW_THREADS
4434 sts = system(command);
4435 Py_END_ALLOW_THREADS
4436 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004437#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004439}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004440#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004444"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
Barry Warsaw53699e91996-12-10 23:23:01 +00004447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004448posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004449{
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 int i;
4451 if (!PyArg_ParseTuple(args, "i:umask", &i))
4452 return NULL;
4453 i = (int)umask(i);
4454 if (i < 0)
4455 return posix_error();
4456 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004457}
4458
Brian Curtind40e6f72010-07-08 21:39:08 +00004459#ifdef MS_WINDOWS
4460
4461/* override the default DeleteFileW behavior so that directory
4462symlinks can be removed with this function, the same as with
4463Unix symlinks */
4464BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4465{
4466 WIN32_FILE_ATTRIBUTE_DATA info;
4467 WIN32_FIND_DATAW find_data;
4468 HANDLE find_data_handle;
4469 int is_directory = 0;
4470 int is_link = 0;
4471
4472 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4473 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004474
Brian Curtind40e6f72010-07-08 21:39:08 +00004475 /* Get WIN32_FIND_DATA structure for the path to determine if
4476 it is a symlink */
4477 if(is_directory &&
4478 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4479 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4480
4481 if(find_data_handle != INVALID_HANDLE_VALUE) {
4482 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4483 FindClose(find_data_handle);
4484 }
4485 }
4486 }
4487
4488 if (is_directory && is_link)
4489 return RemoveDirectoryW(lpFileName);
4490
4491 return DeleteFileW(lpFileName);
4492}
4493#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004495PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004496"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497Remove a file (same as remove()).\n\
4498\n\
4499If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4500 and path should be relative; path will then be relative to that directory.\n\
4501dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004502 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004503
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004505"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506Remove a file (same as unlink()).\n\
4507\n\
4508If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4509 and path should be relative; path will then be relative to that directory.\n\
4510dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004511 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Barry Warsaw53699e91996-12-10 23:23:01 +00004513static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004515{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 path_t path;
4517 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004518 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519 int result;
4520 PyObject *return_value = NULL;
4521
4522 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004523 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525 path_converter, &path,
4526#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004527 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004528#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004529 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004530#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004531 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 return NULL;
4533
4534 Py_BEGIN_ALLOW_THREADS
4535#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004536 if (path.wide)
4537 result = Py_DeleteFileW(path.wide);
4538 else
4539 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 result = !result; /* Windows, success=1, UNIX, success=0 */
4541#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542#ifdef HAVE_UNLINKAT
4543 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004544 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545 else
4546#endif /* HAVE_UNLINKAT */
4547 result = unlink(path.narrow);
4548#endif
4549 Py_END_ALLOW_THREADS
4550
4551 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004552 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 goto exit;
4554 }
4555
4556 return_value = Py_None;
4557 Py_INCREF(Py_None);
4558
4559exit:
4560 path_cleanup(&path);
4561 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004562}
4563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004565PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004566"uname() -> uname_result\n\n\
4567Return an object identifying the current operating system.\n\
4568The object behaves like a named tuple with the following fields:\n\
4569 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Larry Hastings605a62d2012-06-24 04:33:36 -07004571static PyStructSequence_Field uname_result_fields[] = {
4572 {"sysname", "operating system name"},
4573 {"nodename", "name of machine on network (implementation-defined)"},
4574 {"release", "operating system release"},
4575 {"version", "operating system version"},
4576 {"machine", "hardware identifier"},
4577 {NULL}
4578};
4579
4580PyDoc_STRVAR(uname_result__doc__,
4581"uname_result: Result from os.uname().\n\n\
4582This object may be accessed either as a tuple of\n\
4583 (sysname, nodename, release, version, machine),\n\
4584or via the attributes sysname, nodename, release, version, and machine.\n\
4585\n\
4586See os.uname for more information.");
4587
4588static PyStructSequence_Desc uname_result_desc = {
4589 "uname_result", /* name */
4590 uname_result__doc__, /* doc */
4591 uname_result_fields,
4592 5
4593};
4594
4595static PyTypeObject UnameResultType;
4596
4597
4598#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004599static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004600posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004601{
Victor Stinner8c62be82010-05-06 00:08:46 +00004602 struct utsname u;
4603 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004604 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004605
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 Py_BEGIN_ALLOW_THREADS
4607 res = uname(&u);
4608 Py_END_ALLOW_THREADS
4609 if (res < 0)
4610 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004611
4612 value = PyStructSequence_New(&UnameResultType);
4613 if (value == NULL)
4614 return NULL;
4615
4616#define SET(i, field) \
4617 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004618 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004619 if (!o) { \
4620 Py_DECREF(value); \
4621 return NULL; \
4622 } \
4623 PyStructSequence_SET_ITEM(value, i, o); \
4624 } \
4625
4626 SET(0, u.sysname);
4627 SET(1, u.nodename);
4628 SET(2, u.release);
4629 SET(3, u.version);
4630 SET(4, u.machine);
4631
4632#undef SET
4633
4634 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004636#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004637
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004638
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639PyDoc_STRVAR(posix_utime__doc__,
4640"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4641Set the access and modified time of path.\n\
4642\n\
4643path may always be specified as a string.\n\
4644On some platforms, path may also be specified as an open file descriptor.\n\
4645 If this functionality is unavailable, using it raises an exception.\n\
4646\n\
4647If times is not None, it must be a tuple (atime, mtime);\n\
4648 atime and mtime should be expressed as float seconds since the epoch.\n\
4649If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4650 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4651 since the epoch.\n\
4652If both times and ns are None, utime uses the current time.\n\
4653Specifying tuples for both times and ns is an error.\n\
4654\n\
4655If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4656 and path should be relative; path will then be relative to that directory.\n\
4657If follow_symlinks is False, and the last element of the path is a symbolic\n\
4658 link, utime will modify the symbolic link itself instead of the file the\n\
4659 link points to.\n\
4660It is an error to use dir_fd or follow_symlinks when specifying path\n\
4661 as an open file descriptor.\n\
4662dir_fd and follow_symlinks may not be available on your platform.\n\
4663 If they are unavailable, using them will raise a NotImplementedError.");
4664
4665typedef struct {
4666 int now;
4667 time_t atime_s;
4668 long atime_ns;
4669 time_t mtime_s;
4670 long mtime_ns;
4671} utime_t;
4672
4673/*
4674 * these macros assume that "utime" is a pointer to a utime_t
4675 * they also intentionally leak the declaration of a pointer named "time"
4676 */
4677#define UTIME_TO_TIMESPEC \
4678 struct timespec ts[2]; \
4679 struct timespec *time; \
4680 if (utime->now) \
4681 time = NULL; \
4682 else { \
4683 ts[0].tv_sec = utime->atime_s; \
4684 ts[0].tv_nsec = utime->atime_ns; \
4685 ts[1].tv_sec = utime->mtime_s; \
4686 ts[1].tv_nsec = utime->mtime_ns; \
4687 time = ts; \
4688 } \
4689
4690#define UTIME_TO_TIMEVAL \
4691 struct timeval tv[2]; \
4692 struct timeval *time; \
4693 if (utime->now) \
4694 time = NULL; \
4695 else { \
4696 tv[0].tv_sec = utime->atime_s; \
4697 tv[0].tv_usec = utime->atime_ns / 1000; \
4698 tv[1].tv_sec = utime->mtime_s; \
4699 tv[1].tv_usec = utime->mtime_ns / 1000; \
4700 time = tv; \
4701 } \
4702
4703#define UTIME_TO_UTIMBUF \
4704 struct utimbuf u[2]; \
4705 struct utimbuf *time; \
4706 if (utime->now) \
4707 time = NULL; \
4708 else { \
4709 u.actime = utime->atime_s; \
4710 u.modtime = utime->mtime_s; \
4711 time = u; \
4712 }
4713
4714#define UTIME_TO_TIME_T \
4715 time_t timet[2]; \
4716 struct timet time; \
4717 if (utime->now) \
4718 time = NULL; \
4719 else { \
4720 timet[0] = utime->atime_s; \
4721 timet[1] = utime->mtime_s; \
4722 time = &timet; \
4723 } \
4724
4725
4726#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4727
4728#if UTIME_HAVE_DIR_FD
4729
4730static int
4731utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4732{
4733#ifdef HAVE_UTIMENSAT
4734 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4735 UTIME_TO_TIMESPEC;
4736 return utimensat(dir_fd, path, time, flags);
4737#elif defined(HAVE_FUTIMESAT)
4738 UTIME_TO_TIMEVAL;
4739 /*
4740 * follow_symlinks will never be false here;
4741 * we only allow !follow_symlinks and dir_fd together
4742 * if we have utimensat()
4743 */
4744 assert(follow_symlinks);
4745 return futimesat(dir_fd, path, time);
4746#endif
4747}
4748
4749#endif
4750
4751#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4752
4753#if UTIME_HAVE_FD
4754
4755static int
4756utime_fd(utime_t *utime, int fd)
4757{
4758#ifdef HAVE_FUTIMENS
4759 UTIME_TO_TIMESPEC;
4760 return futimens(fd, time);
4761#else
4762 UTIME_TO_TIMEVAL;
4763 return futimes(fd, time);
4764#endif
4765}
4766
4767#endif
4768
4769
4770#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4771 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4772
4773#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4774
4775static int
4776utime_nofollow_symlinks(utime_t *utime, char *path)
4777{
4778#ifdef HAVE_UTIMENSAT
4779 UTIME_TO_TIMESPEC;
4780 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4781#else
4782 UTIME_TO_TIMEVAL;
4783 return lutimes(path, time);
4784#endif
4785}
4786
4787#endif
4788
4789#ifndef MS_WINDOWS
4790
4791static int
4792utime_default(utime_t *utime, char *path)
4793{
4794#ifdef HAVE_UTIMENSAT
4795 UTIME_TO_TIMESPEC;
4796 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4797#elif defined(HAVE_UTIMES)
4798 UTIME_TO_TIMEVAL;
4799 return utimes(path, time);
4800#elif defined(HAVE_UTIME_H)
4801 UTIME_TO_UTIMBUF;
4802 return utime(path, time);
4803#else
4804 UTIME_TO_TIME_T;
4805 return utime(path, time);
4806#endif
4807}
4808
4809#endif
4810
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811static int
4812split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4813{
4814 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004815 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004816 divmod = PyNumber_Divmod(py_long, billion);
4817 if (!divmod)
4818 goto exit;
4819 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4820 if ((*s == -1) && PyErr_Occurred())
4821 goto exit;
4822 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004823 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004824 goto exit;
4825
4826 result = 1;
4827exit:
4828 Py_XDECREF(divmod);
4829 return result;
4830}
4831
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832static PyObject *
4833posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004834{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004836 PyObject *times = NULL;
4837 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 int dir_fd = DEFAULT_DIR_FD;
4839 int follow_symlinks = 1;
4840 char *keywords[] = {"path", "times", "ns", "dir_fd",
4841 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004842
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004844
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845#ifdef MS_WINDOWS
4846 HANDLE hFile;
4847 FILETIME atime, mtime;
4848#else
4849 int result;
4850#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004851
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004853
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004855 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004856 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857#if UTIME_HAVE_FD
4858 path.allow_fd = 1;
4859#endif
4860 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4861 "O&|O$OO&p:utime", keywords,
4862 path_converter, &path,
4863 &times, &ns,
4864#if UTIME_HAVE_DIR_FD
4865 dir_fd_converter, &dir_fd,
4866#else
4867 dir_fd_unavailable, &dir_fd,
4868#endif
4869 &follow_symlinks
4870 ))
4871 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872
Larry Hastings9cf065c2012-06-22 16:30:09 -07004873 if (times && (times != Py_None) && ns) {
4874 PyErr_SetString(PyExc_ValueError,
4875 "utime: you may specify either 'times'"
4876 " or 'ns' but not both");
4877 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004878 }
4879
4880 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004881 time_t a_sec, m_sec;
4882 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004883 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004884 PyErr_SetString(PyExc_TypeError,
4885 "utime: 'times' must be either"
4886 " a tuple of two ints or None");
4887 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004890 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004891 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004892 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004893 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004895 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004896 utime.atime_s = a_sec;
4897 utime.atime_ns = a_nsec;
4898 utime.mtime_s = m_sec;
4899 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004900 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004901 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004902 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903 PyErr_SetString(PyExc_TypeError,
4904 "utime: 'ns' must be a tuple of two ints");
4905 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004906 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004908 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004910 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 &utime.mtime_s, &utime.mtime_ns)) {
4912 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004913 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 }
4915 else {
4916 /* times and ns are both None/unspecified. use "now". */
4917 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004918 }
4919
Larry Hastings9cf065c2012-06-22 16:30:09 -07004920#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4921 if (follow_symlinks_specified("utime", follow_symlinks))
4922 goto exit;
4923#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004924
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4926 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4927 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4928 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004929
Larry Hastings9cf065c2012-06-22 16:30:09 -07004930#if !defined(HAVE_UTIMENSAT)
4931 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004932 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933 "utime: cannot use dir_fd and follow_symlinks "
4934 "together on this platform");
4935 goto exit;
4936 }
4937#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004938
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004939#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004940 Py_BEGIN_ALLOW_THREADS
4941 if (path.wide)
4942 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 NULL, OPEN_EXISTING,
4944 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004945 else
4946 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 NULL, OPEN_EXISTING,
4948 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 Py_END_ALLOW_THREADS
4950 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004951 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004953 }
4954
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 SYSTEMTIME now;
4957 GetSystemTime(&now);
4958 if (!SystemTimeToFileTime(&now, &mtime) ||
4959 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004960 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004962 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4966 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 }
4968 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4969 /* Avoid putting the file name into the error here,
4970 as that may confuse the user into believing that
4971 something is wrong with the file, when it also
4972 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004973 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004976#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004977 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004978
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4980 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4981 result = utime_nofollow_symlinks(&utime, path.narrow);
4982 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004983#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984
4985#if UTIME_HAVE_DIR_FD
4986 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4987 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4988 else
4989#endif
4990
4991#if UTIME_HAVE_FD
4992 if (path.fd != -1)
4993 result = utime_fd(&utime, path.fd);
4994 else
4995#endif
4996
4997 result = utime_default(&utime, path.narrow);
4998
4999 Py_END_ALLOW_THREADS
5000
5001 if (result < 0) {
5002 /* see previous comment about not putting filename in error here */
5003 return_value = posix_error();
5004 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005006
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005007#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005008
5009 Py_INCREF(Py_None);
5010 return_value = Py_None;
5011
5012exit:
5013 path_cleanup(&path);
5014#ifdef MS_WINDOWS
5015 if (hFile != INVALID_HANDLE_VALUE)
5016 CloseHandle(hFile);
5017#endif
5018 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005019}
5020
Guido van Rossum3b066191991-06-04 19:40:25 +00005021/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005022
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005023PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005024"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005025Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005026
Barry Warsaw53699e91996-12-10 23:23:01 +00005027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005028posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005029{
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 int sts;
5031 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5032 return NULL;
5033 _exit(sts);
5034 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005035}
5036
Martin v. Löwis114619e2002-10-07 06:44:21 +00005037#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5038static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005039free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005040{
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 Py_ssize_t i;
5042 for (i = 0; i < count; i++)
5043 PyMem_Free(array[i]);
5044 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005045}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005046
Antoine Pitrou69f71142009-05-24 21:25:49 +00005047static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005048int fsconvert_strdup(PyObject *o, char**out)
5049{
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 PyObject *bytes;
5051 Py_ssize_t size;
5052 if (!PyUnicode_FSConverter(o, &bytes))
5053 return 0;
5054 size = PyBytes_GET_SIZE(bytes);
5055 *out = PyMem_Malloc(size+1);
5056 if (!*out)
5057 return 0;
5058 memcpy(*out, PyBytes_AsString(bytes), size+1);
5059 Py_DECREF(bytes);
5060 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005061}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005062#endif
5063
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005065static char**
5066parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5067{
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 char **envlist;
5069 Py_ssize_t i, pos, envc;
5070 PyObject *keys=NULL, *vals=NULL;
5071 PyObject *key, *val, *key2, *val2;
5072 char *p, *k, *v;
5073 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 i = PyMapping_Size(env);
5076 if (i < 0)
5077 return NULL;
5078 envlist = PyMem_NEW(char *, i + 1);
5079 if (envlist == NULL) {
5080 PyErr_NoMemory();
5081 return NULL;
5082 }
5083 envc = 0;
5084 keys = PyMapping_Keys(env);
5085 vals = PyMapping_Values(env);
5086 if (!keys || !vals)
5087 goto error;
5088 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5089 PyErr_Format(PyExc_TypeError,
5090 "env.keys() or env.values() is not a list");
5091 goto error;
5092 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005093
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 for (pos = 0; pos < i; pos++) {
5095 key = PyList_GetItem(keys, pos);
5096 val = PyList_GetItem(vals, pos);
5097 if (!key || !val)
5098 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005099
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 if (PyUnicode_FSConverter(key, &key2) == 0)
5101 goto error;
5102 if (PyUnicode_FSConverter(val, &val2) == 0) {
5103 Py_DECREF(key2);
5104 goto error;
5105 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005106
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 k = PyBytes_AsString(key2);
5108 v = PyBytes_AsString(val2);
5109 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 p = PyMem_NEW(char, len);
5112 if (p == NULL) {
5113 PyErr_NoMemory();
5114 Py_DECREF(key2);
5115 Py_DECREF(val2);
5116 goto error;
5117 }
5118 PyOS_snprintf(p, len, "%s=%s", k, v);
5119 envlist[envc++] = p;
5120 Py_DECREF(key2);
5121 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 }
5123 Py_DECREF(vals);
5124 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 envlist[envc] = 0;
5127 *envc_ptr = envc;
5128 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005129
5130error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 Py_XDECREF(keys);
5132 Py_XDECREF(vals);
5133 while (--envc >= 0)
5134 PyMem_DEL(envlist[envc]);
5135 PyMem_DEL(envlist);
5136 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005137}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005138
Ross Lagerwall7807c352011-03-17 20:20:30 +02005139static char**
5140parse_arglist(PyObject* argv, Py_ssize_t *argc)
5141{
5142 int i;
5143 char **argvlist = PyMem_NEW(char *, *argc+1);
5144 if (argvlist == NULL) {
5145 PyErr_NoMemory();
5146 return NULL;
5147 }
5148 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005149 PyObject* item = PySequence_ITEM(argv, i);
5150 if (item == NULL)
5151 goto fail;
5152 if (!fsconvert_strdup(item, &argvlist[i])) {
5153 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154 goto fail;
5155 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005156 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005157 }
5158 argvlist[*argc] = NULL;
5159 return argvlist;
5160fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005161 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005162 free_string_array(argvlist, *argc);
5163 return NULL;
5164}
5165#endif
5166
5167#ifdef HAVE_EXECV
5168PyDoc_STRVAR(posix_execv__doc__,
5169"execv(path, args)\n\n\
5170Execute an executable path with arguments, replacing current process.\n\
5171\n\
5172 path: path of executable file\n\
5173 args: tuple or list of strings");
5174
5175static PyObject *
5176posix_execv(PyObject *self, PyObject *args)
5177{
5178 PyObject *opath;
5179 char *path;
5180 PyObject *argv;
5181 char **argvlist;
5182 Py_ssize_t argc;
5183
5184 /* execv has two arguments: (path, argv), where
5185 argv is a list or tuple of strings. */
5186
5187 if (!PyArg_ParseTuple(args, "O&O:execv",
5188 PyUnicode_FSConverter,
5189 &opath, &argv))
5190 return NULL;
5191 path = PyBytes_AsString(opath);
5192 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5193 PyErr_SetString(PyExc_TypeError,
5194 "execv() arg 2 must be a tuple or list");
5195 Py_DECREF(opath);
5196 return NULL;
5197 }
5198 argc = PySequence_Size(argv);
5199 if (argc < 1) {
5200 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5201 Py_DECREF(opath);
5202 return NULL;
5203 }
5204
5205 argvlist = parse_arglist(argv, &argc);
5206 if (argvlist == NULL) {
5207 Py_DECREF(opath);
5208 return NULL;
5209 }
5210
5211 execv(path, argvlist);
5212
5213 /* If we get here it's definitely an error */
5214
5215 free_string_array(argvlist, argc);
5216 Py_DECREF(opath);
5217 return posix_error();
5218}
5219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005220PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005221"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005222Execute a path with arguments and environment, replacing current process.\n\
5223\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 path: path of executable file\n\
5225 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005226 env: dictionary of strings mapping to strings\n\
5227\n\
5228On some platforms, you may specify an open file descriptor for path;\n\
5229 execve will execute the program the file descriptor is open to.\n\
5230 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Barry Warsaw53699e91996-12-10 23:23:01 +00005232static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005233posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005234{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005235 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005237 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005239 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005240 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005241
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 /* execve has three arguments: (path, argv, env), where
5243 argv is a list or tuple of strings and env is a dictionary
5244 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005245
Larry Hastings9cf065c2012-06-22 16:30:09 -07005246 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005247 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005248#ifdef HAVE_FEXECVE
5249 path.allow_fd = 1;
5250#endif
5251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5252 path_converter, &path,
5253 &argv, &env
5254 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005256
Ross Lagerwall7807c352011-03-17 20:20:30 +02005257 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005259 "execve: argv must be a tuple or list");
5260 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005262 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 if (!PyMapping_Check(env)) {
5264 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005265 "execve: environment must be a mapping object");
5266 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005268
Ross Lagerwall7807c352011-03-17 20:20:30 +02005269 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005271 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 envlist = parse_envlist(env, &envc);
5275 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005276 goto fail;
5277
Larry Hastings9cf065c2012-06-22 16:30:09 -07005278#ifdef HAVE_FEXECVE
5279 if (path.fd > -1)
5280 fexecve(path.fd, argvlist, envlist);
5281 else
5282#endif
5283 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005284
5285 /* If we get here it's definitely an error */
5286
Victor Stinner292c8352012-10-30 02:17:38 +01005287 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005288
5289 while (--envc >= 0)
5290 PyMem_DEL(envlist[envc]);
5291 PyMem_DEL(envlist);
5292 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005293 if (argvlist)
5294 free_string_array(argvlist, argc);
5295 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005296 return NULL;
5297}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005298#endif /* HAVE_EXECV */
5299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005300
Guido van Rossuma1065681999-01-25 23:20:23 +00005301#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005304Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005305\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 mode: mode of process creation\n\
5307 path: path of executable file\n\
5308 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005309
5310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005311posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005312{
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 PyObject *opath;
5314 char *path;
5315 PyObject *argv;
5316 char **argvlist;
5317 int mode, i;
5318 Py_ssize_t argc;
5319 Py_intptr_t spawnval;
5320 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005321
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 /* spawnv has three arguments: (mode, path, argv), where
5323 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005324
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5326 PyUnicode_FSConverter,
5327 &opath, &argv))
5328 return NULL;
5329 path = PyBytes_AsString(opath);
5330 if (PyList_Check(argv)) {
5331 argc = PyList_Size(argv);
5332 getitem = PyList_GetItem;
5333 }
5334 else if (PyTuple_Check(argv)) {
5335 argc = PyTuple_Size(argv);
5336 getitem = PyTuple_GetItem;
5337 }
5338 else {
5339 PyErr_SetString(PyExc_TypeError,
5340 "spawnv() arg 2 must be a tuple or list");
5341 Py_DECREF(opath);
5342 return NULL;
5343 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005344
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 argvlist = PyMem_NEW(char *, argc+1);
5346 if (argvlist == NULL) {
5347 Py_DECREF(opath);
5348 return PyErr_NoMemory();
5349 }
5350 for (i = 0; i < argc; i++) {
5351 if (!fsconvert_strdup((*getitem)(argv, i),
5352 &argvlist[i])) {
5353 free_string_array(argvlist, i);
5354 PyErr_SetString(
5355 PyExc_TypeError,
5356 "spawnv() arg 2 must contain only strings");
5357 Py_DECREF(opath);
5358 return NULL;
5359 }
5360 }
5361 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005362
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 if (mode == _OLD_P_OVERLAY)
5364 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005365
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 Py_BEGIN_ALLOW_THREADS
5367 spawnval = _spawnv(mode, path, argvlist);
5368 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005369
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 free_string_array(argvlist, argc);
5371 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005372
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 if (spawnval == -1)
5374 return posix_error();
5375 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005376 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005377}
5378
5379
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005382Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005383\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005384 mode: mode of process creation\n\
5385 path: path of executable file\n\
5386 args: tuple or list of arguments\n\
5387 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005388
5389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005390posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005391{
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 PyObject *opath;
5393 char *path;
5394 PyObject *argv, *env;
5395 char **argvlist;
5396 char **envlist;
5397 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005398 int mode;
5399 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 Py_intptr_t spawnval;
5401 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5402 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005403
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 /* spawnve has four arguments: (mode, path, argv, env), where
5405 argv is a list or tuple of strings and env is a dictionary
5406 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005407
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5409 PyUnicode_FSConverter,
5410 &opath, &argv, &env))
5411 return NULL;
5412 path = PyBytes_AsString(opath);
5413 if (PyList_Check(argv)) {
5414 argc = PyList_Size(argv);
5415 getitem = PyList_GetItem;
5416 }
5417 else if (PyTuple_Check(argv)) {
5418 argc = PyTuple_Size(argv);
5419 getitem = PyTuple_GetItem;
5420 }
5421 else {
5422 PyErr_SetString(PyExc_TypeError,
5423 "spawnve() arg 2 must be a tuple or list");
5424 goto fail_0;
5425 }
5426 if (!PyMapping_Check(env)) {
5427 PyErr_SetString(PyExc_TypeError,
5428 "spawnve() arg 3 must be a mapping object");
5429 goto fail_0;
5430 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005431
Victor Stinner8c62be82010-05-06 00:08:46 +00005432 argvlist = PyMem_NEW(char *, argc+1);
5433 if (argvlist == NULL) {
5434 PyErr_NoMemory();
5435 goto fail_0;
5436 }
5437 for (i = 0; i < argc; i++) {
5438 if (!fsconvert_strdup((*getitem)(argv, i),
5439 &argvlist[i]))
5440 {
5441 lastarg = i;
5442 goto fail_1;
5443 }
5444 }
5445 lastarg = argc;
5446 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005447
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 envlist = parse_envlist(env, &envc);
5449 if (envlist == NULL)
5450 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005451
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 if (mode == _OLD_P_OVERLAY)
5453 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005454
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 Py_BEGIN_ALLOW_THREADS
5456 spawnval = _spawnve(mode, path, argvlist, envlist);
5457 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005458
Victor Stinner8c62be82010-05-06 00:08:46 +00005459 if (spawnval == -1)
5460 (void) posix_error();
5461 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005462 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005463
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 while (--envc >= 0)
5465 PyMem_DEL(envlist[envc]);
5466 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005467 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005468 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005469 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005470 Py_DECREF(opath);
5471 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005472}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005473
Guido van Rossuma1065681999-01-25 23:20:23 +00005474#endif /* HAVE_SPAWNV */
5475
5476
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005477#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005479"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005480Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5481\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005483
5484static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005485posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005486{
Victor Stinner8c62be82010-05-06 00:08:46 +00005487 pid_t pid;
5488 int result = 0;
5489 _PyImport_AcquireLock();
5490 pid = fork1();
5491 if (pid == 0) {
5492 /* child: this clobbers and resets the import lock. */
5493 PyOS_AfterFork();
5494 } else {
5495 /* parent: release the import lock. */
5496 result = _PyImport_ReleaseLock();
5497 }
5498 if (pid == -1)
5499 return posix_error();
5500 if (result < 0) {
5501 /* Don't clobber the OSError if the fork failed. */
5502 PyErr_SetString(PyExc_RuntimeError,
5503 "not holding the import lock");
5504 return NULL;
5505 }
5506 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005507}
5508#endif
5509
5510
Guido van Rossumad0ee831995-03-01 10:34:45 +00005511#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005513"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005514Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Barry Warsaw53699e91996-12-10 23:23:01 +00005517static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005518posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005519{
Victor Stinner8c62be82010-05-06 00:08:46 +00005520 pid_t pid;
5521 int result = 0;
5522 _PyImport_AcquireLock();
5523 pid = fork();
5524 if (pid == 0) {
5525 /* child: this clobbers and resets the import lock. */
5526 PyOS_AfterFork();
5527 } else {
5528 /* parent: release the import lock. */
5529 result = _PyImport_ReleaseLock();
5530 }
5531 if (pid == -1)
5532 return posix_error();
5533 if (result < 0) {
5534 /* Don't clobber the OSError if the fork failed. */
5535 PyErr_SetString(PyExc_RuntimeError,
5536 "not holding the import lock");
5537 return NULL;
5538 }
5539 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005540}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005541#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005542
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005543#ifdef HAVE_SCHED_H
5544
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005545#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5546
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5548"sched_get_priority_max(policy)\n\n\
5549Get the maximum scheduling priority for *policy*.");
5550
5551static PyObject *
5552posix_sched_get_priority_max(PyObject *self, PyObject *args)
5553{
5554 int policy, max;
5555
5556 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5557 return NULL;
5558 max = sched_get_priority_max(policy);
5559 if (max < 0)
5560 return posix_error();
5561 return PyLong_FromLong(max);
5562}
5563
5564PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5565"sched_get_priority_min(policy)\n\n\
5566Get the minimum scheduling priority for *policy*.");
5567
5568static PyObject *
5569posix_sched_get_priority_min(PyObject *self, PyObject *args)
5570{
5571 int policy, min;
5572
5573 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5574 return NULL;
5575 min = sched_get_priority_min(policy);
5576 if (min < 0)
5577 return posix_error();
5578 return PyLong_FromLong(min);
5579}
5580
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005581#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5582
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005583#ifdef HAVE_SCHED_SETSCHEDULER
5584
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005585PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5586"sched_getscheduler(pid)\n\n\
5587Get the scheduling policy for the process with a PID of *pid*.\n\
5588Passing a PID of 0 returns the scheduling policy for the calling process.");
5589
5590static PyObject *
5591posix_sched_getscheduler(PyObject *self, PyObject *args)
5592{
5593 pid_t pid;
5594 int policy;
5595
5596 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5597 return NULL;
5598 policy = sched_getscheduler(pid);
5599 if (policy < 0)
5600 return posix_error();
5601 return PyLong_FromLong(policy);
5602}
5603
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005604#endif
5605
5606#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5607
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005608static PyObject *
5609sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5610{
5611 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005612 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005613
5614 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5615 return NULL;
5616 res = PyStructSequence_New(type);
5617 if (!res)
5618 return NULL;
5619 Py_INCREF(priority);
5620 PyStructSequence_SET_ITEM(res, 0, priority);
5621 return res;
5622}
5623
5624PyDoc_STRVAR(sched_param__doc__,
5625"sched_param(sched_priority): A scheduling parameter.\n\n\
5626Current has only one field: sched_priority");
5627
5628static PyStructSequence_Field sched_param_fields[] = {
5629 {"sched_priority", "the scheduling priority"},
5630 {0}
5631};
5632
5633static PyStructSequence_Desc sched_param_desc = {
5634 "sched_param", /* name */
5635 sched_param__doc__, /* doc */
5636 sched_param_fields,
5637 1
5638};
5639
5640static int
5641convert_sched_param(PyObject *param, struct sched_param *res)
5642{
5643 long priority;
5644
5645 if (Py_TYPE(param) != &SchedParamType) {
5646 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5647 return 0;
5648 }
5649 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5650 if (priority == -1 && PyErr_Occurred())
5651 return 0;
5652 if (priority > INT_MAX || priority < INT_MIN) {
5653 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5654 return 0;
5655 }
5656 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5657 return 1;
5658}
5659
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005660#endif
5661
5662#ifdef HAVE_SCHED_SETSCHEDULER
5663
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005664PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5665"sched_setscheduler(pid, policy, param)\n\n\
5666Set the scheduling policy, *policy*, for *pid*.\n\
5667If *pid* is 0, the calling process is changed.\n\
5668*param* is an instance of sched_param.");
5669
5670static PyObject *
5671posix_sched_setscheduler(PyObject *self, PyObject *args)
5672{
5673 pid_t pid;
5674 int policy;
5675 struct sched_param param;
5676
5677 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5678 &pid, &policy, &convert_sched_param, &param))
5679 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005680
5681 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005682 ** sched_setscheduler() returns 0 in Linux, but the previous
5683 ** scheduling policy under Solaris/Illumos, and others.
5684 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005685 */
5686 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005687 return posix_error();
5688 Py_RETURN_NONE;
5689}
5690
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005691#endif
5692
5693#ifdef HAVE_SCHED_SETPARAM
5694
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005695PyDoc_STRVAR(posix_sched_getparam__doc__,
5696"sched_getparam(pid) -> sched_param\n\n\
5697Returns scheduling parameters for the process with *pid* as an instance of the\n\
5698sched_param class. A PID of 0 means the calling process.");
5699
5700static PyObject *
5701posix_sched_getparam(PyObject *self, PyObject *args)
5702{
5703 pid_t pid;
5704 struct sched_param param;
5705 PyObject *res, *priority;
5706
5707 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5708 return NULL;
5709 if (sched_getparam(pid, &param))
5710 return posix_error();
5711 res = PyStructSequence_New(&SchedParamType);
5712 if (!res)
5713 return NULL;
5714 priority = PyLong_FromLong(param.sched_priority);
5715 if (!priority) {
5716 Py_DECREF(res);
5717 return NULL;
5718 }
5719 PyStructSequence_SET_ITEM(res, 0, priority);
5720 return res;
5721}
5722
5723PyDoc_STRVAR(posix_sched_setparam__doc__,
5724"sched_setparam(pid, param)\n\n\
5725Set scheduling parameters for a process with PID *pid*.\n\
5726A PID of 0 means the calling process.");
5727
5728static PyObject *
5729posix_sched_setparam(PyObject *self, PyObject *args)
5730{
5731 pid_t pid;
5732 struct sched_param param;
5733
5734 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5735 &pid, &convert_sched_param, &param))
5736 return NULL;
5737 if (sched_setparam(pid, &param))
5738 return posix_error();
5739 Py_RETURN_NONE;
5740}
5741
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005742#endif
5743
5744#ifdef HAVE_SCHED_RR_GET_INTERVAL
5745
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005746PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5747"sched_rr_get_interval(pid) -> float\n\n\
5748Return the round-robin quantum for the process with PID *pid* in seconds.");
5749
5750static PyObject *
5751posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5752{
5753 pid_t pid;
5754 struct timespec interval;
5755
5756 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5757 return NULL;
5758 if (sched_rr_get_interval(pid, &interval))
5759 return posix_error();
5760 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5761}
5762
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005763#endif
5764
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005765PyDoc_STRVAR(posix_sched_yield__doc__,
5766"sched_yield()\n\n\
5767Voluntarily relinquish the CPU.");
5768
5769static PyObject *
5770posix_sched_yield(PyObject *self, PyObject *noargs)
5771{
5772 if (sched_yield())
5773 return posix_error();
5774 Py_RETURN_NONE;
5775}
5776
Benjamin Peterson2740af82011-08-02 17:41:34 -05005777#ifdef HAVE_SCHED_SETAFFINITY
5778
Antoine Pitrou84869872012-08-04 16:16:35 +02005779/* The minimum number of CPUs allocated in a cpu_set_t */
5780static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005781
5782PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5783"sched_setaffinity(pid, cpu_set)\n\n\
5784Set the affinity of the process with PID *pid* to *cpu_set*.");
5785
5786static PyObject *
5787posix_sched_setaffinity(PyObject *self, PyObject *args)
5788{
5789 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005790 int ncpus;
5791 size_t setsize;
5792 cpu_set_t *mask = NULL;
5793 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005794
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5796 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005798
5799 iterator = PyObject_GetIter(iterable);
5800 if (iterator == NULL)
5801 return NULL;
5802
5803 ncpus = NCPUS_START;
5804 setsize = CPU_ALLOC_SIZE(ncpus);
5805 mask = CPU_ALLOC(ncpus);
5806 if (mask == NULL) {
5807 PyErr_NoMemory();
5808 goto error;
5809 }
5810 CPU_ZERO_S(setsize, mask);
5811
5812 while ((item = PyIter_Next(iterator))) {
5813 long cpu;
5814 if (!PyLong_Check(item)) {
5815 PyErr_Format(PyExc_TypeError,
5816 "expected an iterator of ints, "
5817 "but iterator yielded %R",
5818 Py_TYPE(item));
5819 Py_DECREF(item);
5820 goto error;
5821 }
5822 cpu = PyLong_AsLong(item);
5823 Py_DECREF(item);
5824 if (cpu < 0) {
5825 if (!PyErr_Occurred())
5826 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5827 goto error;
5828 }
5829 if (cpu > INT_MAX - 1) {
5830 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5831 goto error;
5832 }
5833 if (cpu >= ncpus) {
5834 /* Grow CPU mask to fit the CPU number */
5835 int newncpus = ncpus;
5836 cpu_set_t *newmask;
5837 size_t newsetsize;
5838 while (newncpus <= cpu) {
5839 if (newncpus > INT_MAX / 2)
5840 newncpus = cpu + 1;
5841 else
5842 newncpus = newncpus * 2;
5843 }
5844 newmask = CPU_ALLOC(newncpus);
5845 if (newmask == NULL) {
5846 PyErr_NoMemory();
5847 goto error;
5848 }
5849 newsetsize = CPU_ALLOC_SIZE(newncpus);
5850 CPU_ZERO_S(newsetsize, newmask);
5851 memcpy(newmask, mask, setsize);
5852 CPU_FREE(mask);
5853 setsize = newsetsize;
5854 mask = newmask;
5855 ncpus = newncpus;
5856 }
5857 CPU_SET_S(cpu, setsize, mask);
5858 }
5859 Py_CLEAR(iterator);
5860
5861 if (sched_setaffinity(pid, setsize, mask)) {
5862 posix_error();
5863 goto error;
5864 }
5865 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005866 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005867
5868error:
5869 if (mask)
5870 CPU_FREE(mask);
5871 Py_XDECREF(iterator);
5872 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005873}
5874
5875PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5876"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5877Return the affinity of the process with PID *pid*.\n\
5878The returned cpu_set will be of size *ncpus*.");
5879
5880static PyObject *
5881posix_sched_getaffinity(PyObject *self, PyObject *args)
5882{
5883 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005884 int cpu, ncpus, count;
5885 size_t setsize;
5886 cpu_set_t *mask = NULL;
5887 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005888
Antoine Pitrou84869872012-08-04 16:16:35 +02005889 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5890 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005891 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005892
5893 ncpus = NCPUS_START;
5894 while (1) {
5895 setsize = CPU_ALLOC_SIZE(ncpus);
5896 mask = CPU_ALLOC(ncpus);
5897 if (mask == NULL)
5898 return PyErr_NoMemory();
5899 if (sched_getaffinity(pid, setsize, mask) == 0)
5900 break;
5901 CPU_FREE(mask);
5902 if (errno != EINVAL)
5903 return posix_error();
5904 if (ncpus > INT_MAX / 2) {
5905 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5906 "a large enough CPU set");
5907 return NULL;
5908 }
5909 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005910 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005911
5912 res = PySet_New(NULL);
5913 if (res == NULL)
5914 goto error;
5915 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5916 if (CPU_ISSET_S(cpu, setsize, mask)) {
5917 PyObject *cpu_num = PyLong_FromLong(cpu);
5918 --count;
5919 if (cpu_num == NULL)
5920 goto error;
5921 if (PySet_Add(res, cpu_num)) {
5922 Py_DECREF(cpu_num);
5923 goto error;
5924 }
5925 Py_DECREF(cpu_num);
5926 }
5927 }
5928 CPU_FREE(mask);
5929 return res;
5930
5931error:
5932 if (mask)
5933 CPU_FREE(mask);
5934 Py_XDECREF(res);
5935 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005936}
5937
Benjamin Peterson2740af82011-08-02 17:41:34 -05005938#endif /* HAVE_SCHED_SETAFFINITY */
5939
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005940#endif /* HAVE_SCHED_H */
5941
Neal Norwitzb59798b2003-03-21 01:43:31 +00005942/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005943/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5944#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005945#define DEV_PTY_FILE "/dev/ptc"
5946#define HAVE_DEV_PTMX
5947#else
5948#define DEV_PTY_FILE "/dev/ptmx"
5949#endif
5950
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005951#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952#ifdef HAVE_PTY_H
5953#include <pty.h>
5954#else
5955#ifdef HAVE_LIBUTIL_H
5956#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005957#else
5958#ifdef HAVE_UTIL_H
5959#include <util.h>
5960#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005961#endif /* HAVE_LIBUTIL_H */
5962#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005963#ifdef HAVE_STROPTS_H
5964#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005965#endif
5966#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005967
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005968#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005969PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005970"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005972
5973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005974posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005975{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005976 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005977#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005979#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005980#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005982#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005984#endif
5985#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005986
Thomas Wouters70c21a12000-07-14 14:28:33 +00005987#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005989 goto posix_error;
5990
5991 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5992 goto error;
5993 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5994 goto error;
5995
Neal Norwitzb59798b2003-03-21 01:43:31 +00005996#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5998 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005999 goto posix_error;
6000 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6001 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006002
Victor Stinnerdaf45552013-08-28 00:53:59 +02006003 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006005 goto posix_error;
6006
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006007#else
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 master_fd = _Py_open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006010 goto posix_error;
6011
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006013
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 /* change permission of slave */
6015 if (grantpt(master_fd) < 0) {
6016 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006017 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006019
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 /* unlock slave */
6021 if (unlockpt(master_fd) < 0) {
6022 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006023 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006025
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006027
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 slave_name = ptsname(master_fd); /* get name of slave */
6029 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006030 goto posix_error;
6031
6032 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006034 goto posix_error;
Neal Norwitzb59798b2003-03-21 01:43:31 +00006035#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6037 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006038#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006040#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006041#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006042#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006043
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006045
Victor Stinnerdaf45552013-08-28 00:53:59 +02006046posix_error:
6047 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006048#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006049error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006050#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006051 if (master_fd != -1)
6052 close(master_fd);
6053 if (slave_fd != -1)
6054 close(slave_fd);
6055 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006056}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006057#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006058
6059#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006061"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006062Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6063Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006065
6066static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006067posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006068{
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 int master_fd = -1, result = 0;
6070 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006071
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 _PyImport_AcquireLock();
6073 pid = forkpty(&master_fd, NULL, NULL, NULL);
6074 if (pid == 0) {
6075 /* child: this clobbers and resets the import lock. */
6076 PyOS_AfterFork();
6077 } else {
6078 /* parent: release the import lock. */
6079 result = _PyImport_ReleaseLock();
6080 }
6081 if (pid == -1)
6082 return posix_error();
6083 if (result < 0) {
6084 /* Don't clobber the OSError if the fork failed. */
6085 PyErr_SetString(PyExc_RuntimeError,
6086 "not holding the import lock");
6087 return NULL;
6088 }
6089 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006090}
6091#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006092
Ross Lagerwall7807c352011-03-17 20:20:30 +02006093
Guido van Rossumad0ee831995-03-01 10:34:45 +00006094#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Barry Warsaw53699e91996-12-10 23:23:01 +00006099static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006100posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006101{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006102 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006103}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006104#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006106
Guido van Rossumad0ee831995-03-01 10:34:45 +00006107#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006109"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Barry Warsaw53699e91996-12-10 23:23:01 +00006112static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006113posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006114{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006115 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006116}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006117#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006119
Guido van Rossumad0ee831995-03-01 10:34:45 +00006120#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006124
Barry Warsaw53699e91996-12-10 23:23:01 +00006125static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006126posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006127{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006128 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006129}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006130#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006134"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006136
Barry Warsaw53699e91996-12-10 23:23:01 +00006137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006138posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006139{
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006141}
6142
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006143#ifdef HAVE_GETGROUPLIST
6144PyDoc_STRVAR(posix_getgrouplist__doc__,
6145"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6146Returns a list of groups to which a user belongs.\n\n\
6147 user: username to lookup\n\
6148 group: base group id of the user");
6149
6150static PyObject *
6151posix_getgrouplist(PyObject *self, PyObject *args)
6152{
6153#ifdef NGROUPS_MAX
6154#define MAX_GROUPS NGROUPS_MAX
6155#else
6156 /* defined to be 16 on Solaris7, so this should be a small number */
6157#define MAX_GROUPS 64
6158#endif
6159
6160 const char *user;
6161 int i, ngroups;
6162 PyObject *list;
6163#ifdef __APPLE__
6164 int *groups, basegid;
6165#else
6166 gid_t *groups, basegid;
6167#endif
6168 ngroups = MAX_GROUPS;
6169
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006170#ifdef __APPLE__
6171 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006172 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006173#else
6174 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6175 _Py_Gid_Converter, &basegid))
6176 return NULL;
6177#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006178
6179#ifdef __APPLE__
6180 groups = PyMem_Malloc(ngroups * sizeof(int));
6181#else
6182 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6183#endif
6184 if (groups == NULL)
6185 return PyErr_NoMemory();
6186
6187 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6188 PyMem_Del(groups);
6189 return posix_error();
6190 }
6191
6192 list = PyList_New(ngroups);
6193 if (list == NULL) {
6194 PyMem_Del(groups);
6195 return NULL;
6196 }
6197
6198 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006199#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006200 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006201#else
6202 PyObject *o = _PyLong_FromGid(groups[i]);
6203#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006204 if (o == NULL) {
6205 Py_DECREF(list);
6206 PyMem_Del(groups);
6207 return NULL;
6208 }
6209 PyList_SET_ITEM(list, i, o);
6210 }
6211
6212 PyMem_Del(groups);
6213
6214 return list;
6215}
6216#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006217
Fred Drakec9680921999-12-13 16:37:25 +00006218#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006219PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006220"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006221Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006222
6223static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006224posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006225{
6226 PyObject *result = NULL;
6227
Fred Drakec9680921999-12-13 16:37:25 +00006228#ifdef NGROUPS_MAX
6229#define MAX_GROUPS NGROUPS_MAX
6230#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006232#define MAX_GROUPS 64
6233#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006235
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006236 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006237 * This is a helper variable to store the intermediate result when
6238 * that happens.
6239 *
6240 * To keep the code readable the OSX behaviour is unconditional,
6241 * according to the POSIX spec this should be safe on all unix-y
6242 * systems.
6243 */
6244 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006246
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006247#ifdef __APPLE__
6248 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6249 * there are more groups than can fit in grouplist. Therefore, on OS X
6250 * always first call getgroups with length 0 to get the actual number
6251 * of groups.
6252 */
6253 n = getgroups(0, NULL);
6254 if (n < 0) {
6255 return posix_error();
6256 } else if (n <= MAX_GROUPS) {
6257 /* groups will fit in existing array */
6258 alt_grouplist = grouplist;
6259 } else {
6260 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6261 if (alt_grouplist == NULL) {
6262 errno = EINVAL;
6263 return posix_error();
6264 }
6265 }
6266
6267 n = getgroups(n, alt_grouplist);
6268 if (n == -1) {
6269 if (alt_grouplist != grouplist) {
6270 PyMem_Free(alt_grouplist);
6271 }
6272 return posix_error();
6273 }
6274#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006276 if (n < 0) {
6277 if (errno == EINVAL) {
6278 n = getgroups(0, NULL);
6279 if (n == -1) {
6280 return posix_error();
6281 }
6282 if (n == 0) {
6283 /* Avoid malloc(0) */
6284 alt_grouplist = grouplist;
6285 } else {
6286 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6287 if (alt_grouplist == NULL) {
6288 errno = EINVAL;
6289 return posix_error();
6290 }
6291 n = getgroups(n, alt_grouplist);
6292 if (n == -1) {
6293 PyMem_Free(alt_grouplist);
6294 return posix_error();
6295 }
6296 }
6297 } else {
6298 return posix_error();
6299 }
6300 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006301#endif
6302
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006303 result = PyList_New(n);
6304 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 int i;
6306 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006307 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006309 Py_DECREF(result);
6310 result = NULL;
6311 break;
Fred Drakec9680921999-12-13 16:37:25 +00006312 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006314 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006315 }
6316
6317 if (alt_grouplist != grouplist) {
6318 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006320
Fred Drakec9680921999-12-13 16:37:25 +00006321 return result;
6322}
6323#endif
6324
Antoine Pitroub7572f02009-12-02 20:46:48 +00006325#ifdef HAVE_INITGROUPS
6326PyDoc_STRVAR(posix_initgroups__doc__,
6327"initgroups(username, gid) -> None\n\n\
6328Call the system initgroups() to initialize the group access list with all of\n\
6329the groups of which the specified username is a member, plus the specified\n\
6330group id.");
6331
6332static PyObject *
6333posix_initgroups(PyObject *self, PyObject *args)
6334{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006335 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006337 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006338#ifdef __APPLE__
6339 int gid;
6340#else
6341 gid_t gid;
6342#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006343
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006344#ifdef __APPLE__
6345 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6346 PyUnicode_FSConverter, &oname,
6347 &gid))
6348#else
6349 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6350 PyUnicode_FSConverter, &oname,
6351 _Py_Gid_Converter, &gid))
6352#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006354 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006355
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006356 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006357 Py_DECREF(oname);
6358 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006360
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 Py_INCREF(Py_None);
6362 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006363}
6364#endif
6365
Martin v. Löwis606edc12002-06-13 21:09:11 +00006366#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006367PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006368"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006369Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006370
6371static PyObject *
6372posix_getpgid(PyObject *self, PyObject *args)
6373{
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 pid_t pid, pgid;
6375 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6376 return NULL;
6377 pgid = getpgid(pid);
6378 if (pgid < 0)
6379 return posix_error();
6380 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006381}
6382#endif /* HAVE_GETPGID */
6383
6384
Guido van Rossumb6775db1994-08-01 11:34:53 +00006385#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006386PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006387"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006388Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006389
Barry Warsaw53699e91996-12-10 23:23:01 +00006390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006391posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006392{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006393#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006395#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006397#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006398}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006399#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006401
Guido van Rossumb6775db1994-08-01 11:34:53 +00006402#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006403PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006404"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006405Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006406
Barry Warsaw53699e91996-12-10 23:23:01 +00006407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006408posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006409{
Guido van Rossum64933891994-10-20 21:56:42 +00006410#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006412#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006414#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 return posix_error();
6416 Py_INCREF(Py_None);
6417 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006418}
6419
Guido van Rossumb6775db1994-08-01 11:34:53 +00006420#endif /* HAVE_SETPGRP */
6421
Guido van Rossumad0ee831995-03-01 10:34:45 +00006422#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006423
6424#ifdef MS_WINDOWS
6425#include <tlhelp32.h>
6426
6427static PyObject*
6428win32_getppid()
6429{
6430 HANDLE snapshot;
6431 pid_t mypid;
6432 PyObject* result = NULL;
6433 BOOL have_record;
6434 PROCESSENTRY32 pe;
6435
6436 mypid = getpid(); /* This function never fails */
6437
6438 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6439 if (snapshot == INVALID_HANDLE_VALUE)
6440 return PyErr_SetFromWindowsErr(GetLastError());
6441
6442 pe.dwSize = sizeof(pe);
6443 have_record = Process32First(snapshot, &pe);
6444 while (have_record) {
6445 if (mypid == (pid_t)pe.th32ProcessID) {
6446 /* We could cache the ulong value in a static variable. */
6447 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6448 break;
6449 }
6450
6451 have_record = Process32Next(snapshot, &pe);
6452 }
6453
6454 /* If our loop exits and our pid was not found (result will be NULL)
6455 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6456 * error anyway, so let's raise it. */
6457 if (!result)
6458 result = PyErr_SetFromWindowsErr(GetLastError());
6459
6460 CloseHandle(snapshot);
6461
6462 return result;
6463}
6464#endif /*MS_WINDOWS*/
6465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006466PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006467"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006468Return the parent's process id. If the parent process has already exited,\n\
6469Windows machines will still return its id; others systems will return the id\n\
6470of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Barry Warsaw53699e91996-12-10 23:23:01 +00006472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006473posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006474{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006475#ifdef MS_WINDOWS
6476 return win32_getppid();
6477#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006479#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006480}
6481#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006483
Fred Drake12c6e2d1999-12-14 21:25:03 +00006484#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006485PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006486"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006487Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006488
6489static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006490posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006491{
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006493#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006495 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006496
6497 if (GetUserNameW(user_name, &num_chars)) {
6498 /* num_chars is the number of unicode chars plus null terminator */
6499 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006500 }
6501 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006502 result = PyErr_SetFromWindowsErr(GetLastError());
6503#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 char *name;
6505 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 errno = 0;
6508 name = getlogin();
6509 if (name == NULL) {
6510 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006511 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006512 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006513 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 }
6515 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006516 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006518#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006519 return result;
6520}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006521#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006522
Guido van Rossumad0ee831995-03-01 10:34:45 +00006523#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006525"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Barry Warsaw53699e91996-12-10 23:23:01 +00006528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006529posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006530{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006531 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006532}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006533#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006535
Guido van Rossumad0ee831995-03-01 10:34:45 +00006536#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006537PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006538"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Barry Warsaw53699e91996-12-10 23:23:01 +00006541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006542posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006543{
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 pid_t pid;
6545 int sig;
6546 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6547 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 if (kill(pid, sig) == -1)
6549 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 Py_INCREF(Py_None);
6551 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006552}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006553#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006554
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006555#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006556PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006557"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006558Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006559
6560static PyObject *
6561posix_killpg(PyObject *self, PyObject *args)
6562{
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 int sig;
6564 pid_t pgid;
6565 /* XXX some man pages make the `pgid` parameter an int, others
6566 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6567 take the same type. Moreover, pid_t is always at least as wide as
6568 int (else compilation of this module fails), which is safe. */
6569 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6570 return NULL;
6571 if (killpg(pgid, sig) == -1)
6572 return posix_error();
6573 Py_INCREF(Py_None);
6574 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006575}
6576#endif
6577
Brian Curtineb24d742010-04-12 17:16:38 +00006578#ifdef MS_WINDOWS
6579PyDoc_STRVAR(win32_kill__doc__,
6580"kill(pid, sig)\n\n\
6581Kill a process with a signal.");
6582
6583static PyObject *
6584win32_kill(PyObject *self, PyObject *args)
6585{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006586 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006587 pid_t pid;
6588 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006590
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006591 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 /* Console processes which share a common console can be sent CTRL+C or
6595 CTRL+BREAK events, provided they handle said events. */
6596 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006597 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 err = GetLastError();
6599 PyErr_SetFromWindowsErr(err);
6600 }
6601 else
6602 Py_RETURN_NONE;
6603 }
Brian Curtineb24d742010-04-12 17:16:38 +00006604
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6606 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006607 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 if (handle == NULL) {
6609 err = GetLastError();
6610 return PyErr_SetFromWindowsErr(err);
6611 }
Brian Curtineb24d742010-04-12 17:16:38 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 if (TerminateProcess(handle, sig) == 0) {
6614 err = GetLastError();
6615 result = PyErr_SetFromWindowsErr(err);
6616 } else {
6617 Py_INCREF(Py_None);
6618 result = Py_None;
6619 }
Brian Curtineb24d742010-04-12 17:16:38 +00006620
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 CloseHandle(handle);
6622 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006623}
6624#endif /* MS_WINDOWS */
6625
Guido van Rossumc0125471996-06-28 18:55:32 +00006626#ifdef HAVE_PLOCK
6627
6628#ifdef HAVE_SYS_LOCK_H
6629#include <sys/lock.h>
6630#endif
6631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006632PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006633"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006634Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006635
Barry Warsaw53699e91996-12-10 23:23:01 +00006636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006637posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006638{
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 int op;
6640 if (!PyArg_ParseTuple(args, "i:plock", &op))
6641 return NULL;
6642 if (plock(op) == -1)
6643 return posix_error();
6644 Py_INCREF(Py_None);
6645 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006646}
6647#endif
6648
Guido van Rossumb6775db1994-08-01 11:34:53 +00006649#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006650PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006651"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006652Set the current process's user id.");
6653
Barry Warsaw53699e91996-12-10 23:23:01 +00006654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006655posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006656{
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006658 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 if (setuid(uid) < 0)
6661 return posix_error();
6662 Py_INCREF(Py_None);
6663 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006664}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006665#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006667
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006668#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006669PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006670"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671Set the current process's effective user id.");
6672
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006673static PyObject *
6674posix_seteuid (PyObject *self, PyObject *args)
6675{
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006677 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 if (seteuid(euid) < 0) {
6680 return posix_error();
6681 } else {
6682 Py_INCREF(Py_None);
6683 return Py_None;
6684 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006685}
6686#endif /* HAVE_SETEUID */
6687
6688#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Set the current process's effective group id.");
6692
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006693static PyObject *
6694posix_setegid (PyObject *self, PyObject *args)
6695{
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006697 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 if (setegid(egid) < 0) {
6700 return posix_error();
6701 } else {
6702 Py_INCREF(Py_None);
6703 return Py_None;
6704 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006705}
6706#endif /* HAVE_SETEGID */
6707
6708#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006710"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711Set the current process's real and effective user ids.");
6712
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006713static PyObject *
6714posix_setreuid (PyObject *self, PyObject *args)
6715{
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006717 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6718 _Py_Uid_Converter, &ruid,
6719 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 if (setreuid(ruid, euid) < 0) {
6722 return posix_error();
6723 } else {
6724 Py_INCREF(Py_None);
6725 return Py_None;
6726 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006727}
6728#endif /* HAVE_SETREUID */
6729
6730#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006731PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006732"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006733Set the current process's real and effective group ids.");
6734
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006735static PyObject *
6736posix_setregid (PyObject *self, PyObject *args)
6737{
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006739 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6740 _Py_Gid_Converter, &rgid,
6741 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 if (setregid(rgid, egid) < 0) {
6744 return posix_error();
6745 } else {
6746 Py_INCREF(Py_None);
6747 return Py_None;
6748 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006749}
6750#endif /* HAVE_SETREGID */
6751
Guido van Rossumb6775db1994-08-01 11:34:53 +00006752#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006753PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006754"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006755Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006756
Barry Warsaw53699e91996-12-10 23:23:01 +00006757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006758posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006759{
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006761 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 if (setgid(gid) < 0)
6764 return posix_error();
6765 Py_INCREF(Py_None);
6766 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006767}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006768#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006769
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006770#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006771PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006772"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006773Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006774
6775static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006776posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006777{
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 int i, len;
6779 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (!PySequence_Check(groups)) {
6782 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6783 return NULL;
6784 }
6785 len = PySequence_Size(groups);
6786 if (len > MAX_GROUPS) {
6787 PyErr_SetString(PyExc_ValueError, "too many groups");
6788 return NULL;
6789 }
6790 for(i = 0; i < len; i++) {
6791 PyObject *elem;
6792 elem = PySequence_GetItem(groups, i);
6793 if (!elem)
6794 return NULL;
6795 if (!PyLong_Check(elem)) {
6796 PyErr_SetString(PyExc_TypeError,
6797 "groups must be integers");
6798 Py_DECREF(elem);
6799 return NULL;
6800 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006801 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 Py_DECREF(elem);
6803 return NULL;
6804 }
6805 }
6806 Py_DECREF(elem);
6807 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006808
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 if (setgroups(len, grouplist) < 0)
6810 return posix_error();
6811 Py_INCREF(Py_None);
6812 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006813}
6814#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006815
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006816#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6817static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006818wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819{
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 PyObject *result;
6821 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006822 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 if (pid == -1)
6825 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006826
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 if (struct_rusage == NULL) {
6828 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6829 if (m == NULL)
6830 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006831 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 Py_DECREF(m);
6833 if (struct_rusage == NULL)
6834 return NULL;
6835 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6838 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6839 if (!result)
6840 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841
6842#ifndef doubletime
6843#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6844#endif
6845
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006847 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006849 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6852 SET_INT(result, 2, ru->ru_maxrss);
6853 SET_INT(result, 3, ru->ru_ixrss);
6854 SET_INT(result, 4, ru->ru_idrss);
6855 SET_INT(result, 5, ru->ru_isrss);
6856 SET_INT(result, 6, ru->ru_minflt);
6857 SET_INT(result, 7, ru->ru_majflt);
6858 SET_INT(result, 8, ru->ru_nswap);
6859 SET_INT(result, 9, ru->ru_inblock);
6860 SET_INT(result, 10, ru->ru_oublock);
6861 SET_INT(result, 11, ru->ru_msgsnd);
6862 SET_INT(result, 12, ru->ru_msgrcv);
6863 SET_INT(result, 13, ru->ru_nsignals);
6864 SET_INT(result, 14, ru->ru_nvcsw);
6865 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866#undef SET_INT
6867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 if (PyErr_Occurred()) {
6869 Py_DECREF(result);
6870 return NULL;
6871 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874}
6875#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6876
6877#ifdef HAVE_WAIT3
6878PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006879"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880Wait for completion of a child process.");
6881
6882static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006883posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884{
Victor Stinner8c62be82010-05-06 00:08:46 +00006885 pid_t pid;
6886 int options;
6887 struct rusage ru;
6888 WAIT_TYPE status;
6889 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890
Victor Stinner4195b5c2012-02-08 23:03:19 +01006891 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 Py_BEGIN_ALLOW_THREADS
6895 pid = wait3(&status, options, &ru);
6896 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897
Victor Stinner4195b5c2012-02-08 23:03:19 +01006898 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006899}
6900#endif /* HAVE_WAIT3 */
6901
6902#ifdef HAVE_WAIT4
6903PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006904"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905Wait for completion of a given child process.");
6906
6907static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006908posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909{
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 pid_t pid;
6911 int options;
6912 struct rusage ru;
6913 WAIT_TYPE status;
6914 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915
Victor Stinner4195b5c2012-02-08 23:03:19 +01006916 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 Py_BEGIN_ALLOW_THREADS
6920 pid = wait4(pid, &status, options, &ru);
6921 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922
Victor Stinner4195b5c2012-02-08 23:03:19 +01006923 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924}
6925#endif /* HAVE_WAIT4 */
6926
Ross Lagerwall7807c352011-03-17 20:20:30 +02006927#if defined(HAVE_WAITID) && !defined(__APPLE__)
6928PyDoc_STRVAR(posix_waitid__doc__,
6929"waitid(idtype, id, options) -> waitid_result\n\n\
6930Wait for the completion of one or more child processes.\n\n\
6931idtype can be P_PID, P_PGID or P_ALL.\n\
6932id specifies the pid to wait on.\n\
6933options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6934or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6935Returns either waitid_result or None if WNOHANG is specified and there are\n\
6936no children in a waitable state.");
6937
6938static PyObject *
6939posix_waitid(PyObject *self, PyObject *args)
6940{
6941 PyObject *result;
6942 idtype_t idtype;
6943 id_t id;
6944 int options, res;
6945 siginfo_t si;
6946 si.si_pid = 0;
6947 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6948 return NULL;
6949 Py_BEGIN_ALLOW_THREADS
6950 res = waitid(idtype, id, &si, options);
6951 Py_END_ALLOW_THREADS
6952 if (res == -1)
6953 return posix_error();
6954
6955 if (si.si_pid == 0)
6956 Py_RETURN_NONE;
6957
6958 result = PyStructSequence_New(&WaitidResultType);
6959 if (!result)
6960 return NULL;
6961
6962 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006963 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006964 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6965 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6966 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6967 if (PyErr_Occurred()) {
6968 Py_DECREF(result);
6969 return NULL;
6970 }
6971
6972 return result;
6973}
6974#endif
6975
Guido van Rossumb6775db1994-08-01 11:34:53 +00006976#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006977PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006978"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006979Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006980
Barry Warsaw53699e91996-12-10 23:23:01 +00006981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006982posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006983{
Victor Stinner8c62be82010-05-06 00:08:46 +00006984 pid_t pid;
6985 int options;
6986 WAIT_TYPE status;
6987 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006988
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6990 return NULL;
6991 Py_BEGIN_ALLOW_THREADS
6992 pid = waitpid(pid, &status, options);
6993 Py_END_ALLOW_THREADS
6994 if (pid == -1)
6995 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006996
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006998}
6999
Tim Petersab034fa2002-02-01 11:27:43 +00007000#elif defined(HAVE_CWAIT)
7001
7002/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007003PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007004"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007005"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007006
7007static PyObject *
7008posix_waitpid(PyObject *self, PyObject *args)
7009{
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 Py_intptr_t pid;
7011 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007012
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007013 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 return NULL;
7015 Py_BEGIN_ALLOW_THREADS
7016 pid = _cwait(&status, pid, options);
7017 Py_END_ALLOW_THREADS
7018 if (pid == -1)
7019 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007020
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007022 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007023}
7024#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007025
Guido van Rossumad0ee831995-03-01 10:34:45 +00007026#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007027PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007028"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Barry Warsaw53699e91996-12-10 23:23:01 +00007031static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007032posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007033{
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 pid_t pid;
7035 WAIT_TYPE status;
7036 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007037
Victor Stinner8c62be82010-05-06 00:08:46 +00007038 Py_BEGIN_ALLOW_THREADS
7039 pid = wait(&status);
7040 Py_END_ALLOW_THREADS
7041 if (pid == -1)
7042 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007043
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007045}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007046#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007048
Larry Hastings9cf065c2012-06-22 16:30:09 -07007049#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7050PyDoc_STRVAR(readlink__doc__,
7051"readlink(path, *, dir_fd=None) -> path\n\n\
7052Return a string representing the path to which the symbolic link points.\n\
7053\n\
7054If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7055 and path should be relative; path will then be relative to that directory.\n\
7056dir_fd may not be implemented on your platform.\n\
7057 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007058#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007059
Guido van Rossumb6775db1994-08-01 11:34:53 +00007060#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Barry Warsaw53699e91996-12-10 23:23:01 +00007062static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007064{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065 path_t path;
7066 int dir_fd = DEFAULT_DIR_FD;
7067 char buffer[MAXPATHLEN];
7068 ssize_t length;
7069 PyObject *return_value = NULL;
7070 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007071
Larry Hastings9cf065c2012-06-22 16:30:09 -07007072 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007073 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007074 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7075 path_converter, &path,
7076#ifdef HAVE_READLINKAT
7077 dir_fd_converter, &dir_fd
7078#else
7079 dir_fd_unavailable, &dir_fd
7080#endif
7081 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007083
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085#ifdef HAVE_READLINKAT
7086 if (dir_fd != DEFAULT_DIR_FD)
7087 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007088 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007089#endif
7090 length = readlink(path.narrow, buffer, sizeof(buffer));
7091 Py_END_ALLOW_THREADS
7092
7093 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007094 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095 goto exit;
7096 }
7097
7098 if (PyUnicode_Check(path.object))
7099 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7100 else
7101 return_value = PyBytes_FromStringAndSize(buffer, length);
7102exit:
7103 path_cleanup(&path);
7104 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007105}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106
7107
Guido van Rossumb6775db1994-08-01 11:34:53 +00007108#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007110
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007112PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7114Create a symbolic link pointing to src named dst.\n\n\
7115target_is_directory is required on Windows if the target is to be\n\
7116 interpreted as a directory. (On Windows, symlink requires\n\
7117 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7118 target_is_directory is ignored on non-Windows platforms.\n\
7119\n\
7120If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7121 and path should be relative; path will then be relative to that directory.\n\
7122dir_fd may not be implemented on your platform.\n\
7123 If it is unavailable, using it will raise a NotImplementedError.");
7124
7125#if defined(MS_WINDOWS)
7126
7127/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7128static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7129static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007130
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007132check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133{
7134 HINSTANCE hKernel32;
7135 /* only recheck */
7136 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7137 return 1;
7138 hKernel32 = GetModuleHandleW(L"KERNEL32");
7139 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7140 "CreateSymbolicLinkW");
7141 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7142 "CreateSymbolicLinkA");
7143 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7144}
7145
Victor Stinner31b3b922013-06-05 01:49:17 +02007146/* Remove the last portion of the path */
7147static void
7148_dirnameW(WCHAR *path)
7149{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007150 WCHAR *ptr;
7151
7152 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007153 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007154 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007155 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007156 }
7157 *ptr = 0;
7158}
7159
Victor Stinner31b3b922013-06-05 01:49:17 +02007160/* Remove the last portion of the path */
7161static void
7162_dirnameA(char *path)
7163{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007164 char *ptr;
7165
7166 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007167 for(ptr = path + strlen(path); ptr != path; ptr--) {
7168 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007169 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007170 }
7171 *ptr = 0;
7172}
7173
Victor Stinner31b3b922013-06-05 01:49:17 +02007174/* Is this path absolute? */
7175static int
7176_is_absW(const WCHAR *path)
7177{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007178 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7179
7180}
7181
Victor Stinner31b3b922013-06-05 01:49:17 +02007182/* Is this path absolute? */
7183static int
7184_is_absA(const char *path)
7185{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007186 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7187
7188}
7189
Victor Stinner31b3b922013-06-05 01:49:17 +02007190/* join root and rest with a backslash */
7191static void
7192_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7193{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007194 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007195
Victor Stinner31b3b922013-06-05 01:49:17 +02007196 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007197 wcscpy(dest_path, rest);
7198 return;
7199 }
7200
7201 root_len = wcslen(root);
7202
7203 wcscpy(dest_path, root);
7204 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007205 dest_path[root_len] = L'\\';
7206 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007207 }
7208 wcscpy(dest_path+root_len, rest);
7209}
7210
Victor Stinner31b3b922013-06-05 01:49:17 +02007211/* join root and rest with a backslash */
7212static void
7213_joinA(char *dest_path, const char *root, const char *rest)
7214{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007215 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007216
Victor Stinner31b3b922013-06-05 01:49:17 +02007217 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007218 strcpy(dest_path, rest);
7219 return;
7220 }
7221
7222 root_len = strlen(root);
7223
7224 strcpy(dest_path, root);
7225 if(root_len) {
7226 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007227 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007228 }
7229 strcpy(dest_path+root_len, rest);
7230}
7231
Victor Stinner31b3b922013-06-05 01:49:17 +02007232/* Return True if the path at src relative to dest is a directory */
7233static int
7234_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007236 WIN32_FILE_ATTRIBUTE_DATA src_info;
7237 WCHAR dest_parent[MAX_PATH];
7238 WCHAR src_resolved[MAX_PATH] = L"";
7239
7240 /* dest_parent = os.path.dirname(dest) */
7241 wcscpy(dest_parent, dest);
7242 _dirnameW(dest_parent);
7243 /* src_resolved = os.path.join(dest_parent, src) */
7244 _joinW(src_resolved, dest_parent, src);
7245 return (
7246 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7247 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7248 );
7249}
7250
Victor Stinner31b3b922013-06-05 01:49:17 +02007251/* Return True if the path at src relative to dest is a directory */
7252static int
7253_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007255 WIN32_FILE_ATTRIBUTE_DATA src_info;
7256 char dest_parent[MAX_PATH];
7257 char src_resolved[MAX_PATH] = "";
7258
7259 /* dest_parent = os.path.dirname(dest) */
7260 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007261 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007262 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007263 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 return (
7265 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7266 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7267 );
7268}
7269
Larry Hastings9cf065c2012-06-22 16:30:09 -07007270#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007271
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007272static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007273posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007274{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 path_t src;
7276 path_t dst;
7277 int dir_fd = DEFAULT_DIR_FD;
7278 int target_is_directory = 0;
7279 static char *keywords[] = {"src", "dst", "target_is_directory",
7280 "dir_fd", NULL};
7281 PyObject *return_value;
7282#ifdef MS_WINDOWS
7283 DWORD result;
7284#else
7285 int result;
7286#endif
7287
7288 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007289 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007290 src.argument_name = "src";
7291 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007292 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007293 dst.argument_name = "dst";
7294
7295#ifdef MS_WINDOWS
7296 if (!check_CreateSymbolicLink()) {
7297 PyErr_SetString(PyExc_NotImplementedError,
7298 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007299 return NULL;
7300 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007301 if (!win32_can_symlink) {
7302 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007303 return NULL;
7304 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007305#endif
7306
7307 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7308 keywords,
7309 path_converter, &src,
7310 path_converter, &dst,
7311 &target_is_directory,
7312#ifdef HAVE_SYMLINKAT
7313 dir_fd_converter, &dir_fd
7314#else
7315 dir_fd_unavailable, &dir_fd
7316#endif
7317 ))
7318 return NULL;
7319
7320 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7321 PyErr_SetString(PyExc_ValueError,
7322 "symlink: src and dst must be the same type");
7323 return_value = NULL;
7324 goto exit;
7325 }
7326
7327#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328
Larry Hastings9cf065c2012-06-22 16:30:09 -07007329 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330 if (dst.wide) {
7331 /* if src is a directory, ensure target_is_directory==1 */
7332 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007333 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7334 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335 }
7336 else {
7337 /* if src is a directory, ensure target_is_directory==1 */
7338 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007339 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7340 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007341 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342 Py_END_ALLOW_THREADS
7343
7344 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007345 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007346 goto exit;
7347 }
7348
7349#else
7350
7351 Py_BEGIN_ALLOW_THREADS
7352#if HAVE_SYMLINKAT
7353 if (dir_fd != DEFAULT_DIR_FD)
7354 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7355 else
7356#endif
7357 result = symlink(src.narrow, dst.narrow);
7358 Py_END_ALLOW_THREADS
7359
7360 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007361 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362 goto exit;
7363 }
7364#endif
7365
7366 return_value = Py_None;
7367 Py_INCREF(Py_None);
7368 goto exit; /* silence "unused label" warning */
7369exit:
7370 path_cleanup(&src);
7371 path_cleanup(&dst);
7372 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007373}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007375#endif /* HAVE_SYMLINK */
7376
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377
Brian Curtind40e6f72010-07-08 21:39:08 +00007378#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7379
Brian Curtind40e6f72010-07-08 21:39:08 +00007380static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007381win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007382{
7383 wchar_t *path;
7384 DWORD n_bytes_returned;
7385 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007386 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007387 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007388 HANDLE reparse_point_handle;
7389
7390 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7391 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7392 wchar_t *print_name;
7393
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394 static char *keywords[] = {"path", "dir_fd", NULL};
7395
7396 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7397 &po,
7398 dir_fd_unavailable, &dir_fd
7399 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007400 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401
Victor Stinnereb5657a2011-09-30 01:44:27 +02007402 path = PyUnicode_AsUnicode(po);
7403 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007404 return NULL;
7405
7406 /* First get a handle to the reparse point */
7407 Py_BEGIN_ALLOW_THREADS
7408 reparse_point_handle = CreateFileW(
7409 path,
7410 0,
7411 0,
7412 0,
7413 OPEN_EXISTING,
7414 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7415 0);
7416 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007417
Brian Curtind40e6f72010-07-08 21:39:08 +00007418 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007419 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007420
Brian Curtind40e6f72010-07-08 21:39:08 +00007421 Py_BEGIN_ALLOW_THREADS
7422 /* New call DeviceIoControl to read the reparse point */
7423 io_result = DeviceIoControl(
7424 reparse_point_handle,
7425 FSCTL_GET_REPARSE_POINT,
7426 0, 0, /* in buffer */
7427 target_buffer, sizeof(target_buffer),
7428 &n_bytes_returned,
7429 0 /* we're not using OVERLAPPED_IO */
7430 );
7431 CloseHandle(reparse_point_handle);
7432 Py_END_ALLOW_THREADS
7433
7434 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007435 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007436
7437 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7438 {
7439 PyErr_SetString(PyExc_ValueError,
7440 "not a symbolic link");
7441 return NULL;
7442 }
Brian Curtin74e45612010-07-09 15:58:59 +00007443 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7444 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7445
7446 result = PyUnicode_FromWideChar(print_name,
7447 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007448 return result;
7449}
7450
7451#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7452
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007453
Larry Hastings605a62d2012-06-24 04:33:36 -07007454static PyStructSequence_Field times_result_fields[] = {
7455 {"user", "user time"},
7456 {"system", "system time"},
7457 {"children_user", "user time of children"},
7458 {"children_system", "system time of children"},
7459 {"elapsed", "elapsed time since an arbitrary point in the past"},
7460 {NULL}
7461};
7462
7463PyDoc_STRVAR(times_result__doc__,
7464"times_result: Result from os.times().\n\n\
7465This object may be accessed either as a tuple of\n\
7466 (user, system, children_user, children_system, elapsed),\n\
7467or via the attributes user, system, children_user, children_system,\n\
7468and elapsed.\n\
7469\n\
7470See os.times for more information.");
7471
7472static PyStructSequence_Desc times_result_desc = {
7473 "times_result", /* name */
7474 times_result__doc__, /* doc */
7475 times_result_fields,
7476 5
7477};
7478
7479static PyTypeObject TimesResultType;
7480
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007481#ifdef MS_WINDOWS
7482#define HAVE_TIMES /* mandatory, for the method table */
7483#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007484
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007485#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007486
7487static PyObject *
7488build_times_result(double user, double system,
7489 double children_user, double children_system,
7490 double elapsed)
7491{
7492 PyObject *value = PyStructSequence_New(&TimesResultType);
7493 if (value == NULL)
7494 return NULL;
7495
7496#define SET(i, field) \
7497 { \
7498 PyObject *o = PyFloat_FromDouble(field); \
7499 if (!o) { \
7500 Py_DECREF(value); \
7501 return NULL; \
7502 } \
7503 PyStructSequence_SET_ITEM(value, i, o); \
7504 } \
7505
7506 SET(0, user);
7507 SET(1, system);
7508 SET(2, children_user);
7509 SET(3, children_system);
7510 SET(4, elapsed);
7511
7512#undef SET
7513
7514 return value;
7515}
7516
7517PyDoc_STRVAR(posix_times__doc__,
7518"times() -> times_result\n\n\
7519Return an object containing floating point numbers indicating process\n\
7520times. The object behaves like a named tuple with these fields:\n\
7521 (utime, stime, cutime, cstime, elapsed_time)");
7522
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007523#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007524static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007525posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007526{
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 FILETIME create, exit, kernel, user;
7528 HANDLE hProc;
7529 hProc = GetCurrentProcess();
7530 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7531 /* The fields of a FILETIME structure are the hi and lo part
7532 of a 64-bit value expressed in 100 nanosecond units.
7533 1e7 is one second in such units; 1e-7 the inverse.
7534 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7535 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007536 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 (double)(user.dwHighDateTime*429.4967296 +
7538 user.dwLowDateTime*1e-7),
7539 (double)(kernel.dwHighDateTime*429.4967296 +
7540 kernel.dwLowDateTime*1e-7),
7541 (double)0,
7542 (double)0,
7543 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007544}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007545#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007546#define NEED_TICKS_PER_SECOND
7547static long ticks_per_second = -1;
7548static PyObject *
7549posix_times(PyObject *self, PyObject *noargs)
7550{
7551 struct tms t;
7552 clock_t c;
7553 errno = 0;
7554 c = times(&t);
7555 if (c == (clock_t) -1)
7556 return posix_error();
7557 return build_times_result(
7558 (double)t.tms_utime / ticks_per_second,
7559 (double)t.tms_stime / ticks_per_second,
7560 (double)t.tms_cutime / ticks_per_second,
7561 (double)t.tms_cstime / ticks_per_second,
7562 (double)c / ticks_per_second);
7563}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007564#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007565
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007566#endif /* HAVE_TIMES */
7567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007568
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007569#ifdef HAVE_GETSID
7570PyDoc_STRVAR(posix_getsid__doc__,
7571"getsid(pid) -> sid\n\n\
7572Call the system call getsid().");
7573
7574static PyObject *
7575posix_getsid(PyObject *self, PyObject *args)
7576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 pid_t pid;
7578 int sid;
7579 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7580 return NULL;
7581 sid = getsid(pid);
7582 if (sid < 0)
7583 return posix_error();
7584 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007585}
7586#endif /* HAVE_GETSID */
7587
7588
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007590PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007591"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007592Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007593
Barry Warsaw53699e91996-12-10 23:23:01 +00007594static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007595posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007596{
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 if (setsid() < 0)
7598 return posix_error();
7599 Py_INCREF(Py_None);
7600 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007601}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007602#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007605PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007606"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007608
Barry Warsaw53699e91996-12-10 23:23:01 +00007609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007610posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007611{
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 pid_t pid;
7613 int pgrp;
7614 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7615 return NULL;
7616 if (setpgid(pid, pgrp) < 0)
7617 return posix_error();
7618 Py_INCREF(Py_None);
7619 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007620}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007621#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007623
Guido van Rossumb6775db1994-08-01 11:34:53 +00007624#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007625PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007626"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007627Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007628
Barry Warsaw53699e91996-12-10 23:23:01 +00007629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007630posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007631{
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 int fd;
7633 pid_t pgid;
7634 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7635 return NULL;
7636 pgid = tcgetpgrp(fd);
7637 if (pgid < 0)
7638 return posix_error();
7639 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007640}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007641#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007645PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007646"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007647Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007648
Barry Warsaw53699e91996-12-10 23:23:01 +00007649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007650posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007651{
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 int fd;
7653 pid_t pgid;
7654 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7655 return NULL;
7656 if (tcsetpgrp(fd, pgid) < 0)
7657 return posix_error();
7658 Py_INCREF(Py_None);
7659 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007660}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007662
Guido van Rossum687dd131993-05-17 08:34:16 +00007663/* Functions acting on file descriptors */
7664
Victor Stinnerdaf45552013-08-28 00:53:59 +02007665#ifdef O_CLOEXEC
7666extern int _Py_open_cloexec_works;
7667#endif
7668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007669PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007670"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7671Open a file for low level IO. Returns a file handle (integer).\n\
7672\n\
7673If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7674 and path should be relative; path will then be relative to that directory.\n\
7675dir_fd may not be implemented on your platform.\n\
7676 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007677
Barry Warsaw53699e91996-12-10 23:23:01 +00007678static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007679posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007680{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007681 path_t path;
7682 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007684 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007686 PyObject *return_value = NULL;
7687 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007688#ifdef O_CLOEXEC
7689 int *atomic_flag_works = &_Py_open_cloexec_works;
7690#elif !defined(MS_WINDOWS)
7691 int *atomic_flag_works = NULL;
7692#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007693
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007695 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007696 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7697 path_converter, &path,
7698 &flags, &mode,
7699#ifdef HAVE_OPENAT
7700 dir_fd_converter, &dir_fd
7701#else
7702 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007703#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007704 ))
7705 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007706
Victor Stinnerdaf45552013-08-28 00:53:59 +02007707#ifdef MS_WINDOWS
7708 flags |= O_NOINHERIT;
7709#elif defined(O_CLOEXEC)
7710 flags |= O_CLOEXEC;
7711#endif
7712
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007714#ifdef MS_WINDOWS
7715 if (path.wide)
7716 fd = _wopen(path.wide, flags, mode);
7717 else
7718#endif
7719#ifdef HAVE_OPENAT
7720 if (dir_fd != DEFAULT_DIR_FD)
7721 fd = openat(dir_fd, path.narrow, flags, mode);
7722 else
7723#endif
7724 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007726
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007728 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007729 goto exit;
7730 }
7731
Victor Stinnerdaf45552013-08-28 00:53:59 +02007732#ifndef MS_WINDOWS
7733 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7734 close(fd);
7735 goto exit;
7736 }
7737#endif
7738
Larry Hastings9cf065c2012-06-22 16:30:09 -07007739 return_value = PyLong_FromLong((long)fd);
7740
7741exit:
7742 path_cleanup(&path);
7743 return return_value;
7744}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007746PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007747"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007748Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007749
Barry Warsaw53699e91996-12-10 23:23:01 +00007750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007751posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007752{
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 int fd, res;
7754 if (!PyArg_ParseTuple(args, "i:close", &fd))
7755 return NULL;
7756 if (!_PyVerify_fd(fd))
7757 return posix_error();
7758 Py_BEGIN_ALLOW_THREADS
7759 res = close(fd);
7760 Py_END_ALLOW_THREADS
7761 if (res < 0)
7762 return posix_error();
7763 Py_INCREF(Py_None);
7764 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007765}
7766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007767
Victor Stinner8c62be82010-05-06 00:08:46 +00007768PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007769"closerange(fd_low, fd_high)\n\n\
7770Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7771
7772static PyObject *
7773posix_closerange(PyObject *self, PyObject *args)
7774{
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 int fd_from, fd_to, i;
7776 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7777 return NULL;
7778 Py_BEGIN_ALLOW_THREADS
7779 for (i = fd_from; i < fd_to; i++)
7780 if (_PyVerify_fd(i))
7781 close(i);
7782 Py_END_ALLOW_THREADS
7783 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007784}
7785
7786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007787PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007788"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007789Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007790
Barry Warsaw53699e91996-12-10 23:23:01 +00007791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007792posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007793{
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007795
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7797 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007798
Victor Stinnerdaf45552013-08-28 00:53:59 +02007799 fd = _Py_dup(fd);
7800 if (fd == -1)
7801 return NULL;
7802
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007804}
7805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007807PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007808"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Barry Warsaw53699e91996-12-10 23:23:01 +00007811static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007812posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007813{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007814 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7815 int fd, fd2;
7816 int inheritable = 1;
7817 int res;
7818#if defined(HAVE_DUP3) && \
7819 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7820 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7821 int dup3_works = -1;
7822#endif
7823
7824 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7825 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007827
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 if (!_PyVerify_fd_dup2(fd, fd2))
7829 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007830
7831#ifdef MS_WINDOWS
7832 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007834 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 if (res < 0)
7836 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007837
7838 /* Character files like console cannot be make non-inheritable */
7839 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7840 close(fd2);
7841 return NULL;
7842 }
7843
7844#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7845 Py_BEGIN_ALLOW_THREADS
7846 if (!inheritable)
7847 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7848 else
7849 res = dup2(fd, fd2);
7850 Py_END_ALLOW_THREADS
7851 if (res < 0)
7852 return posix_error();
7853
7854#else
7855
7856#ifdef HAVE_DUP3
7857 if (!inheritable && dup3_works != 0) {
7858 Py_BEGIN_ALLOW_THREADS
7859 res = dup3(fd, fd2, O_CLOEXEC);
7860 Py_END_ALLOW_THREADS
7861 if (res < 0) {
7862 if (dup3_works == -1)
7863 dup3_works = (errno != ENOSYS);
7864 if (dup3_works)
7865 return posix_error();
7866 }
7867 }
7868
7869 if (inheritable || dup3_works == 0)
7870 {
7871#endif
7872 Py_BEGIN_ALLOW_THREADS
7873 res = dup2(fd, fd2);
7874 Py_END_ALLOW_THREADS
7875 if (res < 0)
7876 return posix_error();
7877
7878 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7879 close(fd2);
7880 return NULL;
7881 }
7882#ifdef HAVE_DUP3
7883 }
7884#endif
7885
7886#endif
7887
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 Py_INCREF(Py_None);
7889 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007890}
7891
Ross Lagerwall7807c352011-03-17 20:20:30 +02007892#ifdef HAVE_LOCKF
7893PyDoc_STRVAR(posix_lockf__doc__,
7894"lockf(fd, cmd, len)\n\n\
7895Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7896fd is an open file descriptor.\n\
7897cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7898F_TEST.\n\
7899len specifies the section of the file to lock.");
7900
7901static PyObject *
7902posix_lockf(PyObject *self, PyObject *args)
7903{
7904 int fd, cmd, res;
7905 off_t len;
7906 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7907 &fd, &cmd, _parse_off_t, &len))
7908 return NULL;
7909
7910 Py_BEGIN_ALLOW_THREADS
7911 res = lockf(fd, cmd, len);
7912 Py_END_ALLOW_THREADS
7913
7914 if (res < 0)
7915 return posix_error();
7916
7917 Py_RETURN_NONE;
7918}
7919#endif
7920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007922PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007923"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007924Set the current position of a file descriptor.\n\
7925Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007926
Barry Warsaw53699e91996-12-10 23:23:01 +00007927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007928posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007929{
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007931#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007933#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007935#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007936 PyObject *posobj;
7937 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007938 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007939#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7941 switch (how) {
7942 case 0: how = SEEK_SET; break;
7943 case 1: how = SEEK_CUR; break;
7944 case 2: how = SEEK_END; break;
7945 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007946#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007947
Ross Lagerwall8e749672011-03-17 21:54:07 +02007948#if !defined(HAVE_LARGEFILE_SUPPORT)
7949 pos = PyLong_AsLong(posobj);
7950#else
7951 pos = PyLong_AsLongLong(posobj);
7952#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 if (PyErr_Occurred())
7954 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007955
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 if (!_PyVerify_fd(fd))
7957 return posix_error();
7958 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007961#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007963#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 Py_END_ALLOW_THREADS
7965 if (res < 0)
7966 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007967
7968#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007970#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007972#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007973}
7974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007975
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007976PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007977"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007978Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007979
Barry Warsaw53699e91996-12-10 23:23:01 +00007980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007981posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007982{
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 int fd, size;
7984 Py_ssize_t n;
7985 PyObject *buffer;
7986 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7987 return NULL;
7988 if (size < 0) {
7989 errno = EINVAL;
7990 return posix_error();
7991 }
7992 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7993 if (buffer == NULL)
7994 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007995 if (!_PyVerify_fd(fd)) {
7996 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007998 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 Py_BEGIN_ALLOW_THREADS
8000 n = read(fd, PyBytes_AS_STRING(buffer), size);
8001 Py_END_ALLOW_THREADS
8002 if (n < 0) {
8003 Py_DECREF(buffer);
8004 return posix_error();
8005 }
8006 if (n != size)
8007 _PyBytes_Resize(&buffer, n);
8008 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008009}
8010
Ross Lagerwall7807c352011-03-17 20:20:30 +02008011#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8012 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008013static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008014iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8015{
8016 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008017 Py_ssize_t blen, total = 0;
8018
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008019 *iov = PyMem_New(struct iovec, cnt);
8020 if (*iov == NULL) {
8021 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008022 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008023 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008024
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 *buf = PyMem_New(Py_buffer, cnt);
8026 if (*buf == NULL) {
8027 PyMem_Del(*iov);
8028 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008029 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008030 }
8031
8032 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008033 PyObject *item = PySequence_GetItem(seq, i);
8034 if (item == NULL)
8035 goto fail;
8036 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8037 Py_DECREF(item);
8038 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008039 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008040 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008042 blen = (*buf)[i].len;
8043 (*iov)[i].iov_len = blen;
8044 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008045 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008046 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008047
8048fail:
8049 PyMem_Del(*iov);
8050 for (j = 0; j < i; j++) {
8051 PyBuffer_Release(&(*buf)[j]);
8052 }
8053 PyMem_Del(*buf);
8054 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055}
8056
8057static void
8058iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8059{
8060 int i;
8061 PyMem_Del(iov);
8062 for (i = 0; i < cnt; i++) {
8063 PyBuffer_Release(&buf[i]);
8064 }
8065 PyMem_Del(buf);
8066}
8067#endif
8068
Ross Lagerwall7807c352011-03-17 20:20:30 +02008069#ifdef HAVE_READV
8070PyDoc_STRVAR(posix_readv__doc__,
8071"readv(fd, buffers) -> bytesread\n\n\
8072Read from a file descriptor into a number of writable buffers. buffers\n\
8073is an arbitrary sequence of writable buffers.\n\
8074Returns the total number of bytes read.");
8075
8076static PyObject *
8077posix_readv(PyObject *self, PyObject *args)
8078{
8079 int fd, cnt;
8080 Py_ssize_t n;
8081 PyObject *seq;
8082 struct iovec *iov;
8083 Py_buffer *buf;
8084
8085 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8086 return NULL;
8087 if (!PySequence_Check(seq)) {
8088 PyErr_SetString(PyExc_TypeError,
8089 "readv() arg 2 must be a sequence");
8090 return NULL;
8091 }
8092 cnt = PySequence_Size(seq);
8093
8094 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8095 return NULL;
8096
8097 Py_BEGIN_ALLOW_THREADS
8098 n = readv(fd, iov, cnt);
8099 Py_END_ALLOW_THREADS
8100
8101 iov_cleanup(iov, buf, cnt);
8102 return PyLong_FromSsize_t(n);
8103}
8104#endif
8105
8106#ifdef HAVE_PREAD
8107PyDoc_STRVAR(posix_pread__doc__,
8108"pread(fd, buffersize, offset) -> string\n\n\
8109Read from a file descriptor, fd, at a position of offset. It will read up\n\
8110to buffersize number of bytes. The file offset remains unchanged.");
8111
8112static PyObject *
8113posix_pread(PyObject *self, PyObject *args)
8114{
8115 int fd, size;
8116 off_t offset;
8117 Py_ssize_t n;
8118 PyObject *buffer;
8119 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8120 return NULL;
8121
8122 if (size < 0) {
8123 errno = EINVAL;
8124 return posix_error();
8125 }
8126 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8127 if (buffer == NULL)
8128 return NULL;
8129 if (!_PyVerify_fd(fd)) {
8130 Py_DECREF(buffer);
8131 return posix_error();
8132 }
8133 Py_BEGIN_ALLOW_THREADS
8134 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8135 Py_END_ALLOW_THREADS
8136 if (n < 0) {
8137 Py_DECREF(buffer);
8138 return posix_error();
8139 }
8140 if (n != size)
8141 _PyBytes_Resize(&buffer, n);
8142 return buffer;
8143}
8144#endif
8145
8146PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008147"write(fd, data) -> byteswritten\n\n\
8148Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149
8150static PyObject *
8151posix_write(PyObject *self, PyObject *args)
8152{
8153 Py_buffer pbuf;
8154 int fd;
8155 Py_ssize_t size, len;
8156
8157 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8158 return NULL;
8159 if (!_PyVerify_fd(fd)) {
8160 PyBuffer_Release(&pbuf);
8161 return posix_error();
8162 }
8163 len = pbuf.len;
8164 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008165#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166 if (len > INT_MAX)
8167 len = INT_MAX;
8168 size = write(fd, pbuf.buf, (int)len);
8169#else
8170 size = write(fd, pbuf.buf, len);
8171#endif
8172 Py_END_ALLOW_THREADS
8173 PyBuffer_Release(&pbuf);
8174 if (size < 0)
8175 return posix_error();
8176 return PyLong_FromSsize_t(size);
8177}
8178
8179#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008180PyDoc_STRVAR(posix_sendfile__doc__,
8181"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8182sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8183 -> byteswritten\n\
8184Copy nbytes bytes from file descriptor in to file descriptor out.");
8185
8186static PyObject *
8187posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8188{
8189 int in, out;
8190 Py_ssize_t ret;
8191 off_t offset;
8192
8193#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8194#ifndef __APPLE__
8195 Py_ssize_t len;
8196#endif
8197 PyObject *headers = NULL, *trailers = NULL;
8198 Py_buffer *hbuf, *tbuf;
8199 off_t sbytes;
8200 struct sf_hdtr sf;
8201 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008202 static char *keywords[] = {"out", "in",
8203 "offset", "count",
8204 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008205
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008206 sf.headers = NULL;
8207 sf.trailers = NULL;
8208
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008209#ifdef __APPLE__
8210 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008211 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008212#else
8213 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008214 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008215#endif
8216 &headers, &trailers, &flags))
8217 return NULL;
8218 if (headers != NULL) {
8219 if (!PySequence_Check(headers)) {
8220 PyErr_SetString(PyExc_TypeError,
8221 "sendfile() headers must be a sequence or None");
8222 return NULL;
8223 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008224 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008226 if (sf.hdr_cnt > 0 &&
8227 !(i = iov_setup(&(sf.headers), &hbuf,
8228 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008229 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008230#ifdef __APPLE__
8231 sbytes += i;
8232#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008233 }
8234 }
8235 if (trailers != NULL) {
8236 if (!PySequence_Check(trailers)) {
8237 PyErr_SetString(PyExc_TypeError,
8238 "sendfile() trailers must be a sequence or None");
8239 return NULL;
8240 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008241 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008243 if (sf.trl_cnt > 0 &&
8244 !(i = iov_setup(&(sf.trailers), &tbuf,
8245 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008246 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008247#ifdef __APPLE__
8248 sbytes += i;
8249#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008250 }
8251 }
8252
8253 Py_BEGIN_ALLOW_THREADS
8254#ifdef __APPLE__
8255 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8256#else
8257 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8258#endif
8259 Py_END_ALLOW_THREADS
8260
8261 if (sf.headers != NULL)
8262 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8263 if (sf.trailers != NULL)
8264 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8265
8266 if (ret < 0) {
8267 if ((errno == EAGAIN) || (errno == EBUSY)) {
8268 if (sbytes != 0) {
8269 // some data has been sent
8270 goto done;
8271 }
8272 else {
8273 // no data has been sent; upper application is supposed
8274 // to retry on EAGAIN or EBUSY
8275 return posix_error();
8276 }
8277 }
8278 return posix_error();
8279 }
8280 goto done;
8281
8282done:
8283 #if !defined(HAVE_LARGEFILE_SUPPORT)
8284 return Py_BuildValue("l", sbytes);
8285 #else
8286 return Py_BuildValue("L", sbytes);
8287 #endif
8288
8289#else
8290 Py_ssize_t count;
8291 PyObject *offobj;
8292 static char *keywords[] = {"out", "in",
8293 "offset", "count", NULL};
8294 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8295 keywords, &out, &in, &offobj, &count))
8296 return NULL;
8297#ifdef linux
8298 if (offobj == Py_None) {
8299 Py_BEGIN_ALLOW_THREADS
8300 ret = sendfile(out, in, NULL, count);
8301 Py_END_ALLOW_THREADS
8302 if (ret < 0)
8303 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008304 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305 }
8306#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008307 if (!_parse_off_t(offobj, &offset))
8308 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309 Py_BEGIN_ALLOW_THREADS
8310 ret = sendfile(out, in, &offset, count);
8311 Py_END_ALLOW_THREADS
8312 if (ret < 0)
8313 return posix_error();
8314 return Py_BuildValue("n", ret);
8315#endif
8316}
8317#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008319PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008320"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008321Like stat(), but for an open file descriptor.\n\
8322Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008323
Barry Warsaw53699e91996-12-10 23:23:01 +00008324static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008325posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008326{
Victor Stinner8c62be82010-05-06 00:08:46 +00008327 int fd;
8328 STRUCT_STAT st;
8329 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008330 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008332#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 /* on OpenVMS we must ensure that all bytes are written to the file */
8334 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008335#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008336 Py_BEGIN_ALLOW_THREADS
8337 res = FSTAT(fd, &st);
8338 Py_END_ALLOW_THREADS
8339 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008340#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008341 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008342#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008344#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 }
Tim Peters5aa91602002-01-30 05:46:57 +00008346
Victor Stinner4195b5c2012-02-08 23:03:19 +01008347 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008348}
8349
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008350PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008351"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008352Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008353connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008354
8355static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008356posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008357{
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 int fd;
8359 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8360 return NULL;
8361 if (!_PyVerify_fd(fd))
8362 return PyBool_FromLong(0);
8363 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008364}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008365
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008366#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008367PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008368"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008369Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008370
Barry Warsaw53699e91996-12-10 23:23:01 +00008371static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008372posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008373{
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008375#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008377 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008379#else
8380 int res;
8381#endif
8382
8383#ifdef MS_WINDOWS
8384 attr.nLength = sizeof(attr);
8385 attr.lpSecurityDescriptor = NULL;
8386 attr.bInheritHandle = FALSE;
8387
8388 Py_BEGIN_ALLOW_THREADS
8389 ok = CreatePipe(&read, &write, &attr, 0);
8390 if (ok) {
8391 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8392 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8393 if (fds[0] == -1 || fds[1] == -1) {
8394 CloseHandle(read);
8395 CloseHandle(write);
8396 ok = 0;
8397 }
8398 }
8399 Py_END_ALLOW_THREADS
8400
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008402 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008403#else
8404
8405#ifdef HAVE_PIPE2
8406 Py_BEGIN_ALLOW_THREADS
8407 res = pipe2(fds, O_CLOEXEC);
8408 Py_END_ALLOW_THREADS
8409
8410 if (res != 0 && errno == ENOSYS)
8411 {
8412#endif
8413 Py_BEGIN_ALLOW_THREADS
8414 res = pipe(fds);
8415 Py_END_ALLOW_THREADS
8416
8417 if (res == 0) {
8418 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8419 close(fds[0]);
8420 close(fds[1]);
8421 return NULL;
8422 }
8423 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8424 close(fds[0]);
8425 close(fds[1]);
8426 return NULL;
8427 }
8428 }
8429#ifdef HAVE_PIPE2
8430 }
8431#endif
8432
8433 if (res != 0)
8434 return PyErr_SetFromErrno(PyExc_OSError);
8435#endif /* !MS_WINDOWS */
8436 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008437}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008438#endif /* HAVE_PIPE */
8439
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008440#ifdef HAVE_PIPE2
8441PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008442"pipe2(flags) -> (read_end, write_end)\n\n\
8443Create a pipe with flags set atomically.\n\
8444flags can be constructed by ORing together one or more of these values:\n\
8445O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008446");
8447
8448static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008449posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008450{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008451 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008452 int fds[2];
8453 int res;
8454
Serhiy Storchaka78980432013-01-15 01:12:17 +02008455 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008456 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008457 return NULL;
8458
8459 res = pipe2(fds, flags);
8460 if (res != 0)
8461 return posix_error();
8462 return Py_BuildValue("(ii)", fds[0], fds[1]);
8463}
8464#endif /* HAVE_PIPE2 */
8465
Ross Lagerwall7807c352011-03-17 20:20:30 +02008466#ifdef HAVE_WRITEV
8467PyDoc_STRVAR(posix_writev__doc__,
8468"writev(fd, buffers) -> byteswritten\n\n\
8469Write the contents of buffers to a file descriptor, where buffers is an\n\
8470arbitrary sequence of buffers.\n\
8471Returns the total bytes written.");
8472
8473static PyObject *
8474posix_writev(PyObject *self, PyObject *args)
8475{
8476 int fd, cnt;
8477 Py_ssize_t res;
8478 PyObject *seq;
8479 struct iovec *iov;
8480 Py_buffer *buf;
8481 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8482 return NULL;
8483 if (!PySequence_Check(seq)) {
8484 PyErr_SetString(PyExc_TypeError,
8485 "writev() arg 2 must be a sequence");
8486 return NULL;
8487 }
8488 cnt = PySequence_Size(seq);
8489
8490 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8491 return NULL;
8492 }
8493
8494 Py_BEGIN_ALLOW_THREADS
8495 res = writev(fd, iov, cnt);
8496 Py_END_ALLOW_THREADS
8497
8498 iov_cleanup(iov, buf, cnt);
8499 return PyLong_FromSsize_t(res);
8500}
8501#endif
8502
8503#ifdef HAVE_PWRITE
8504PyDoc_STRVAR(posix_pwrite__doc__,
8505"pwrite(fd, string, offset) -> byteswritten\n\n\
8506Write string to a file descriptor, fd, from offset, leaving the file\n\
8507offset unchanged.");
8508
8509static PyObject *
8510posix_pwrite(PyObject *self, PyObject *args)
8511{
8512 Py_buffer pbuf;
8513 int fd;
8514 off_t offset;
8515 Py_ssize_t size;
8516
8517 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8518 return NULL;
8519
8520 if (!_PyVerify_fd(fd)) {
8521 PyBuffer_Release(&pbuf);
8522 return posix_error();
8523 }
8524 Py_BEGIN_ALLOW_THREADS
8525 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8526 Py_END_ALLOW_THREADS
8527 PyBuffer_Release(&pbuf);
8528 if (size < 0)
8529 return posix_error();
8530 return PyLong_FromSsize_t(size);
8531}
8532#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008533
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008534#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008535PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008536"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8537Create a FIFO (a POSIX named pipe).\n\
8538\n\
8539If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8540 and path should be relative; path will then be relative to that directory.\n\
8541dir_fd may not be implemented on your platform.\n\
8542 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008543
Barry Warsaw53699e91996-12-10 23:23:01 +00008544static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008545posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008546{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008547 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008549 int dir_fd = DEFAULT_DIR_FD;
8550 int result;
8551 PyObject *return_value = NULL;
8552 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8553
8554 memset(&path, 0, sizeof(path));
8555 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8556 path_converter, &path,
8557 &mode,
8558#ifdef HAVE_MKFIFOAT
8559 dir_fd_converter, &dir_fd
8560#else
8561 dir_fd_unavailable, &dir_fd
8562#endif
8563 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008565
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008567#ifdef HAVE_MKFIFOAT
8568 if (dir_fd != DEFAULT_DIR_FD)
8569 result = mkfifoat(dir_fd, path.narrow, mode);
8570 else
8571#endif
8572 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008574
8575 if (result < 0) {
8576 return_value = posix_error();
8577 goto exit;
8578 }
8579
8580 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008582
8583exit:
8584 path_cleanup(&path);
8585 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008586}
8587#endif
8588
Neal Norwitz11690112002-07-30 01:08:28 +00008589#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008590PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008591"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008592Create a filesystem node (file, device special file or named pipe)\n\
8593named filename. mode specifies both the permissions to use and the\n\
8594type of node to be created, being combined (bitwise OR) with one of\n\
8595S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008596device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008597os.makedev()), otherwise it is ignored.\n\
8598\n\
8599If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8600 and path should be relative; path will then be relative to that directory.\n\
8601dir_fd may not be implemented on your platform.\n\
8602 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008603
8604
8605static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008606posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008607{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008608 path_t path;
8609 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008611 int dir_fd = DEFAULT_DIR_FD;
8612 int result;
8613 PyObject *return_value = NULL;
8614 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8615
8616 memset(&path, 0, sizeof(path));
8617 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8618 path_converter, &path,
8619 &mode, &device,
8620#ifdef HAVE_MKNODAT
8621 dir_fd_converter, &dir_fd
8622#else
8623 dir_fd_unavailable, &dir_fd
8624#endif
8625 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008627
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008629#ifdef HAVE_MKNODAT
8630 if (dir_fd != DEFAULT_DIR_FD)
8631 result = mknodat(dir_fd, path.narrow, mode, device);
8632 else
8633#endif
8634 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008636
8637 if (result < 0) {
8638 return_value = posix_error();
8639 goto exit;
8640 }
8641
8642 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008643 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008644
Larry Hastings9cf065c2012-06-22 16:30:09 -07008645exit:
8646 path_cleanup(&path);
8647 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008648}
8649#endif
8650
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008651#ifdef HAVE_DEVICE_MACROS
8652PyDoc_STRVAR(posix_major__doc__,
8653"major(device) -> major number\n\
8654Extracts a device major number from a raw device number.");
8655
8656static PyObject *
8657posix_major(PyObject *self, PyObject *args)
8658{
Victor Stinner8c62be82010-05-06 00:08:46 +00008659 int device;
8660 if (!PyArg_ParseTuple(args, "i:major", &device))
8661 return NULL;
8662 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008663}
8664
8665PyDoc_STRVAR(posix_minor__doc__,
8666"minor(device) -> minor number\n\
8667Extracts a device minor number from a raw device number.");
8668
8669static PyObject *
8670posix_minor(PyObject *self, PyObject *args)
8671{
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 int device;
8673 if (!PyArg_ParseTuple(args, "i:minor", &device))
8674 return NULL;
8675 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008676}
8677
8678PyDoc_STRVAR(posix_makedev__doc__,
8679"makedev(major, minor) -> device number\n\
8680Composes a raw device number from the major and minor device numbers.");
8681
8682static PyObject *
8683posix_makedev(PyObject *self, PyObject *args)
8684{
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 int major, minor;
8686 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8687 return NULL;
8688 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008689}
8690#endif /* device macros */
8691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008692
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008693#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008694PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008695"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008696Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008697
Barry Warsaw53699e91996-12-10 23:23:01 +00008698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008699posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008700{
Victor Stinner8c62be82010-05-06 00:08:46 +00008701 int fd;
8702 off_t length;
8703 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008704
Ross Lagerwall7807c352011-03-17 20:20:30 +02008705 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008707
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 Py_BEGIN_ALLOW_THREADS
8709 res = ftruncate(fd, length);
8710 Py_END_ALLOW_THREADS
8711 if (res < 0)
8712 return posix_error();
8713 Py_INCREF(Py_None);
8714 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008715}
8716#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008717
Ross Lagerwall7807c352011-03-17 20:20:30 +02008718#ifdef HAVE_TRUNCATE
8719PyDoc_STRVAR(posix_truncate__doc__,
8720"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008721Truncate the file given by path to length bytes.\n\
8722On some platforms, path may also be specified as an open file descriptor.\n\
8723 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008724
8725static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008726posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008727{
Georg Brandl306336b2012-06-24 12:55:33 +02008728 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729 off_t length;
8730 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008731 PyObject *result = NULL;
8732 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008733
Georg Brandl306336b2012-06-24 12:55:33 +02008734 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008735 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008736#ifdef HAVE_FTRUNCATE
8737 path.allow_fd = 1;
8738#endif
8739 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8740 path_converter, &path,
8741 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008743
8744 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008745#ifdef HAVE_FTRUNCATE
8746 if (path.fd != -1)
8747 res = ftruncate(path.fd, length);
8748 else
8749#endif
8750 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008751 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008752 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008753 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008754 else {
8755 Py_INCREF(Py_None);
8756 result = Py_None;
8757 }
8758 path_cleanup(&path);
8759 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008760}
8761#endif
8762
8763#ifdef HAVE_POSIX_FALLOCATE
8764PyDoc_STRVAR(posix_posix_fallocate__doc__,
8765"posix_fallocate(fd, offset, len)\n\n\
8766Ensures that enough disk space is allocated for the file specified by fd\n\
8767starting from offset and continuing for len bytes.");
8768
8769static PyObject *
8770posix_posix_fallocate(PyObject *self, PyObject *args)
8771{
8772 off_t len, offset;
8773 int res, fd;
8774
8775 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8776 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8777 return NULL;
8778
8779 Py_BEGIN_ALLOW_THREADS
8780 res = posix_fallocate(fd, offset, len);
8781 Py_END_ALLOW_THREADS
8782 if (res != 0) {
8783 errno = res;
8784 return posix_error();
8785 }
8786 Py_RETURN_NONE;
8787}
8788#endif
8789
8790#ifdef HAVE_POSIX_FADVISE
8791PyDoc_STRVAR(posix_posix_fadvise__doc__,
8792"posix_fadvise(fd, offset, len, advice)\n\n\
8793Announces an intention to access data in a specific pattern thus allowing\n\
8794the kernel to make optimizations.\n\
8795The advice applies to the region of the file specified by fd starting at\n\
8796offset and continuing for len bytes.\n\
8797advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8798POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8799POSIX_FADV_DONTNEED.");
8800
8801static PyObject *
8802posix_posix_fadvise(PyObject *self, PyObject *args)
8803{
8804 off_t len, offset;
8805 int res, fd, advice;
8806
8807 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8808 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8809 return NULL;
8810
8811 Py_BEGIN_ALLOW_THREADS
8812 res = posix_fadvise(fd, offset, len, advice);
8813 Py_END_ALLOW_THREADS
8814 if (res != 0) {
8815 errno = res;
8816 return posix_error();
8817 }
8818 Py_RETURN_NONE;
8819}
8820#endif
8821
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008822#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008823PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008824"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008825Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008826
Fred Drake762e2061999-08-26 17:23:54 +00008827/* Save putenv() parameters as values here, so we can collect them when they
8828 * get re-set with another call for the same key. */
8829static PyObject *posix_putenv_garbage;
8830
Tim Peters5aa91602002-01-30 05:46:57 +00008831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008832posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008833{
Victor Stinner84ae1182010-05-06 22:05:07 +00008834 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008835#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008836 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008837 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008838
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008840 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008841 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008843
Victor Stinner65170952011-11-22 22:16:17 +01008844 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008845 if (newstr == NULL) {
8846 PyErr_NoMemory();
8847 goto error;
8848 }
Victor Stinner65170952011-11-22 22:16:17 +01008849 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8850 PyErr_Format(PyExc_ValueError,
8851 "the environment variable is longer than %u characters",
8852 _MAX_ENV);
8853 goto error;
8854 }
8855
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008857 if (newenv == NULL)
8858 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008861 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008863#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008864 PyObject *os1, *os2;
8865 char *s1, *s2;
8866 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008867
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008868 if (!PyArg_ParseTuple(args,
8869 "O&O&:putenv",
8870 PyUnicode_FSConverter, &os1,
8871 PyUnicode_FSConverter, &os2))
8872 return NULL;
8873 s1 = PyBytes_AsString(os1);
8874 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008875
Victor Stinner65170952011-11-22 22:16:17 +01008876 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008877 if (newstr == NULL) {
8878 PyErr_NoMemory();
8879 goto error;
8880 }
8881
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008885 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008887#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008888
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 /* Install the first arg and newstr in posix_putenv_garbage;
8890 * this will cause previous value to be collected. This has to
8891 * happen after the real putenv() call because the old value
8892 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008893 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 /* really not much we can do; just leak */
8895 PyErr_Clear();
8896 }
8897 else {
8898 Py_DECREF(newstr);
8899 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008900
Martin v. Löwis011e8422009-05-05 04:43:17 +00008901#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 Py_DECREF(os1);
8903 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008904#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008905 Py_RETURN_NONE;
8906
8907error:
8908#ifndef MS_WINDOWS
8909 Py_DECREF(os1);
8910 Py_DECREF(os2);
8911#endif
8912 Py_XDECREF(newstr);
8913 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008914}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008915#endif /* putenv */
8916
Guido van Rossumc524d952001-10-19 01:31:59 +00008917#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008918PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008919"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008920Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008921
8922static PyObject *
8923posix_unsetenv(PyObject *self, PyObject *args)
8924{
Victor Stinner65170952011-11-22 22:16:17 +01008925 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008926#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008927 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008928#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008929
8930 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008931
Victor Stinner65170952011-11-22 22:16:17 +01008932 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008933 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008934
Victor Stinner984890f2011-11-24 13:53:38 +01008935#ifdef HAVE_BROKEN_UNSETENV
8936 unsetenv(PyBytes_AS_STRING(name));
8937#else
Victor Stinner65170952011-11-22 22:16:17 +01008938 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008939 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008940 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008941 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008942 }
Victor Stinner984890f2011-11-24 13:53:38 +01008943#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008944
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 /* Remove the key from posix_putenv_garbage;
8946 * this will cause it to be collected. This has to
8947 * happen after the real unsetenv() call because the
8948 * old value was still accessible until then.
8949 */
Victor Stinner65170952011-11-22 22:16:17 +01008950 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 /* really not much we can do; just leak */
8952 PyErr_Clear();
8953 }
Victor Stinner65170952011-11-22 22:16:17 +01008954 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008955 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008956}
8957#endif /* unsetenv */
8958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008959PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008960"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008961Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008962
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008964posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008965{
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 int code;
8967 char *message;
8968 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8969 return NULL;
8970 message = strerror(code);
8971 if (message == NULL) {
8972 PyErr_SetString(PyExc_ValueError,
8973 "strerror() argument out of range");
8974 return NULL;
8975 }
Victor Stinner1b579672011-12-17 05:47:23 +01008976 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008977}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008978
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008979
Guido van Rossumc9641791998-08-04 15:26:23 +00008980#ifdef HAVE_SYS_WAIT_H
8981
Fred Drake106c1a02002-04-23 15:58:02 +00008982#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008983PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008984"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008985Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008986
8987static PyObject *
8988posix_WCOREDUMP(PyObject *self, PyObject *args)
8989{
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 WAIT_TYPE status;
8991 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008992
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8994 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008995
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008997}
8998#endif /* WCOREDUMP */
8999
9000#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009001PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009002"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009003Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009004job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009005
9006static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009007posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009008{
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 WAIT_TYPE status;
9010 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009011
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9013 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009014
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009016}
9017#endif /* WIFCONTINUED */
9018
Guido van Rossumc9641791998-08-04 15:26:23 +00009019#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009020PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009021"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009022Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009023
9024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009025posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009026{
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 WAIT_TYPE status;
9028 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009029
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9031 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009032
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009034}
9035#endif /* WIFSTOPPED */
9036
9037#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009038PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009039"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009040Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009041
9042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009043posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009044{
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 WAIT_TYPE status;
9046 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009047
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9049 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009050
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009052}
9053#endif /* WIFSIGNALED */
9054
9055#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009056PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009057"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009058Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009059system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009060
9061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009062posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009063{
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 WAIT_TYPE status;
9065 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009066
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9068 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009069
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009071}
9072#endif /* WIFEXITED */
9073
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009074#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009075PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009076"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009077Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009078
9079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009080posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009081{
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 WAIT_TYPE status;
9083 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009084
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9086 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009087
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009089}
9090#endif /* WEXITSTATUS */
9091
9092#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009093PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009094"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009095Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009096value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009097
9098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009099posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009100{
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 WAIT_TYPE status;
9102 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009103
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9105 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009106
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009108}
9109#endif /* WTERMSIG */
9110
9111#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009112PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009113"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009114Return the signal that stopped the process that provided\n\
9115the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009116
9117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009118posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009119{
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 WAIT_TYPE status;
9121 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009122
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9124 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009127}
9128#endif /* WSTOPSIG */
9129
9130#endif /* HAVE_SYS_WAIT_H */
9131
9132
Thomas Wouters477c8d52006-05-27 19:21:47 +00009133#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009134#ifdef _SCO_DS
9135/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9136 needed definitions in sys/statvfs.h */
9137#define _SVID3
9138#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009139#include <sys/statvfs.h>
9140
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009141static PyObject*
9142_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9144 if (v == NULL)
9145 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009146
9147#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9149 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9150 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9151 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9152 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9153 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9154 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9155 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9156 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9157 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009158#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009159 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9160 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9161 PyStructSequence_SET_ITEM(v, 2,
9162 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9163 PyStructSequence_SET_ITEM(v, 3,
9164 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9165 PyStructSequence_SET_ITEM(v, 4,
9166 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9167 PyStructSequence_SET_ITEM(v, 5,
9168 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9169 PyStructSequence_SET_ITEM(v, 6,
9170 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9171 PyStructSequence_SET_ITEM(v, 7,
9172 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9173 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9174 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009175#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009176 if (PyErr_Occurred()) {
9177 Py_DECREF(v);
9178 return NULL;
9179 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009180
Victor Stinner8c62be82010-05-06 00:08:46 +00009181 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009182}
9183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009184PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009185"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009186Perform an fstatvfs system call on the given fd.\n\
9187Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009188
9189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009190posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009191{
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 int fd, res;
9193 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009194
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9196 return NULL;
9197 Py_BEGIN_ALLOW_THREADS
9198 res = fstatvfs(fd, &st);
9199 Py_END_ALLOW_THREADS
9200 if (res != 0)
9201 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009202
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009204}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009205#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009206
9207
Thomas Wouters477c8d52006-05-27 19:21:47 +00009208#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009209#include <sys/statvfs.h>
9210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009211PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009212"statvfs(path)\n\n\
9213Perform a statvfs system call on the given path.\n\
9214\n\
9215path may always be specified as a string.\n\
9216On some platforms, path may also be specified as an open file descriptor.\n\
9217 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009218
9219static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009220posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009221{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009222 static char *keywords[] = {"path", NULL};
9223 path_t path;
9224 int result;
9225 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009227
Larry Hastings9cf065c2012-06-22 16:30:09 -07009228 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009229 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009230#ifdef HAVE_FSTATVFS
9231 path.allow_fd = 1;
9232#endif
9233 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9234 path_converter, &path
9235 ))
9236 return NULL;
9237
9238 Py_BEGIN_ALLOW_THREADS
9239#ifdef HAVE_FSTATVFS
9240 if (path.fd != -1) {
9241#ifdef __APPLE__
9242 /* handle weak-linking on Mac OS X 10.3 */
9243 if (fstatvfs == NULL) {
9244 fd_specified("statvfs", path.fd);
9245 goto exit;
9246 }
9247#endif
9248 result = fstatvfs(path.fd, &st);
9249 }
9250 else
9251#endif
9252 result = statvfs(path.narrow, &st);
9253 Py_END_ALLOW_THREADS
9254
9255 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009256 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009257 goto exit;
9258 }
9259
9260 return_value = _pystatvfs_fromstructstatvfs(st);
9261
9262exit:
9263 path_cleanup(&path);
9264 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009265}
9266#endif /* HAVE_STATVFS */
9267
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009268#ifdef MS_WINDOWS
9269PyDoc_STRVAR(win32__getdiskusage__doc__,
9270"_getdiskusage(path) -> (total, free)\n\n\
9271Return disk usage statistics about the given path as (total, free) tuple.");
9272
9273static PyObject *
9274win32__getdiskusage(PyObject *self, PyObject *args)
9275{
9276 BOOL retval;
9277 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009278 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009279
Victor Stinner6139c1b2011-11-09 22:14:14 +01009280 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009281 return NULL;
9282
9283 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009284 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009285 Py_END_ALLOW_THREADS
9286 if (retval == 0)
9287 return PyErr_SetFromWindowsErr(0);
9288
9289 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9290}
9291#endif
9292
9293
Fred Drakec9680921999-12-13 16:37:25 +00009294/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9295 * It maps strings representing configuration variable names to
9296 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009297 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009298 * rarely-used constants. There are three separate tables that use
9299 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009300 *
9301 * This code is always included, even if none of the interfaces that
9302 * need it are included. The #if hackery needed to avoid it would be
9303 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009304 */
9305struct constdef {
9306 char *name;
9307 long value;
9308};
9309
Fred Drake12c6e2d1999-12-14 21:25:03 +00009310static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009311conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009312 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009313{
Christian Heimes217cfd12007-12-02 14:31:20 +00009314 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009315 *valuep = PyLong_AS_LONG(arg);
9316 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009317 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009318 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009319 /* look up the value in the table using a binary search */
9320 size_t lo = 0;
9321 size_t mid;
9322 size_t hi = tablesize;
9323 int cmp;
9324 const char *confname;
9325 if (!PyUnicode_Check(arg)) {
9326 PyErr_SetString(PyExc_TypeError,
9327 "configuration names must be strings or integers");
9328 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009330 confname = _PyUnicode_AsString(arg);
9331 if (confname == NULL)
9332 return 0;
9333 while (lo < hi) {
9334 mid = (lo + hi) / 2;
9335 cmp = strcmp(confname, table[mid].name);
9336 if (cmp < 0)
9337 hi = mid;
9338 else if (cmp > 0)
9339 lo = mid + 1;
9340 else {
9341 *valuep = table[mid].value;
9342 return 1;
9343 }
9344 }
9345 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9346 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009348}
9349
9350
9351#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9352static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009353#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009355#endif
9356#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009358#endif
Fred Drakec9680921999-12-13 16:37:25 +00009359#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009361#endif
9362#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009404#ifdef _PC_ACL_ENABLED
9405 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9406#endif
9407#ifdef _PC_MIN_HOLE_SIZE
9408 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9409#endif
9410#ifdef _PC_ALLOC_SIZE_MIN
9411 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9412#endif
9413#ifdef _PC_REC_INCR_XFER_SIZE
9414 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9415#endif
9416#ifdef _PC_REC_MAX_XFER_SIZE
9417 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9418#endif
9419#ifdef _PC_REC_MIN_XFER_SIZE
9420 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9421#endif
9422#ifdef _PC_REC_XFER_ALIGN
9423 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9424#endif
9425#ifdef _PC_SYMLINK_MAX
9426 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9427#endif
9428#ifdef _PC_XATTR_ENABLED
9429 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9430#endif
9431#ifdef _PC_XATTR_EXISTS
9432 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9433#endif
9434#ifdef _PC_TIMESTAMP_RESOLUTION
9435 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9436#endif
Fred Drakec9680921999-12-13 16:37:25 +00009437};
9438
Fred Drakec9680921999-12-13 16:37:25 +00009439static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009440conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009441{
9442 return conv_confname(arg, valuep, posix_constants_pathconf,
9443 sizeof(posix_constants_pathconf)
9444 / sizeof(struct constdef));
9445}
9446#endif
9447
9448#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009449PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009450"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009451Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009452If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009453
9454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009455posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009456{
9457 PyObject *result = NULL;
9458 int name, fd;
9459
Fred Drake12c6e2d1999-12-14 21:25:03 +00009460 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9461 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009462 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009463
Stefan Krah0e803b32010-11-26 16:16:47 +00009464 errno = 0;
9465 limit = fpathconf(fd, name);
9466 if (limit == -1 && errno != 0)
9467 posix_error();
9468 else
9469 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009470 }
9471 return result;
9472}
9473#endif
9474
9475
9476#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009477PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009478"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009479Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009480If there is no limit, return -1.\n\
9481On some platforms, path may also be specified as an open file descriptor.\n\
9482 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009483
9484static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009485posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009486{
Georg Brandl306336b2012-06-24 12:55:33 +02009487 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009488 PyObject *result = NULL;
9489 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009490 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009491
Georg Brandl306336b2012-06-24 12:55:33 +02009492 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009493 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009494#ifdef HAVE_FPATHCONF
9495 path.allow_fd = 1;
9496#endif
9497 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9498 path_converter, &path,
9499 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009501
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009503#ifdef HAVE_FPATHCONF
9504 if (path.fd != -1)
9505 limit = fpathconf(path.fd, name);
9506 else
9507#endif
9508 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 if (limit == -1 && errno != 0) {
9510 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009511 /* could be a path or name problem */
9512 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009513 else
Victor Stinner292c8352012-10-30 02:17:38 +01009514 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 }
9516 else
9517 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009518 }
Georg Brandl306336b2012-06-24 12:55:33 +02009519 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009520 return result;
9521}
9522#endif
9523
9524#ifdef HAVE_CONFSTR
9525static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009526#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009528#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009529#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009531#endif
9532#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009534#endif
Fred Draked86ed291999-12-15 15:34:33 +00009535#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009537#endif
9538#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009540#endif
9541#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009543#endif
9544#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009546#endif
Fred Drakec9680921999-12-13 16:37:25 +00009547#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
Fred Draked86ed291999-12-15 15:34:33 +00009571#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009573#endif
Fred Drakec9680921999-12-13 16:37:25 +00009574#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
Fred Draked86ed291999-12-15 15:34:33 +00009577#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009579#endif
9580#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009582#endif
9583#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009585#endif
9586#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009588#endif
Fred Drakec9680921999-12-13 16:37:25 +00009589#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
9625#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
Fred Draked86ed291999-12-15 15:34:33 +00009637#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
9640#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009642#endif
9643#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009645#endif
9646#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009648#endif
9649#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
9652#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
9655#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009657#endif
9658#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
9661#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009663#endif
9664#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009666#endif
9667#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
9670#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009672#endif
9673#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009675#endif
Fred Drakec9680921999-12-13 16:37:25 +00009676};
9677
9678static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009679conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009680{
9681 return conv_confname(arg, valuep, posix_constants_confstr,
9682 sizeof(posix_constants_confstr)
9683 / sizeof(struct constdef));
9684}
9685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009686PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009687"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009688Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009689
9690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009691posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009692{
9693 PyObject *result = NULL;
9694 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009695 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009696 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009697
Victor Stinnercb043522010-09-10 23:49:04 +00009698 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9699 return NULL;
9700
9701 errno = 0;
9702 len = confstr(name, buffer, sizeof(buffer));
9703 if (len == 0) {
9704 if (errno) {
9705 posix_error();
9706 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009707 }
9708 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009709 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009710 }
9711 }
Victor Stinnercb043522010-09-10 23:49:04 +00009712
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009713 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009714 char *buf = PyMem_Malloc(len);
9715 if (buf == NULL)
9716 return PyErr_NoMemory();
9717 confstr(name, buf, len);
9718 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9719 PyMem_Free(buf);
9720 }
9721 else
9722 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009723 return result;
9724}
9725#endif
9726
9727
9728#ifdef HAVE_SYSCONF
9729static struct constdef posix_constants_sysconf[] = {
9730#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
Fred Draked86ed291999-12-15 15:34:33 +00009760#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009762#endif
9763#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009765#endif
Fred Drakec9680921999-12-13 16:37:25 +00009766#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
Fred Drakec9680921999-12-13 16:37:25 +00009769#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
Fred Draked86ed291999-12-15 15:34:33 +00009784#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009786#endif
Fred Drakec9680921999-12-13 16:37:25 +00009787#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
Fred Draked86ed291999-12-15 15:34:33 +00009802#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009804#endif
Fred Drakec9680921999-12-13 16:37:25 +00009805#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
9841#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
Fred Draked86ed291999-12-15 15:34:33 +00009874#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009876#endif
Fred Drakec9680921999-12-13 16:37:25 +00009877#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
Fred Draked86ed291999-12-15 15:34:33 +00009886#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009888#endif
Fred Drakec9680921999-12-13 16:37:25 +00009889#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
Fred Draked86ed291999-12-15 15:34:33 +00009892#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009894#endif
9895#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009897#endif
Fred Drakec9680921999-12-13 16:37:25 +00009898#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
Fred Draked86ed291999-12-15 15:34:33 +00009910#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009912#endif
Fred Drakec9680921999-12-13 16:37:25 +00009913#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
Fred Draked86ed291999-12-15 15:34:33 +00009934#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009936#endif
Fred Drakec9680921999-12-13 16:37:25 +00009937#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
Fred Draked86ed291999-12-15 15:34:33 +00009943#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009945#endif
Fred Drakec9680921999-12-13 16:37:25 +00009946#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
Fred Draked86ed291999-12-15 15:34:33 +00009973#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009975#endif
9976#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009978#endif
Fred Drakec9680921999-12-13 16:37:25 +00009979#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
Fred Draked86ed291999-12-15 15:34:33 +000010084#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010086#endif
Fred Drakec9680921999-12-13 16:37:25 +000010087#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222};
10223
10224static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010225conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010226{
10227 return conv_confname(arg, valuep, posix_constants_sysconf,
10228 sizeof(posix_constants_sysconf)
10229 / sizeof(struct constdef));
10230}
10231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010232PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010233"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010234Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010235
10236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010237posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010238{
10239 PyObject *result = NULL;
10240 int name;
10241
10242 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010243 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010244
10245 errno = 0;
10246 value = sysconf(name);
10247 if (value == -1 && errno != 0)
10248 posix_error();
10249 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010250 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010251 }
10252 return result;
10253}
10254#endif
10255
10256
Fred Drakebec628d1999-12-15 18:31:10 +000010257/* This code is used to ensure that the tables of configuration value names
10258 * are in sorted order as required by conv_confname(), and also to build the
10259 * the exported dictionaries that are used to publish information about the
10260 * names available on the host platform.
10261 *
10262 * Sorting the table at runtime ensures that the table is properly ordered
10263 * when used, even for platforms we're not able to test on. It also makes
10264 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010265 */
Fred Drakebec628d1999-12-15 18:31:10 +000010266
10267static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010268cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010269{
10270 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010272 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010274
10275 return strcmp(c1->name, c2->name);
10276}
10277
10278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010279setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010281{
Fred Drakebec628d1999-12-15 18:31:10 +000010282 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010283 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010284
10285 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10286 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010287 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010289
Barry Warsaw3155db32000-04-13 15:20:40 +000010290 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 PyObject *o = PyLong_FromLong(table[i].value);
10292 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10293 Py_XDECREF(o);
10294 Py_DECREF(d);
10295 return -1;
10296 }
10297 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010298 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010299 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010300}
10301
Fred Drakebec628d1999-12-15 18:31:10 +000010302/* Return -1 on failure, 0 on success. */
10303static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010304setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010305{
10306#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010307 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010308 sizeof(posix_constants_pathconf)
10309 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010310 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010311 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010312#endif
10313#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010314 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010315 sizeof(posix_constants_confstr)
10316 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010317 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010318 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010319#endif
10320#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010321 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010322 sizeof(posix_constants_sysconf)
10323 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010324 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010325 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010326#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010327 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010328}
Fred Draked86ed291999-12-15 15:34:33 +000010329
10330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010331PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010332"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010333Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010334in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010335
10336static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010337posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010339 abort();
10340 /*NOTREACHED*/
10341 Py_FatalError("abort() called from Python code didn't abort!");
10342 return NULL;
10343}
Fred Drakebec628d1999-12-15 18:31:10 +000010344
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010345#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010346PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010347"startfile(filepath [, operation]) - Start a file with its associated\n\
10348application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010349\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010350When \"operation\" is not specified or \"open\", this acts like\n\
10351double-clicking the file in Explorer, or giving the file name as an\n\
10352argument to the DOS \"start\" command: the file is opened with whatever\n\
10353application (if any) its extension is associated.\n\
10354When another \"operation\" is given, it specifies what should be done with\n\
10355the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010356\n\
10357startfile returns as soon as the associated application is launched.\n\
10358There is no option to wait for the application to close, and no way\n\
10359to retrieve the application's exit status.\n\
10360\n\
10361The filepath is relative to the current directory. If you want to use\n\
10362an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010363the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010364
10365static PyObject *
10366win32_startfile(PyObject *self, PyObject *args)
10367{
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 PyObject *ofilepath;
10369 char *filepath;
10370 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010371 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010373
Victor Stinnereb5657a2011-09-30 01:44:27 +020010374 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 if (!PyArg_ParseTuple(args, "U|s:startfile",
10376 &unipath, &operation)) {
10377 PyErr_Clear();
10378 goto normal;
10379 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010380
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010382 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010384 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 PyErr_Clear();
10386 operation = NULL;
10387 goto normal;
10388 }
10389 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010390
Victor Stinnereb5657a2011-09-30 01:44:27 +020010391 wpath = PyUnicode_AsUnicode(unipath);
10392 if (wpath == NULL)
10393 goto normal;
10394 if (uoperation) {
10395 woperation = PyUnicode_AsUnicode(uoperation);
10396 if (woperation == NULL)
10397 goto normal;
10398 }
10399 else
10400 woperation = NULL;
10401
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010403 rc = ShellExecuteW((HWND)0, woperation, wpath,
10404 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 Py_END_ALLOW_THREADS
10406
Victor Stinnereb5657a2011-09-30 01:44:27 +020010407 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010409 win32_error_object("startfile", unipath);
10410 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 }
10412 Py_INCREF(Py_None);
10413 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010414
10415normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10417 PyUnicode_FSConverter, &ofilepath,
10418 &operation))
10419 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010420 if (win32_warn_bytes_api()) {
10421 Py_DECREF(ofilepath);
10422 return NULL;
10423 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 filepath = PyBytes_AsString(ofilepath);
10425 Py_BEGIN_ALLOW_THREADS
10426 rc = ShellExecute((HWND)0, operation, filepath,
10427 NULL, NULL, SW_SHOWNORMAL);
10428 Py_END_ALLOW_THREADS
10429 if (rc <= (HINSTANCE)32) {
10430 PyObject *errval = win32_error("startfile", filepath);
10431 Py_DECREF(ofilepath);
10432 return errval;
10433 }
10434 Py_DECREF(ofilepath);
10435 Py_INCREF(Py_None);
10436 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010437}
10438#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010439
Martin v. Löwis438b5342002-12-27 10:16:42 +000010440#ifdef HAVE_GETLOADAVG
10441PyDoc_STRVAR(posix_getloadavg__doc__,
10442"getloadavg() -> (float, float, float)\n\n\
10443Return the number of processes in the system run queue averaged over\n\
10444the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10445was unobtainable");
10446
10447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010448posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010449{
10450 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010451 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010452 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10453 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010454 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010455 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010456}
10457#endif
10458
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010459PyDoc_STRVAR(device_encoding__doc__,
10460"device_encoding(fd) -> str\n\n\
10461Return a string describing the encoding of the device\n\
10462if the output is a terminal; else return None.");
10463
10464static PyObject *
10465device_encoding(PyObject *self, PyObject *args)
10466{
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010468
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10470 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010471
10472 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010473}
10474
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010475#ifdef HAVE_SETRESUID
10476PyDoc_STRVAR(posix_setresuid__doc__,
10477"setresuid(ruid, euid, suid)\n\n\
10478Set the current process's real, effective, and saved user ids.");
10479
10480static PyObject*
10481posix_setresuid (PyObject *self, PyObject *args)
10482{
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010484 uid_t ruid, euid, suid;
10485 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10486 _Py_Uid_Converter, &ruid,
10487 _Py_Uid_Converter, &euid,
10488 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 return NULL;
10490 if (setresuid(ruid, euid, suid) < 0)
10491 return posix_error();
10492 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010493}
10494#endif
10495
10496#ifdef HAVE_SETRESGID
10497PyDoc_STRVAR(posix_setresgid__doc__,
10498"setresgid(rgid, egid, sgid)\n\n\
10499Set the current process's real, effective, and saved group ids.");
10500
10501static PyObject*
10502posix_setresgid (PyObject *self, PyObject *args)
10503{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010504 gid_t rgid, egid, sgid;
10505 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10506 _Py_Gid_Converter, &rgid,
10507 _Py_Gid_Converter, &egid,
10508 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 return NULL;
10510 if (setresgid(rgid, egid, sgid) < 0)
10511 return posix_error();
10512 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010513}
10514#endif
10515
10516#ifdef HAVE_GETRESUID
10517PyDoc_STRVAR(posix_getresuid__doc__,
10518"getresuid() -> (ruid, euid, suid)\n\n\
10519Get tuple of the current process's real, effective, and saved user ids.");
10520
10521static PyObject*
10522posix_getresuid (PyObject *self, PyObject *noargs)
10523{
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 if (getresuid(&ruid, &euid, &suid) < 0)
10526 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010527 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10528 _PyLong_FromUid(euid),
10529 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010530}
10531#endif
10532
10533#ifdef HAVE_GETRESGID
10534PyDoc_STRVAR(posix_getresgid__doc__,
10535"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010536Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010537
10538static PyObject*
10539posix_getresgid (PyObject *self, PyObject *noargs)
10540{
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 if (getresgid(&rgid, &egid, &sgid) < 0)
10543 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010544 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10545 _PyLong_FromGid(egid),
10546 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010547}
10548#endif
10549
Benjamin Peterson9428d532011-09-14 11:45:52 -040010550#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010551
Benjamin Peterson799bd802011-08-31 22:15:17 -040010552PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010553"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10554Return the value of extended attribute attribute on path.\n\
10555\n\
10556path may be either a string or an open file descriptor.\n\
10557If follow_symlinks is False, and the last element of the path is a symbolic\n\
10558 link, getxattr will examine the symbolic link itself instead of the file\n\
10559 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560
10561static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564 path_t path;
10565 path_t attribute;
10566 int follow_symlinks = 1;
10567 PyObject *buffer = NULL;
10568 int i;
10569 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010570
Larry Hastings9cf065c2012-06-22 16:30:09 -070010571 memset(&path, 0, sizeof(path));
10572 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010573 path.function_name = "getxattr";
10574 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010575 path.allow_fd = 1;
10576 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10577 path_converter, &path,
10578 path_converter, &attribute,
10579 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10583 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010584
Larry Hastings9cf065c2012-06-22 16:30:09 -070010585 for (i = 0; ; i++) {
10586 void *ptr;
10587 ssize_t result;
10588 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10589 Py_ssize_t buffer_size = buffer_sizes[i];
10590 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010591 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010592 goto exit;
10593 }
10594 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10595 if (!buffer)
10596 goto exit;
10597 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010598
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 Py_BEGIN_ALLOW_THREADS;
10600 if (path.fd >= 0)
10601 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10602 else if (follow_symlinks)
10603 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10604 else
10605 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10606 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010607
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 if (result < 0) {
10609 Py_DECREF(buffer);
10610 buffer = NULL;
10611 if (errno == ERANGE)
10612 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010613 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 goto exit;
10615 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010616
Larry Hastings9cf065c2012-06-22 16:30:09 -070010617 if (result != buffer_size) {
10618 /* Can only shrink. */
10619 _PyBytes_Resize(&buffer, result);
10620 }
10621 break;
10622 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010623
Larry Hastings9cf065c2012-06-22 16:30:09 -070010624exit:
10625 path_cleanup(&path);
10626 path_cleanup(&attribute);
10627 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010628}
10629
10630PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010631"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10632Set extended attribute attribute on path to value.\n\
10633path may be either a string or an open file descriptor.\n\
10634If follow_symlinks is False, and the last element of the path is a symbolic\n\
10635 link, setxattr will modify the symbolic link itself instead of the file\n\
10636 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010637
10638static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010639posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010640{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010641 path_t path;
10642 path_t attribute;
10643 Py_buffer value;
10644 int flags = 0;
10645 int follow_symlinks = 1;
10646 int result;
10647 PyObject *return_value = NULL;
10648 static char *keywords[] = {"path", "attribute", "value",
10649 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010652 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010653 path.allow_fd = 1;
10654 memset(&attribute, 0, sizeof(attribute));
10655 memset(&value, 0, sizeof(value));
10656 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10657 keywords,
10658 path_converter, &path,
10659 path_converter, &attribute,
10660 &value, &flags,
10661 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010662 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010663
10664 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10665 goto exit;
10666
Benjamin Peterson799bd802011-08-31 22:15:17 -040010667 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 if (path.fd > -1)
10669 result = fsetxattr(path.fd, attribute.narrow,
10670 value.buf, value.len, flags);
10671 else if (follow_symlinks)
10672 result = setxattr(path.narrow, attribute.narrow,
10673 value.buf, value.len, flags);
10674 else
10675 result = lsetxattr(path.narrow, attribute.narrow,
10676 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010680 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010681 goto exit;
10682 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010683
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 return_value = Py_None;
10685 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010686
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687exit:
10688 path_cleanup(&path);
10689 path_cleanup(&attribute);
10690 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691
Larry Hastings9cf065c2012-06-22 16:30:09 -070010692 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010693}
10694
10695PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10697Remove extended attribute attribute on path.\n\
10698path may be either a string or an open file descriptor.\n\
10699If follow_symlinks is False, and the last element of the path is a symbolic\n\
10700 link, removexattr will modify the symbolic link itself instead of the file\n\
10701 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010702
10703static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010704posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010705{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706 path_t path;
10707 path_t attribute;
10708 int follow_symlinks = 1;
10709 int result;
10710 PyObject *return_value = NULL;
10711 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010712
Larry Hastings9cf065c2012-06-22 16:30:09 -070010713 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010714 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010716 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 path.allow_fd = 1;
10718 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10719 keywords,
10720 path_converter, &path,
10721 path_converter, &attribute,
10722 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010723 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010724
10725 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10726 goto exit;
10727
Benjamin Peterson799bd802011-08-31 22:15:17 -040010728 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010729 if (path.fd > -1)
10730 result = fremovexattr(path.fd, attribute.narrow);
10731 else if (follow_symlinks)
10732 result = removexattr(path.narrow, attribute.narrow);
10733 else
10734 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010735 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010736
Larry Hastings9cf065c2012-06-22 16:30:09 -070010737 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010738 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010740 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010741
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 return_value = Py_None;
10743 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010744
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745exit:
10746 path_cleanup(&path);
10747 path_cleanup(&attribute);
10748
10749 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010750}
10751
10752PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753"listxattr(path='.', *, follow_symlinks=True)\n\n\
10754Return a list of extended attributes on path.\n\
10755\n\
10756path may be either None, a string, or an open file descriptor.\n\
10757if path is None, listxattr will examine the current directory.\n\
10758If follow_symlinks is False, and the last element of the path is a symbolic\n\
10759 link, listxattr will examine the symbolic link itself instead of the file\n\
10760 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761
10762static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010764{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 path_t path;
10766 int follow_symlinks = 1;
10767 Py_ssize_t i;
10768 PyObject *result = NULL;
10769 char *buffer = NULL;
10770 char *name;
10771 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010774 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 path.allow_fd = 1;
10776 path.fd = -1;
10777 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10778 path_converter, &path,
10779 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010780 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010781
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10783 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 name = path.narrow ? path.narrow : ".";
10786 for (i = 0; ; i++) {
10787 char *start, *trace, *end;
10788 ssize_t length;
10789 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10790 Py_ssize_t buffer_size = buffer_sizes[i];
10791 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010792 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010793 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010794 break;
10795 }
10796 buffer = PyMem_MALLOC(buffer_size);
10797 if (!buffer) {
10798 PyErr_NoMemory();
10799 break;
10800 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010801
Larry Hastings9cf065c2012-06-22 16:30:09 -070010802 Py_BEGIN_ALLOW_THREADS;
10803 if (path.fd > -1)
10804 length = flistxattr(path.fd, buffer, buffer_size);
10805 else if (follow_symlinks)
10806 length = listxattr(name, buffer, buffer_size);
10807 else
10808 length = llistxattr(name, buffer, buffer_size);
10809 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010812 if (errno == ERANGE) {
10813 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010814 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010816 }
Victor Stinner292c8352012-10-30 02:17:38 +010010817 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 break;
10819 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 result = PyList_New(0);
10822 if (!result) {
10823 goto exit;
10824 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010825
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 end = buffer + length;
10827 for (trace = start = buffer; trace != end; trace++) {
10828 if (!*trace) {
10829 int error;
10830 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10831 trace - start);
10832 if (!attribute) {
10833 Py_DECREF(result);
10834 result = NULL;
10835 goto exit;
10836 }
10837 error = PyList_Append(result, attribute);
10838 Py_DECREF(attribute);
10839 if (error) {
10840 Py_DECREF(result);
10841 result = NULL;
10842 goto exit;
10843 }
10844 start = trace + 1;
10845 }
10846 }
10847 break;
10848 }
10849exit:
10850 path_cleanup(&path);
10851 if (buffer)
10852 PyMem_FREE(buffer);
10853 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010854}
10855
Benjamin Peterson9428d532011-09-14 11:45:52 -040010856#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010857
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010858
Georg Brandl2fb477c2012-02-21 00:33:36 +010010859PyDoc_STRVAR(posix_urandom__doc__,
10860"urandom(n) -> str\n\n\
10861Return n random bytes suitable for cryptographic use.");
10862
10863static PyObject *
10864posix_urandom(PyObject *self, PyObject *args)
10865{
10866 Py_ssize_t size;
10867 PyObject *result;
10868 int ret;
10869
10870 /* Read arguments */
10871 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10872 return NULL;
10873 if (size < 0)
10874 return PyErr_Format(PyExc_ValueError,
10875 "negative argument not allowed");
10876 result = PyBytes_FromStringAndSize(NULL, size);
10877 if (result == NULL)
10878 return NULL;
10879
10880 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10881 PyBytes_GET_SIZE(result));
10882 if (ret == -1) {
10883 Py_DECREF(result);
10884 return NULL;
10885 }
10886 return result;
10887}
10888
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010889/* Terminal size querying */
10890
10891static PyTypeObject TerminalSizeType;
10892
10893PyDoc_STRVAR(TerminalSize_docstring,
10894 "A tuple of (columns, lines) for holding terminal window size");
10895
10896static PyStructSequence_Field TerminalSize_fields[] = {
10897 {"columns", "width of the terminal window in characters"},
10898 {"lines", "height of the terminal window in characters"},
10899 {NULL, NULL}
10900};
10901
10902static PyStructSequence_Desc TerminalSize_desc = {
10903 "os.terminal_size",
10904 TerminalSize_docstring,
10905 TerminalSize_fields,
10906 2,
10907};
10908
10909#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10910PyDoc_STRVAR(termsize__doc__,
10911 "Return the size of the terminal window as (columns, lines).\n" \
10912 "\n" \
10913 "The optional argument fd (default standard output) specifies\n" \
10914 "which file descriptor should be queried.\n" \
10915 "\n" \
10916 "If the file descriptor is not connected to a terminal, an OSError\n" \
10917 "is thrown.\n" \
10918 "\n" \
10919 "This function will only be defined if an implementation is\n" \
10920 "available for this system.\n" \
10921 "\n" \
10922 "shutil.get_terminal_size is the high-level function which should \n" \
10923 "normally be used, os.get_terminal_size is the low-level implementation.");
10924
10925static PyObject*
10926get_terminal_size(PyObject *self, PyObject *args)
10927{
10928 int columns, lines;
10929 PyObject *termsize;
10930
10931 int fd = fileno(stdout);
10932 /* Under some conditions stdout may not be connected and
10933 * fileno(stdout) may point to an invalid file descriptor. For example
10934 * GUI apps don't have valid standard streams by default.
10935 *
10936 * If this happens, and the optional fd argument is not present,
10937 * the ioctl below will fail returning EBADF. This is what we want.
10938 */
10939
10940 if (!PyArg_ParseTuple(args, "|i", &fd))
10941 return NULL;
10942
10943#ifdef TERMSIZE_USE_IOCTL
10944 {
10945 struct winsize w;
10946 if (ioctl(fd, TIOCGWINSZ, &w))
10947 return PyErr_SetFromErrno(PyExc_OSError);
10948 columns = w.ws_col;
10949 lines = w.ws_row;
10950 }
10951#endif /* TERMSIZE_USE_IOCTL */
10952
10953#ifdef TERMSIZE_USE_CONIO
10954 {
10955 DWORD nhandle;
10956 HANDLE handle;
10957 CONSOLE_SCREEN_BUFFER_INFO csbi;
10958 switch (fd) {
10959 case 0: nhandle = STD_INPUT_HANDLE;
10960 break;
10961 case 1: nhandle = STD_OUTPUT_HANDLE;
10962 break;
10963 case 2: nhandle = STD_ERROR_HANDLE;
10964 break;
10965 default:
10966 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10967 }
10968 handle = GetStdHandle(nhandle);
10969 if (handle == NULL)
10970 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10971 if (handle == INVALID_HANDLE_VALUE)
10972 return PyErr_SetFromWindowsErr(0);
10973
10974 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10975 return PyErr_SetFromWindowsErr(0);
10976
10977 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10978 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10979 }
10980#endif /* TERMSIZE_USE_CONIO */
10981
10982 termsize = PyStructSequence_New(&TerminalSizeType);
10983 if (termsize == NULL)
10984 return NULL;
10985 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10986 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10987 if (PyErr_Occurred()) {
10988 Py_DECREF(termsize);
10989 return NULL;
10990 }
10991 return termsize;
10992}
10993#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10994
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010995PyDoc_STRVAR(posix_cpu_count__doc__,
10996"cpu_count() -> integer\n\n\
10997Return the number of CPUs in the system, or None if this value cannot be\n\
10998established.");
10999
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011000static PyObject *
11001posix_cpu_count(PyObject *self)
11002{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011003 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011004#ifdef MS_WINDOWS
11005 SYSTEM_INFO sysinfo;
11006 GetSystemInfo(&sysinfo);
11007 ncpu = sysinfo.dwNumberOfProcessors;
11008#elif defined(__hpux)
11009 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11010#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11011 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011012#elif defined(__DragonFly__) || \
11013 defined(__OpenBSD__) || \
11014 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011015 defined(__NetBSD__) || \
11016 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011017 int mib[2];
11018 size_t len = sizeof(ncpu);
11019 mib[0] = CTL_HW;
11020 mib[1] = HW_NCPU;
11021 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11022 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011023#endif
11024 if (ncpu >= 1)
11025 return PyLong_FromLong(ncpu);
11026 else
11027 Py_RETURN_NONE;
11028}
11029
Victor Stinnerdaf45552013-08-28 00:53:59 +020011030PyDoc_STRVAR(get_inheritable__doc__,
11031 "get_inheritable(fd) -> bool\n" \
11032 "\n" \
11033 "Get the close-on-exe flag of the specified file descriptor.");
11034
11035static PyObject*
11036posix_get_inheritable(PyObject *self, PyObject *args)
11037{
11038 int fd;
11039 int inheritable;
11040
11041 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11042 return NULL;
11043
11044 if (!_PyVerify_fd(fd))
11045 return posix_error();
11046
11047 inheritable = _Py_get_inheritable(fd);
11048 if (inheritable < 0)
11049 return NULL;
11050 return PyBool_FromLong(inheritable);
11051}
11052
11053PyDoc_STRVAR(set_inheritable__doc__,
11054 "set_inheritable(fd, inheritable)\n" \
11055 "\n" \
11056 "Set the inheritable flag of the specified file descriptor.");
11057
11058static PyObject*
11059posix_set_inheritable(PyObject *self, PyObject *args)
11060{
11061 int fd, inheritable;
11062
11063 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11064 return NULL;
11065
11066 if (!_PyVerify_fd(fd))
11067 return posix_error();
11068
11069 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11070 return NULL;
11071 Py_RETURN_NONE;
11072}
11073
11074
11075#ifdef MS_WINDOWS
11076PyDoc_STRVAR(get_handle_inheritable__doc__,
11077 "get_handle_inheritable(fd) -> bool\n" \
11078 "\n" \
11079 "Get the close-on-exe flag of the specified file descriptor.");
11080
11081static PyObject*
11082posix_get_handle_inheritable(PyObject *self, PyObject *args)
11083{
11084 Py_intptr_t handle;
11085 DWORD flags;
11086
11087 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11088 return NULL;
11089
11090 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11091 PyErr_SetFromWindowsErr(0);
11092 return NULL;
11093 }
11094
11095 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11096}
11097
11098PyDoc_STRVAR(set_handle_inheritable__doc__,
11099 "set_handle_inheritable(fd, inheritable)\n" \
11100 "\n" \
11101 "Set the inheritable flag of the specified handle.");
11102
11103static PyObject*
11104posix_set_handle_inheritable(PyObject *self, PyObject *args)
11105{
11106 int inheritable = 1;
11107 Py_intptr_t handle;
11108 DWORD flags;
11109
11110 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11111 &handle, &inheritable))
11112 return NULL;
11113
11114 if (inheritable)
11115 flags = HANDLE_FLAG_INHERIT;
11116 else
11117 flags = 0;
11118 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11119 PyErr_SetFromWindowsErr(0);
11120 return NULL;
11121 }
11122 Py_RETURN_NONE;
11123}
11124#endif /* MS_WINDOWS */
11125
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011126
Larry Hastings31826802013-10-19 00:09:25 -070011127
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011128static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011129
11130 OS_STAT_METHODDEF
11131 OS_ACCESS_METHODDEF
11132 OS_TTYNAME_METHODDEF
11133
Larry Hastings9cf065c2012-06-22 16:30:09 -070011134 {"chdir", (PyCFunction)posix_chdir,
11135 METH_VARARGS | METH_KEYWORDS,
11136 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011137#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 {"chflags", (PyCFunction)posix_chflags,
11139 METH_VARARGS | METH_KEYWORDS,
11140 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011141#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011142 {"chmod", (PyCFunction)posix_chmod,
11143 METH_VARARGS | METH_KEYWORDS,
11144 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011145#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011147#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011148#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011149 {"chown", (PyCFunction)posix_chown,
11150 METH_VARARGS | METH_KEYWORDS,
11151 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011152#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011153#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011155#endif /* HAVE_LCHMOD */
11156#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011158#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011159#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011161#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011162#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011164#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011165#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011167#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011168#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011170#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11172 METH_NOARGS, posix_getcwd__doc__},
11173 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11174 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011175#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11176 {"link", (PyCFunction)posix_link,
11177 METH_VARARGS | METH_KEYWORDS,
11178 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011179#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 {"listdir", (PyCFunction)posix_listdir,
11181 METH_VARARGS | METH_KEYWORDS,
11182 posix_listdir__doc__},
11183 {"lstat", (PyCFunction)posix_lstat,
11184 METH_VARARGS | METH_KEYWORDS,
11185 posix_lstat__doc__},
11186 {"mkdir", (PyCFunction)posix_mkdir,
11187 METH_VARARGS | METH_KEYWORDS,
11188 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011189#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011191#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011192#ifdef HAVE_GETPRIORITY
11193 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11194#endif /* HAVE_GETPRIORITY */
11195#ifdef HAVE_SETPRIORITY
11196 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11197#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011198#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011199 {"readlink", (PyCFunction)posix_readlink,
11200 METH_VARARGS | METH_KEYWORDS,
11201 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011202#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011203#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011204 {"readlink", (PyCFunction)win_readlink,
11205 METH_VARARGS | METH_KEYWORDS,
11206 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011207#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011208 {"rename", (PyCFunction)posix_rename,
11209 METH_VARARGS | METH_KEYWORDS,
11210 posix_rename__doc__},
11211 {"replace", (PyCFunction)posix_replace,
11212 METH_VARARGS | METH_KEYWORDS,
11213 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011214 {"rmdir", (PyCFunction)posix_rmdir,
11215 METH_VARARGS | METH_KEYWORDS,
11216 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011218#if defined(HAVE_SYMLINK)
11219 {"symlink", (PyCFunction)posix_symlink,
11220 METH_VARARGS | METH_KEYWORDS,
11221 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011222#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011223#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011225#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011227#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011229#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011230 {"unlink", (PyCFunction)posix_unlink,
11231 METH_VARARGS | METH_KEYWORDS,
11232 posix_unlink__doc__},
11233 {"remove", (PyCFunction)posix_unlink,
11234 METH_VARARGS | METH_KEYWORDS,
11235 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011236 {"utime", (PyCFunction)posix_utime,
11237 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011238#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011240#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011242#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011244 {"execve", (PyCFunction)posix_execve,
11245 METH_VARARGS | METH_KEYWORDS,
11246 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011247#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011248#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11250 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011251#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011252#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011254#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011255#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011257#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011258#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011259#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011260 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11261 {"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 +020011262#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011263#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011264 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011265#endif
11266#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011267 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011268#endif
11269#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011270 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011271#endif
11272#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011273 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011274#endif
11275#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011276 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011277#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011278 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011279#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011280 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11281 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11282#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011283#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011284#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011286#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011287#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011289#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011290#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011292#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011293#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011295#endif /* HAVE_GETEUID */
11296#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011298#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011299#ifdef HAVE_GETGROUPLIST
11300 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11301#endif
Fred Drakec9680921999-12-13 16:37:25 +000011302#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011304#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011306#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011308#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011309#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011311#endif /* HAVE_GETPPID */
11312#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011314#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011315#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011317#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011318#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011320#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011321#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011323#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011324#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011326#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011327#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11329 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011330#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011331#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011333#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011334#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011336#endif /* HAVE_SETEUID */
11337#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011339#endif /* HAVE_SETEGID */
11340#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011342#endif /* HAVE_SETREUID */
11343#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011345#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011346#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011348#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011349#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011351#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011352#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011354#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011355#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011357#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011358#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011360#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011361#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011363#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011364#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011365 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011366#endif /* HAVE_WAIT3 */
11367#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011368 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011369#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011370#if defined(HAVE_WAITID) && !defined(__APPLE__)
11371 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11372#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011373#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011375#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011376#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011378#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011379#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011381#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011382#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011384#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011385#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011387#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011388#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011390#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011391 {"open", (PyCFunction)posix_open,\
11392 METH_VARARGS | METH_KEYWORDS,
11393 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11395 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11396 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11397 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011398 {"dup2", (PyCFunction)posix_dup2,
11399 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011400#ifdef HAVE_LOCKF
11401 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11402#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11404 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011405#ifdef HAVE_READV
11406 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11407#endif
11408#ifdef HAVE_PREAD
11409 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11410#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011412#ifdef HAVE_WRITEV
11413 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11414#endif
11415#ifdef HAVE_PWRITE
11416 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11417#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011418#ifdef HAVE_SENDFILE
11419 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11420 posix_sendfile__doc__},
11421#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011422 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011424#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011426#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011427#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011428 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011429#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011430#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011431 {"mkfifo", (PyCFunction)posix_mkfifo,
11432 METH_VARARGS | METH_KEYWORDS,
11433 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011434#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011435#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011436 {"mknod", (PyCFunction)posix_mknod,
11437 METH_VARARGS | METH_KEYWORDS,
11438 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011439#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011440#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11442 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11443 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011444#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011445#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011447#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011448#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011449 {"truncate", (PyCFunction)posix_truncate,
11450 METH_VARARGS | METH_KEYWORDS,
11451 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011452#endif
11453#ifdef HAVE_POSIX_FALLOCATE
11454 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11455#endif
11456#ifdef HAVE_POSIX_FADVISE
11457 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11458#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011459#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011461#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011462#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011464#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011466#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011468#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011469#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011471#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011472#ifdef HAVE_SYNC
11473 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11474#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011475#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011477#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011478#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011479#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011481#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011482#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011484#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011485#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011487#endif /* WIFSTOPPED */
11488#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011490#endif /* WIFSIGNALED */
11491#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011493#endif /* WIFEXITED */
11494#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011496#endif /* WEXITSTATUS */
11497#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011499#endif /* WTERMSIG */
11500#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011502#endif /* WSTOPSIG */
11503#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011504#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011506#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011507#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011508 {"statvfs", (PyCFunction)posix_statvfs,
11509 METH_VARARGS | METH_KEYWORDS,
11510 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011511#endif
Fred Drakec9680921999-12-13 16:37:25 +000011512#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011514#endif
11515#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011517#endif
11518#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011520#endif
11521#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011522 {"pathconf", (PyCFunction)posix_pathconf,
11523 METH_VARARGS | METH_KEYWORDS,
11524 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011525#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011527#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011529 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011530 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011531 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011532 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011533#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011534#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011536#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011537 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011538#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011540#endif
11541#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011543#endif
11544#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011546#endif
11547#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011549#endif
11550
Benjamin Peterson9428d532011-09-14 11:45:52 -040011551#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011552 {"setxattr", (PyCFunction)posix_setxattr,
11553 METH_VARARGS | METH_KEYWORDS,
11554 posix_setxattr__doc__},
11555 {"getxattr", (PyCFunction)posix_getxattr,
11556 METH_VARARGS | METH_KEYWORDS,
11557 posix_getxattr__doc__},
11558 {"removexattr", (PyCFunction)posix_removexattr,
11559 METH_VARARGS | METH_KEYWORDS,
11560 posix_removexattr__doc__},
11561 {"listxattr", (PyCFunction)posix_listxattr,
11562 METH_VARARGS | METH_KEYWORDS,
11563 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011564#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011565#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11566 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11567#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011568 {"cpu_count", (PyCFunction)posix_cpu_count,
11569 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011570 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11571 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11572#ifdef MS_WINDOWS
11573 {"get_handle_inheritable", posix_get_handle_inheritable,
11574 METH_VARARGS, get_handle_inheritable__doc__},
11575 {"set_handle_inheritable", posix_set_handle_inheritable,
11576 METH_VARARGS, set_handle_inheritable__doc__},
11577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011579};
11580
11581
Brian Curtin52173d42010-12-02 18:29:18 +000011582#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011583static int
Brian Curtin52173d42010-12-02 18:29:18 +000011584enable_symlink()
11585{
11586 HANDLE tok;
11587 TOKEN_PRIVILEGES tok_priv;
11588 LUID luid;
11589 int meth_idx = 0;
11590
11591 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011592 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011593
11594 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011595 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011596
11597 tok_priv.PrivilegeCount = 1;
11598 tok_priv.Privileges[0].Luid = luid;
11599 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11600
11601 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11602 sizeof(TOKEN_PRIVILEGES),
11603 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011604 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011605
Brian Curtin3b4499c2010-12-28 14:31:47 +000011606 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11607 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011608}
11609#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11610
Barry Warsaw4a342091996-12-19 23:50:02 +000011611static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011612all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011613{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011614#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011615 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011616#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011617#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011618 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011620#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011621 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011623#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011624 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011625#endif
Fred Drakec9680921999-12-13 16:37:25 +000011626#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011627 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011628#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011629#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011630 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011631#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011632#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011633 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011634#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011635#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011636 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011637#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011638#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011639 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011640#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011641#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011642 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011643#endif
11644#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011645 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011646#endif
11647#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011648 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011649#endif
11650#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011651 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011652#endif
11653#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011654 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011655#endif
11656#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011657 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011658#endif
11659#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011660 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011661#endif
11662#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011663 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011664#endif
11665#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011666 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011667#endif
11668#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011669 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011670#endif
11671#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011672 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011673#endif
11674#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011675 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011676#endif
11677#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011678 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011679#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011680#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011681 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011682#endif
11683#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011684 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011685#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011686#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011687 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011688#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011689#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011690 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011691#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011692#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011693 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011694#endif
11695#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011696 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011697#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011698#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011699 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011700#endif
11701#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011702 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011703#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011704#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011705 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011706#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011707#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011708 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011709#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011710#ifdef O_TMPFILE
11711 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11712#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011713#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011714 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011715#endif
11716#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011717 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011718#endif
11719#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011720 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011721#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011722#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011723 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011724#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011725#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011726 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011727#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011728
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011729
Jesus Cea94363612012-06-22 18:32:07 +020011730#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011731 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011732#endif
11733#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011734 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011735#endif
11736
Tim Peters5aa91602002-01-30 05:46:57 +000011737/* MS Windows */
11738#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011739 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011740 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011741#endif
11742#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 /* Optimize for short life (keep in memory). */
11744 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011745 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011746#endif
11747#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011748 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011749 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011750#endif
11751#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011752 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011753 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011754#endif
11755#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011756 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011758#endif
11759
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011760/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011761#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011762 /* Send a SIGIO signal whenever input or output
11763 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011764 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011765#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011766#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011767 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011768 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011769#endif
11770#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011771 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011772 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011773#endif
11774#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011775 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011776 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011777#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011778#ifdef O_NOLINKS
11779 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011780 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011781#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011782#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011783 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011784 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011785#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011786
Victor Stinner8c62be82010-05-06 00:08:46 +000011787 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011788#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011789 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011790#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011791#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011792 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011793#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011794#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011795 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011796#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011797#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011798 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011799#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011800#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011801 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011802#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011803#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011804 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011805#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011806#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011807 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011808#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011809#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011810 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011811#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011812#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011813 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011814#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011815#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011816 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011817#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011818#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011819 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011820#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011821#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011822 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011823#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011824#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011825 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011826#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011827#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011828 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011829#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011830#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011831 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011832#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011833#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011834 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011835#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011836#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011837 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011838#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011839
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011840 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011841#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011842 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011843#endif /* ST_RDONLY */
11844#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011845 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011846#endif /* ST_NOSUID */
11847
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011848 /* FreeBSD sendfile() constants */
11849#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011850 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011851#endif
11852#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011853 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011854#endif
11855#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011856 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011857#endif
11858
Ross Lagerwall7807c352011-03-17 20:20:30 +020011859 /* constants for posix_fadvise */
11860#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011861 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011862#endif
11863#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011864 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011865#endif
11866#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011867 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011868#endif
11869#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011870 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011871#endif
11872#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011873 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011874#endif
11875#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011876 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011877#endif
11878
11879 /* constants for waitid */
11880#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011881 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11882 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11883 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011884#endif
11885#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011886 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011887#endif
11888#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011889 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011890#endif
11891#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011892 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011893#endif
11894#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011895 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011896#endif
11897#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011898 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011899#endif
11900#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011901 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011902#endif
11903#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011904 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011905#endif
11906
11907 /* constants for lockf */
11908#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011909 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011910#endif
11911#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011912 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011913#endif
11914#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011915 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011916#endif
11917#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011918 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011919#endif
11920
Guido van Rossum246bc171999-02-01 23:54:31 +000011921#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11923 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11924 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11925 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11926 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011927#endif
11928
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011929#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011930 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11931 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11932 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011933#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011934 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011935#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011936#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011937 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011938#endif
11939#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011940 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011941#endif
11942#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011943 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011944#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011945#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011946 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011947#endif
11948#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011949 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011950#endif
11951#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011952 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011953#endif
11954#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011955 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011956#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011957#endif
11958
Benjamin Peterson9428d532011-09-14 11:45:52 -040011959#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011960 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11961 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11962 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011963#endif
11964
Victor Stinner8b905bd2011-10-25 13:34:04 +020011965#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011966 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011967#endif
11968#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011969 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011970#endif
11971#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011972 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011973#endif
11974#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011975 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011976#endif
11977#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011979#endif
11980#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011982#endif
11983#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011985#endif
11986
Victor Stinner8c62be82010-05-06 00:08:46 +000011987 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011988}
11989
11990
Tim Peters5aa91602002-01-30 05:46:57 +000011991#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011992#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011993#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011994
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011995#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011996#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011997#define MODNAME "posix"
11998#endif
11999
Martin v. Löwis1a214512008-06-11 05:26:20 +000012000static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012001 PyModuleDef_HEAD_INIT,
12002 MODNAME,
12003 posix__doc__,
12004 -1,
12005 posix_methods,
12006 NULL,
12007 NULL,
12008 NULL,
12009 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012010};
12011
12012
Larry Hastings9cf065c2012-06-22 16:30:09 -070012013static char *have_functions[] = {
12014
12015#ifdef HAVE_FACCESSAT
12016 "HAVE_FACCESSAT",
12017#endif
12018
12019#ifdef HAVE_FCHDIR
12020 "HAVE_FCHDIR",
12021#endif
12022
12023#ifdef HAVE_FCHMOD
12024 "HAVE_FCHMOD",
12025#endif
12026
12027#ifdef HAVE_FCHMODAT
12028 "HAVE_FCHMODAT",
12029#endif
12030
12031#ifdef HAVE_FCHOWN
12032 "HAVE_FCHOWN",
12033#endif
12034
Larry Hastings00964ed2013-08-12 13:49:30 -040012035#ifdef HAVE_FCHOWNAT
12036 "HAVE_FCHOWNAT",
12037#endif
12038
Larry Hastings9cf065c2012-06-22 16:30:09 -070012039#ifdef HAVE_FEXECVE
12040 "HAVE_FEXECVE",
12041#endif
12042
12043#ifdef HAVE_FDOPENDIR
12044 "HAVE_FDOPENDIR",
12045#endif
12046
Georg Brandl306336b2012-06-24 12:55:33 +020012047#ifdef HAVE_FPATHCONF
12048 "HAVE_FPATHCONF",
12049#endif
12050
Larry Hastings9cf065c2012-06-22 16:30:09 -070012051#ifdef HAVE_FSTATAT
12052 "HAVE_FSTATAT",
12053#endif
12054
12055#ifdef HAVE_FSTATVFS
12056 "HAVE_FSTATVFS",
12057#endif
12058
Georg Brandl306336b2012-06-24 12:55:33 +020012059#ifdef HAVE_FTRUNCATE
12060 "HAVE_FTRUNCATE",
12061#endif
12062
Larry Hastings9cf065c2012-06-22 16:30:09 -070012063#ifdef HAVE_FUTIMENS
12064 "HAVE_FUTIMENS",
12065#endif
12066
12067#ifdef HAVE_FUTIMES
12068 "HAVE_FUTIMES",
12069#endif
12070
12071#ifdef HAVE_FUTIMESAT
12072 "HAVE_FUTIMESAT",
12073#endif
12074
12075#ifdef HAVE_LINKAT
12076 "HAVE_LINKAT",
12077#endif
12078
12079#ifdef HAVE_LCHFLAGS
12080 "HAVE_LCHFLAGS",
12081#endif
12082
12083#ifdef HAVE_LCHMOD
12084 "HAVE_LCHMOD",
12085#endif
12086
12087#ifdef HAVE_LCHOWN
12088 "HAVE_LCHOWN",
12089#endif
12090
12091#ifdef HAVE_LSTAT
12092 "HAVE_LSTAT",
12093#endif
12094
12095#ifdef HAVE_LUTIMES
12096 "HAVE_LUTIMES",
12097#endif
12098
12099#ifdef HAVE_MKDIRAT
12100 "HAVE_MKDIRAT",
12101#endif
12102
12103#ifdef HAVE_MKFIFOAT
12104 "HAVE_MKFIFOAT",
12105#endif
12106
12107#ifdef HAVE_MKNODAT
12108 "HAVE_MKNODAT",
12109#endif
12110
12111#ifdef HAVE_OPENAT
12112 "HAVE_OPENAT",
12113#endif
12114
12115#ifdef HAVE_READLINKAT
12116 "HAVE_READLINKAT",
12117#endif
12118
12119#ifdef HAVE_RENAMEAT
12120 "HAVE_RENAMEAT",
12121#endif
12122
12123#ifdef HAVE_SYMLINKAT
12124 "HAVE_SYMLINKAT",
12125#endif
12126
12127#ifdef HAVE_UNLINKAT
12128 "HAVE_UNLINKAT",
12129#endif
12130
12131#ifdef HAVE_UTIMENSAT
12132 "HAVE_UTIMENSAT",
12133#endif
12134
12135#ifdef MS_WINDOWS
12136 "MS_WINDOWS",
12137#endif
12138
12139 NULL
12140};
12141
12142
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012143PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012144INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012145{
Victor Stinner8c62be82010-05-06 00:08:46 +000012146 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012147 PyObject *list;
12148 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012149
Brian Curtin52173d42010-12-02 18:29:18 +000012150#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012151 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012152#endif
12153
Victor Stinner8c62be82010-05-06 00:08:46 +000012154 m = PyModule_Create(&posixmodule);
12155 if (m == NULL)
12156 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012157
Victor Stinner8c62be82010-05-06 00:08:46 +000012158 /* Initialize environ dictionary */
12159 v = convertenviron();
12160 Py_XINCREF(v);
12161 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12162 return NULL;
12163 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012164
Victor Stinner8c62be82010-05-06 00:08:46 +000012165 if (all_ins(m))
12166 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012167
Victor Stinner8c62be82010-05-06 00:08:46 +000012168 if (setup_confname_tables(m))
12169 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012170
Victor Stinner8c62be82010-05-06 00:08:46 +000012171 Py_INCREF(PyExc_OSError);
12172 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012173
Guido van Rossumb3d39562000-01-31 18:41:26 +000012174#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012175 if (posix_putenv_garbage == NULL)
12176 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012177#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012178
Victor Stinner8c62be82010-05-06 00:08:46 +000012179 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012180#if defined(HAVE_WAITID) && !defined(__APPLE__)
12181 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012182 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12183 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012184#endif
12185
Christian Heimes25827622013-10-12 01:27:08 +020012186 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012187 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12188 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12189 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012190 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12191 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012192 structseq_new = StatResultType.tp_new;
12193 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012194
Christian Heimes25827622013-10-12 01:27:08 +020012195 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012196 if (PyStructSequence_InitType2(&StatVFSResultType,
12197 &statvfs_result_desc) < 0)
12198 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012199#ifdef NEED_TICKS_PER_SECOND
12200# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012201 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012202# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012203 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012204# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012205 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012206# endif
12207#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012208
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012209#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012210 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012211 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12212 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012213 SchedParamType.tp_new = sched_param_new;
12214#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012215
12216 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012217 if (PyStructSequence_InitType2(&TerminalSizeType,
12218 &TerminalSize_desc) < 0)
12219 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012220 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012221#if defined(HAVE_WAITID) && !defined(__APPLE__)
12222 Py_INCREF((PyObject*) &WaitidResultType);
12223 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12224#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012225 Py_INCREF((PyObject*) &StatResultType);
12226 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12227 Py_INCREF((PyObject*) &StatVFSResultType);
12228 PyModule_AddObject(m, "statvfs_result",
12229 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012230
12231#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012232 Py_INCREF(&SchedParamType);
12233 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012234#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012235
Larry Hastings605a62d2012-06-24 04:33:36 -070012236 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012237 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12238 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012239 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12240
12241 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012242 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12243 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012244 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12245
Thomas Wouters477c8d52006-05-27 19:21:47 +000012246#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012247 /*
12248 * Step 2 of weak-linking support on Mac OS X.
12249 *
12250 * The code below removes functions that are not available on the
12251 * currently active platform.
12252 *
12253 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012254 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012255 * OSX 10.4.
12256 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012257#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012258 if (fstatvfs == NULL) {
12259 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12260 return NULL;
12261 }
12262 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012263#endif /* HAVE_FSTATVFS */
12264
12265#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012266 if (statvfs == NULL) {
12267 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12268 return NULL;
12269 }
12270 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012271#endif /* HAVE_STATVFS */
12272
12273# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012274 if (lchown == NULL) {
12275 if (PyObject_DelAttrString(m, "lchown") == -1) {
12276 return NULL;
12277 }
12278 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012279#endif /* HAVE_LCHOWN */
12280
12281
12282#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012283
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012284 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012285 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12286
Larry Hastings6fe20b32012-04-19 15:07:49 -070012287 billion = PyLong_FromLong(1000000000);
12288 if (!billion)
12289 return NULL;
12290
Larry Hastings9cf065c2012-06-22 16:30:09 -070012291 /* suppress "function not used" warnings */
12292 {
12293 int ignored;
12294 fd_specified("", -1);
12295 follow_symlinks_specified("", 1);
12296 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12297 dir_fd_converter(Py_None, &ignored);
12298 dir_fd_unavailable(Py_None, &ignored);
12299 }
12300
12301 /*
12302 * provide list of locally available functions
12303 * so os.py can populate support_* lists
12304 */
12305 list = PyList_New(0);
12306 if (!list)
12307 return NULL;
12308 for (trace = have_functions; *trace; trace++) {
12309 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12310 if (!unicode)
12311 return NULL;
12312 if (PyList_Append(list, unicode))
12313 return NULL;
12314 Py_DECREF(unicode);
12315 }
12316 PyModule_AddObject(m, "_have_functions", list);
12317
12318 initialized = 1;
12319
Victor Stinner8c62be82010-05-06 00:08:46 +000012320 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012321}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012322
12323#ifdef __cplusplus
12324}
12325#endif