blob: ab3e9f0b033fc65a34c5b7888bc66cc0345b6a66 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000011#ifdef __APPLE__
12 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000013 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000014 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
15 * at the end of this file for more information.
16 */
17# pragma weak lchown
18# pragma weak statvfs
19# pragma weak fstatvfs
20
21#endif /* __APPLE__ */
22
Thomas Wouters68bc4f92006-03-01 01:05:10 +000023#define PY_SSIZE_T_CLEAN
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020026#ifndef MS_WINDOWS
27#include "posixmodule.h"
28#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
Benjamin Peterson9428d532011-09-14 11:45:52 -040098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
99#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200116#ifdef __hpux
117#include <sys/mpctl.h>
118#endif
119
120#if defined(__DragonFly__) || \
121 defined(__OpenBSD__) || \
122 defined(__FreeBSD__) || \
123 defined(__NetBSD__) || \
124 defined(__APPLE__)
125#include <sys/sysctl.h>
126#endif
127
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100128#if defined(MS_WINDOWS)
129# define TERMSIZE_USE_CONIO
130#elif defined(HAVE_SYS_IOCTL_H)
131# include <sys/ioctl.h>
132# if defined(HAVE_TERMIOS_H)
133# include <termios.h>
134# endif
135# if defined(TIOCGWINSZ)
136# define TERMSIZE_USE_IOCTL
137# endif
138#endif /* MS_WINDOWS */
139
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000141/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000145#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#include <process.h>
147#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_EXECV 1
150#define HAVE_GETCWD 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 */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000157#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000158#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000159#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000160#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#define HAVE_EXECV 1
162#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000163#define HAVE_SYSTEM 1
164#define HAVE_CWAIT 1
165#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000166#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000167#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200168#if defined(__VMS)
169/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171/* Unix functions that the configure script doesn't check for */
172#define HAVE_EXECV 1
173#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000175#define HAVE_FORK1 1
176#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_GETCWD 1
178#define HAVE_GETEGID 1
179#define HAVE_GETEUID 1
180#define HAVE_GETGID 1
181#define HAVE_GETPPID 1
182#define HAVE_GETUID 1
183#define HAVE_KILL 1
184#define HAVE_OPENDIR 1
185#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000186#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200189#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#endif /* _MSC_VER */
191#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000192#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000193
Victor Stinnera2f7c002012-02-08 03:36:25 +0100194
195
196
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000197#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000198
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000199#if defined(__sgi)&&_COMPILER_VERSION>=700
200/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
201 (default) */
202extern char *ctermid_r(char *);
203#endif
204
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000205#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000209#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#endif
215#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int chdir(char *);
217extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chdir(const char *);
220extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000222#ifdef __BORLANDC__
223extern int chmod(const char *, int);
224#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000226#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000227/*#ifdef HAVE_FCHMOD
228extern int fchmod(int, mode_t);
229#endif*/
230/*#ifdef HAVE_LCHMOD
231extern int lchmod(const char *, mode_t);
232#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int chown(const char *, uid_t, gid_t);
234extern char *getcwd(char *, int);
235extern char *strerror(int);
236extern int link(const char *, const char *);
237extern int rename(const char *, const char *);
238extern int stat(const char *, struct stat *);
239extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000241extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000242#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000244extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000247
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000248#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#ifdef HAVE_UTIME_H
251#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000252#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000254#ifdef HAVE_SYS_UTIME_H
255#include <sys/utime.h>
256#define HAVE_UTIME_H /* pretend we do for the rest of this file */
257#endif /* HAVE_SYS_UTIME_H */
258
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#ifdef HAVE_SYS_TIMES_H
260#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
263#ifdef HAVE_SYS_PARAM_H
264#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
267#ifdef HAVE_SYS_UTSNAME_H
268#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000269#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#define NAMLEN(dirent) strlen((dirent)->d_name)
274#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000275#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#include <direct.h>
277#define NAMLEN(dirent) strlen((dirent)->d_name)
278#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000284#endif
285#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#endif
288#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000290#endif
291#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296#endif
297#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000299#endif
300#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000302#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000304#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000305#endif
306#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000307#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000308#endif
309#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000310#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000311#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000313#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000315#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000316#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000317#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
318#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000319static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000320#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000321#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000322
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#if defined(PATH_MAX) && PATH_MAX > 1024
325#define MAXPATHLEN PATH_MAX
326#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#endif /* MAXPATHLEN */
330
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000331#ifdef UNION_WAIT
332/* Emulate some macros on systems that have a union instead of macros */
333
334#ifndef WIFEXITED
335#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
336#endif
337
338#ifndef WEXITSTATUS
339#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340#endif
341
342#ifndef WTERMSIG
343#define WTERMSIG(u_wait) ((u_wait).w_termsig)
344#endif
345
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000346#define WAIT_TYPE union wait
347#define WAIT_STATUS_INT(s) (s.w_status)
348
349#else /* !UNION_WAIT */
350#define WAIT_TYPE int
351#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000352#endif /* UNION_WAIT */
353
Greg Wardb48bc172000-03-01 21:51:56 +0000354/* Don't use the "_r" form if we don't need it (also, won't have a
355 prototype for it, at least on Solaris -- maybe others as well?). */
356#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
357#define USE_CTERMID_R
358#endif
359
Fred Drake699f3522000-06-29 21:12:41 +0000360/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000361#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000362#undef FSTAT
363#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200364#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700366# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define FSTAT win32_fstat
368# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000369#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000370# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700371# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define FSTAT fstat
373# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000374#endif
375
Tim Peters11b23062003-04-23 02:39:17 +0000376#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#include <sys/mkdev.h>
378#else
379#if defined(MAJOR_IN_SYSMACROS)
380#include <sys/sysmacros.h>
381#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000382#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
383#include <sys/mkdev.h>
384#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000385#endif
Fred Drake699f3522000-06-29 21:12:41 +0000386
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387
388#ifdef MS_WINDOWS
389static int
390win32_warn_bytes_api()
391{
392 return PyErr_WarnEx(PyExc_DeprecationWarning,
393 "The Windows bytes API has been deprecated, "
394 "use Unicode filenames instead",
395 1);
396}
397#endif
398
399
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200400#ifndef MS_WINDOWS
401PyObject *
402_PyLong_FromUid(uid_t uid)
403{
404 if (uid == (uid_t)-1)
405 return PyLong_FromLong(-1);
406 return PyLong_FromUnsignedLong(uid);
407}
408
409PyObject *
410_PyLong_FromGid(gid_t gid)
411{
412 if (gid == (gid_t)-1)
413 return PyLong_FromLong(-1);
414 return PyLong_FromUnsignedLong(gid);
415}
416
417int
418_Py_Uid_Converter(PyObject *obj, void *p)
419{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700420 uid_t uid;
421 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200422 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200423 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700424 unsigned long uresult;
425
426 index = PyNumber_Index(obj);
427 if (index == NULL) {
428 PyErr_Format(PyExc_TypeError,
429 "uid should be integer, not %.200s",
430 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200431 return 0;
432 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700433
434 /*
435 * Handling uid_t is complicated for two reasons:
436 * * Although uid_t is (always?) unsigned, it still
437 * accepts -1.
438 * * We don't know its size in advance--it may be
439 * bigger than an int, or it may be smaller than
440 * a long.
441 *
442 * So a bit of defensive programming is in order.
443 * Start with interpreting the value passed
444 * in as a signed long and see if it works.
445 */
446
447 result = PyLong_AsLongAndOverflow(index, &overflow);
448
449 if (!overflow) {
450 uid = (uid_t)result;
451
452 if (result == -1) {
453 if (PyErr_Occurred())
454 goto fail;
455 /* It's a legitimate -1, we're done. */
456 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200457 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700458
459 /* Any other negative number is disallowed. */
460 if (result < 0)
461 goto underflow;
462
463 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200464 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700465 (long)uid != result)
466 goto underflow;
467 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200468 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700469
470 if (overflow < 0)
471 goto underflow;
472
473 /*
474 * Okay, the value overflowed a signed long. If it
475 * fits in an *unsigned* long, it may still be okay,
476 * as uid_t may be unsigned long on this platform.
477 */
478 uresult = PyLong_AsUnsignedLong(index);
479 if (PyErr_Occurred()) {
480 if (PyErr_ExceptionMatches(PyExc_OverflowError))
481 goto overflow;
482 goto fail;
483 }
484
485 uid = (uid_t)uresult;
486
487 /*
488 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
489 * but this value would get interpreted as (uid_t)-1 by chown
490 * and its siblings. That's not what the user meant! So we
491 * throw an overflow exception instead. (We already
492 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
493 */
494 if (uid == (uid_t)-1)
495 goto overflow;
496
497 /* Ensure the value wasn't truncated. */
498 if (sizeof(uid_t) < sizeof(long) &&
499 (unsigned long)uid != uresult)
500 goto overflow;
501 /* fallthrough */
502
503success:
504 Py_DECREF(index);
505 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506 return 1;
507
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700508underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200509 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700510 "uid is less than minimum");
511 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700515 "uid is greater than maximum");
516 /* fallthrough */
517
518fail:
519 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200520 return 0;
521}
522
523int
524_Py_Gid_Converter(PyObject *obj, void *p)
525{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 gid_t gid;
527 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200528 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200529 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 unsigned long uresult;
531
532 index = PyNumber_Index(obj);
533 if (index == NULL) {
534 PyErr_Format(PyExc_TypeError,
535 "gid should be integer, not %.200s",
536 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200537 return 0;
538 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700539
540 /*
541 * Handling gid_t is complicated for two reasons:
542 * * Although gid_t is (always?) unsigned, it still
543 * accepts -1.
544 * * We don't know its size in advance--it may be
545 * bigger than an int, or it may be smaller than
546 * a long.
547 *
548 * So a bit of defensive programming is in order.
549 * Start with interpreting the value passed
550 * in as a signed long and see if it works.
551 */
552
553 result = PyLong_AsLongAndOverflow(index, &overflow);
554
555 if (!overflow) {
556 gid = (gid_t)result;
557
558 if (result == -1) {
559 if (PyErr_Occurred())
560 goto fail;
561 /* It's a legitimate -1, we're done. */
562 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200563 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700564
565 /* Any other negative number is disallowed. */
566 if (result < 0) {
567 goto underflow;
568 }
569
570 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200571 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700572 (long)gid != result)
573 goto underflow;
574 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200575 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700576
577 if (overflow < 0)
578 goto underflow;
579
580 /*
581 * Okay, the value overflowed a signed long. If it
582 * fits in an *unsigned* long, it may still be okay,
583 * as gid_t may be unsigned long on this platform.
584 */
585 uresult = PyLong_AsUnsignedLong(index);
586 if (PyErr_Occurred()) {
587 if (PyErr_ExceptionMatches(PyExc_OverflowError))
588 goto overflow;
589 goto fail;
590 }
591
592 gid = (gid_t)uresult;
593
594 /*
595 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
596 * but this value would get interpreted as (gid_t)-1 by chown
597 * and its siblings. That's not what the user meant! So we
598 * throw an overflow exception instead. (We already
599 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
600 */
601 if (gid == (gid_t)-1)
602 goto overflow;
603
604 /* Ensure the value wasn't truncated. */
605 if (sizeof(gid_t) < sizeof(long) &&
606 (unsigned long)gid != uresult)
607 goto overflow;
608 /* fallthrough */
609
610success:
611 Py_DECREF(index);
612 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613 return 1;
614
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617 "gid is less than minimum");
618 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700622 "gid is greater than maximum");
623 /* fallthrough */
624
625fail:
626 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200627 return 0;
628}
629#endif /* MS_WINDOWS */
630
631
Larry Hastings9cf065c2012-06-22 16:30:09 -0700632#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400633/*
634 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
635 * without the int cast, the value gets interpreted as uint (4291925331),
636 * which doesn't play nicely with all the initializer lines in this file that
637 * look like this:
638 * int dir_fd = DEFAULT_DIR_FD;
639 */
640#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700641#else
642#define DEFAULT_DIR_FD (-100)
643#endif
644
645static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200646_fd_converter(PyObject *o, int *p, const char *allowed)
647{
648 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700649 long long_value;
650
651 PyObject *index = PyNumber_Index(o);
652 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200653 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700654 "argument should be %s, not %.200s",
655 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700656 return 0;
657 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700658
659 long_value = PyLong_AsLongAndOverflow(index, &overflow);
660 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200661 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700662 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700663 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700664 return 0;
665 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200666 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700668 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700669 return 0;
670 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700671
Larry Hastings9cf065c2012-06-22 16:30:09 -0700672 *p = (int)long_value;
673 return 1;
674}
675
676static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200677dir_fd_converter(PyObject *o, void *p)
678{
679 if (o == Py_None) {
680 *(int *)p = DEFAULT_DIR_FD;
681 return 1;
682 }
683 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684}
685
686
687
688/*
689 * A PyArg_ParseTuple "converter" function
690 * that handles filesystem paths in the manner
691 * preferred by the os module.
692 *
693 * path_converter accepts (Unicode) strings and their
694 * subclasses, and bytes and their subclasses. What
695 * it does with the argument depends on the platform:
696 *
697 * * On Windows, if we get a (Unicode) string we
698 * extract the wchar_t * and return it; if we get
699 * bytes we extract the char * and return that.
700 *
701 * * On all other platforms, strings are encoded
702 * to bytes using PyUnicode_FSConverter, then we
703 * extract the char * from the bytes object and
704 * return that.
705 *
706 * path_converter also optionally accepts signed
707 * integers (representing open file descriptors) instead
708 * of path strings.
709 *
710 * Input fields:
711 * path.nullable
712 * If nonzero, the path is permitted to be None.
713 * path.allow_fd
714 * If nonzero, the path is permitted to be a file handle
715 * (a signed int) instead of a string.
716 * path.function_name
717 * If non-NULL, path_converter will use that as the name
718 * of the function in error messages.
719 * (If path.argument_name is NULL it omits the function name.)
720 * path.argument_name
721 * If non-NULL, path_converter will use that as the name
722 * of the parameter in error messages.
723 * (If path.argument_name is NULL it uses "path".)
724 *
725 * Output fields:
726 * path.wide
727 * Points to the path if it was expressed as Unicode
728 * and was not encoded. (Only used on Windows.)
729 * path.narrow
730 * Points to the path if it was expressed as bytes,
731 * or it was Unicode and was encoded to bytes.
732 * path.fd
733 * Contains a file descriptor if path.accept_fd was true
734 * and the caller provided a signed integer instead of any
735 * sort of string.
736 *
737 * WARNING: if your "path" parameter is optional, and is
738 * unspecified, path_converter will never get called.
739 * So if you set allow_fd, you *MUST* initialize path.fd = -1
740 * yourself!
741 * path.length
742 * The length of the path in characters, if specified as
743 * a string.
744 * path.object
745 * The original object passed in.
746 * path.cleanup
747 * For internal use only. May point to a temporary object.
748 * (Pay no attention to the man behind the curtain.)
749 *
750 * At most one of path.wide or path.narrow will be non-NULL.
751 * If path was None and path.nullable was set,
752 * or if path was an integer and path.allow_fd was set,
753 * both path.wide and path.narrow will be NULL
754 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200755 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756 * path_converter takes care to not write to the path_t
757 * unless it's successful. However it must reset the
758 * "cleanup" field each time it's called.
759 *
760 * Use as follows:
761 * path_t path;
762 * memset(&path, 0, sizeof(path));
763 * PyArg_ParseTuple(args, "O&", path_converter, &path);
764 * // ... use values from path ...
765 * path_cleanup(&path);
766 *
767 * (Note that if PyArg_Parse fails you don't need to call
768 * path_cleanup(). However it is safe to do so.)
769 */
770typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100771 const char *function_name;
772 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773 int nullable;
774 int allow_fd;
775 wchar_t *wide;
776 char *narrow;
777 int fd;
778 Py_ssize_t length;
779 PyObject *object;
780 PyObject *cleanup;
781} path_t;
782
783static void
784path_cleanup(path_t *path) {
785 if (path->cleanup) {
786 Py_DECREF(path->cleanup);
787 path->cleanup = NULL;
788 }
789}
790
791static int
792path_converter(PyObject *o, void *p) {
793 path_t *path = (path_t *)p;
794 PyObject *unicode, *bytes;
795 Py_ssize_t length;
796 char *narrow;
797
798#define FORMAT_EXCEPTION(exc, fmt) \
799 PyErr_Format(exc, "%s%s" fmt, \
800 path->function_name ? path->function_name : "", \
801 path->function_name ? ": " : "", \
802 path->argument_name ? path->argument_name : "path")
803
804 /* Py_CLEANUP_SUPPORTED support */
805 if (o == NULL) {
806 path_cleanup(path);
807 return 1;
808 }
809
810 /* ensure it's always safe to call path_cleanup() */
811 path->cleanup = NULL;
812
813 if (o == Py_None) {
814 if (!path->nullable) {
815 FORMAT_EXCEPTION(PyExc_TypeError,
816 "can't specify None for %s argument");
817 return 0;
818 }
819 path->wide = NULL;
820 path->narrow = NULL;
821 path->length = 0;
822 path->object = o;
823 path->fd = -1;
824 return 1;
825 }
826
827 unicode = PyUnicode_FromObject(o);
828 if (unicode) {
829#ifdef MS_WINDOWS
830 wchar_t *wide;
831 length = PyUnicode_GET_SIZE(unicode);
832 if (length > 32767) {
833 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
834 Py_DECREF(unicode);
835 return 0;
836 }
837
838 wide = PyUnicode_AsUnicode(unicode);
839 if (!wide) {
840 Py_DECREF(unicode);
841 return 0;
842 }
843
844 path->wide = wide;
845 path->narrow = NULL;
846 path->length = length;
847 path->object = o;
848 path->fd = -1;
849 path->cleanup = unicode;
850 return Py_CLEANUP_SUPPORTED;
851#else
852 int converted = PyUnicode_FSConverter(unicode, &bytes);
853 Py_DECREF(unicode);
854 if (!converted)
855 bytes = NULL;
856#endif
857 }
858 else {
859 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200860 if (PyObject_CheckBuffer(o))
861 bytes = PyBytes_FromObject(o);
862 else
863 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700864 if (!bytes) {
865 PyErr_Clear();
866 if (path->allow_fd) {
867 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200868 int result = _fd_converter(o, &fd,
869 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700870 if (result) {
871 path->wide = NULL;
872 path->narrow = NULL;
873 path->length = 0;
874 path->object = o;
875 path->fd = fd;
876 return result;
877 }
878 }
879 }
880 }
881
882 if (!bytes) {
883 if (!PyErr_Occurred())
884 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
885 return 0;
886 }
887
888#ifdef MS_WINDOWS
889 if (win32_warn_bytes_api()) {
890 Py_DECREF(bytes);
891 return 0;
892 }
893#endif
894
895 length = PyBytes_GET_SIZE(bytes);
896#ifdef MS_WINDOWS
897 if (length > MAX_PATH) {
898 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
899 Py_DECREF(bytes);
900 return 0;
901 }
902#endif
903
904 narrow = PyBytes_AS_STRING(bytes);
905 if (length != strlen(narrow)) {
906 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
907 Py_DECREF(bytes);
908 return 0;
909 }
910
911 path->wide = NULL;
912 path->narrow = narrow;
913 path->length = length;
914 path->object = o;
915 path->fd = -1;
916 path->cleanup = bytes;
917 return Py_CLEANUP_SUPPORTED;
918}
919
920static void
921argument_unavailable_error(char *function_name, char *argument_name) {
922 PyErr_Format(PyExc_NotImplementedError,
923 "%s%s%s unavailable on this platform",
924 (function_name != NULL) ? function_name : "",
925 (function_name != NULL) ? ": ": "",
926 argument_name);
927}
928
929static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200930dir_fd_unavailable(PyObject *o, void *p)
931{
932 int dir_fd;
933 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200935 if (dir_fd != DEFAULT_DIR_FD) {
936 argument_unavailable_error(NULL, "dir_fd");
937 return 0;
938 }
939 *(int *)p = dir_fd;
940 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941}
942
943static int
944fd_specified(char *function_name, int fd) {
945 if (fd == -1)
946 return 0;
947
948 argument_unavailable_error(function_name, "fd");
949 return 1;
950}
951
952static int
953follow_symlinks_specified(char *function_name, int follow_symlinks) {
954 if (follow_symlinks)
955 return 0;
956
957 argument_unavailable_error(function_name, "follow_symlinks");
958 return 1;
959}
960
961static int
962path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
963 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
964 PyErr_Format(PyExc_ValueError,
965 "%s: can't specify dir_fd without matching path",
966 function_name);
967 return 1;
968 }
969 return 0;
970}
971
972static int
973dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
974 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
975 PyErr_Format(PyExc_ValueError,
976 "%s: can't specify both dir_fd and fd",
977 function_name);
978 return 1;
979 }
980 return 0;
981}
982
983static int
984fd_and_follow_symlinks_invalid(char *function_name, int fd,
985 int follow_symlinks) {
986 if ((fd > 0) && (!follow_symlinks)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: cannot use fd and follow_symlinks together",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
995static int
996dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
997 int follow_symlinks) {
998 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
999 PyErr_Format(PyExc_ValueError,
1000 "%s: cannot use dir_fd and follow_symlinks together",
1001 function_name);
1002 return 1;
1003 }
1004 return 0;
1005}
1006
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001007/* A helper used by a number of POSIX-only functions */
1008#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001009static int
1010_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001011{
1012#if !defined(HAVE_LARGEFILE_SUPPORT)
1013 *((off_t*)addr) = PyLong_AsLong(arg);
1014#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001015 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001016#endif
1017 if (PyErr_Occurred())
1018 return 0;
1019 return 1;
1020}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001021#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001022
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001023#if defined _MSC_VER && _MSC_VER >= 1400
1024/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001025 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001026 * Normally, an invalid fd is likely to be a C program error and therefore
1027 * an assertion can be useful, but it does contradict the POSIX standard
1028 * which for write(2) states:
1029 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1030 * "[EBADF] The fildes argument is not a valid file descriptor open for
1031 * writing."
1032 * Furthermore, python allows the user to enter any old integer
1033 * as a fd and should merely raise a python exception on error.
1034 * The Microsoft CRT doesn't provide an official way to check for the
1035 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001036 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001037 * internal structures involved.
1038 * The structures below must be updated for each version of visual studio
1039 * according to the file internal.h in the CRT source, until MS comes
1040 * up with a less hacky way to do this.
1041 * (all of this is to avoid globally modifying the CRT behaviour using
1042 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1043 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001044/* The actual size of the structure is determined at runtime.
1045 * Only the first items must be present.
1046 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001047typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001048 intptr_t osfhnd;
1049 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001050} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001051
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001052extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001053#define IOINFO_L2E 5
1054#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1055#define IOINFO_ARRAYS 64
1056#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1057#define FOPEN 0x01
1058#define _NO_CONSOLE_FILENO (intptr_t)-2
1059
1060/* This function emulates what the windows CRT does to validate file handles */
1061int
1062_PyVerify_fd(int fd)
1063{
Victor Stinner8c62be82010-05-06 00:08:46 +00001064 const int i1 = fd >> IOINFO_L2E;
1065 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001066
Antoine Pitrou22e41552010-08-15 18:07:50 +00001067 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 /* Determine the actual size of the ioinfo structure,
1070 * as used by the CRT loaded in memory
1071 */
1072 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1073 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1074 }
1075 if (sizeof_ioinfo == 0) {
1076 /* This should not happen... */
1077 goto fail;
1078 }
1079
1080 /* See that it isn't a special CLEAR fileno */
1081 if (fd != _NO_CONSOLE_FILENO) {
1082 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1083 * we check pointer validity and other info
1084 */
1085 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1086 /* finally, check that the file is open */
1087 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1088 if (info->osfile & FOPEN) {
1089 return 1;
1090 }
1091 }
1092 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001093 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001094 errno = EBADF;
1095 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001096}
1097
1098/* the special case of checking dup2. The target fd must be in a sensible range */
1099static int
1100_PyVerify_fd_dup2(int fd1, int fd2)
1101{
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 if (!_PyVerify_fd(fd1))
1103 return 0;
1104 if (fd2 == _NO_CONSOLE_FILENO)
1105 return 0;
1106 if ((unsigned)fd2 < _NHANDLE_)
1107 return 1;
1108 else
1109 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001110}
1111#else
1112/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1113#define _PyVerify_fd_dup2(A, B) (1)
1114#endif
1115
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001116#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001117/* The following structure was copied from
1118 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1119 include doesn't seem to be present in the Windows SDK (at least as included
1120 with Visual Studio Express). */
1121typedef struct _REPARSE_DATA_BUFFER {
1122 ULONG ReparseTag;
1123 USHORT ReparseDataLength;
1124 USHORT Reserved;
1125 union {
1126 struct {
1127 USHORT SubstituteNameOffset;
1128 USHORT SubstituteNameLength;
1129 USHORT PrintNameOffset;
1130 USHORT PrintNameLength;
1131 ULONG Flags;
1132 WCHAR PathBuffer[1];
1133 } SymbolicLinkReparseBuffer;
1134
1135 struct {
1136 USHORT SubstituteNameOffset;
1137 USHORT SubstituteNameLength;
1138 USHORT PrintNameOffset;
1139 USHORT PrintNameLength;
1140 WCHAR PathBuffer[1];
1141 } MountPointReparseBuffer;
1142
1143 struct {
1144 UCHAR DataBuffer[1];
1145 } GenericReparseBuffer;
1146 };
1147} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1148
1149#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1150 GenericReparseBuffer)
1151#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1152
1153static int
Brian Curtind25aef52011-06-13 15:16:04 -05001154win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001155{
1156 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1157 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1158 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001159
1160 if (0 == DeviceIoControl(
1161 reparse_point_handle,
1162 FSCTL_GET_REPARSE_POINT,
1163 NULL, 0, /* in buffer */
1164 target_buffer, sizeof(target_buffer),
1165 &n_bytes_returned,
1166 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001167 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001168
1169 if (reparse_tag)
1170 *reparse_tag = rdb->ReparseTag;
1171
Brian Curtind25aef52011-06-13 15:16:04 -05001172 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001173}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001174
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001175#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001176
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001178#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001179/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001180** environ directly, we must obtain it with _NSGetEnviron(). See also
1181** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001182*/
1183#include <crt_externs.h>
1184static char **environ;
1185#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001187#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188
Barry Warsaw53699e91996-12-10 23:23:01 +00001189static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001190convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191{
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001193#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001194 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001196 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001197#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001198
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 d = PyDict_New();
1200 if (d == NULL)
1201 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001202#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001203 if (environ == NULL)
1204 environ = *_NSGetEnviron();
1205#endif
1206#ifdef MS_WINDOWS
1207 /* _wenviron must be initialized in this way if the program is started
1208 through main() instead of wmain(). */
1209 _wgetenv(L"");
1210 if (_wenviron == NULL)
1211 return d;
1212 /* This part ignores errors */
1213 for (e = _wenviron; *e != NULL; e++) {
1214 PyObject *k;
1215 PyObject *v;
1216 wchar_t *p = wcschr(*e, L'=');
1217 if (p == NULL)
1218 continue;
1219 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1220 if (k == NULL) {
1221 PyErr_Clear();
1222 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001223 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1225 if (v == NULL) {
1226 PyErr_Clear();
1227 Py_DECREF(k);
1228 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001229 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001230 if (PyDict_GetItem(d, k) == NULL) {
1231 if (PyDict_SetItem(d, k, v) != 0)
1232 PyErr_Clear();
1233 }
1234 Py_DECREF(k);
1235 Py_DECREF(v);
1236 }
1237#else
1238 if (environ == NULL)
1239 return d;
1240 /* This part ignores errors */
1241 for (e = environ; *e != NULL; e++) {
1242 PyObject *k;
1243 PyObject *v;
1244 char *p = strchr(*e, '=');
1245 if (p == NULL)
1246 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001247 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 if (k == NULL) {
1249 PyErr_Clear();
1250 continue;
1251 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001252 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (v == NULL) {
1254 PyErr_Clear();
1255 Py_DECREF(k);
1256 continue;
1257 }
1258 if (PyDict_GetItem(d, k) == NULL) {
1259 if (PyDict_SetItem(d, k, v) != 0)
1260 PyErr_Clear();
1261 }
1262 Py_DECREF(k);
1263 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001264 }
1265#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269/* Set a POSIX-specific error from errno, and return NULL */
1270
Barry Warsawd58d7641998-07-23 16:14:40 +00001271static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001272posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001273{
Victor Stinner8c62be82010-05-06 00:08:46 +00001274 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275}
Mark Hammondef8b6542001-05-13 08:04:26 +00001276
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001277#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001278static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001279win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001280{
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 /* XXX We should pass the function name along in the future.
1282 (winreg.c also wants to pass the function name.)
1283 This would however require an additional param to the
1284 Windows error object, which is non-trivial.
1285 */
1286 errno = GetLastError();
1287 if (filename)
1288 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1289 else
1290 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001291}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001292
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001293static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001294win32_error_object(char* function, PyObject* filename)
1295{
1296 /* XXX - see win32_error for comments on 'function' */
1297 errno = GetLastError();
1298 if (filename)
1299 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001300 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001301 errno,
1302 filename);
1303 else
1304 return PyErr_SetFromWindowsErr(errno);
1305}
1306
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001307#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308
Larry Hastings9cf065c2012-06-22 16:30:09 -07001309static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001310path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001311{
1312#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001313 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1314 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001315#else
Victor Stinner292c8352012-10-30 02:17:38 +01001316 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001317#endif
1318}
1319
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320/* POSIX generic methods */
1321
Barry Warsaw53699e91996-12-10 23:23:01 +00001322static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001323posix_fildes(PyObject *fdobj, int (*func)(int))
1324{
Victor Stinner8c62be82010-05-06 00:08:46 +00001325 int fd;
1326 int res;
1327 fd = PyObject_AsFileDescriptor(fdobj);
1328 if (fd < 0)
1329 return NULL;
1330 if (!_PyVerify_fd(fd))
1331 return posix_error();
1332 Py_BEGIN_ALLOW_THREADS
1333 res = (*func)(fd);
1334 Py_END_ALLOW_THREADS
1335 if (res < 0)
1336 return posix_error();
1337 Py_INCREF(Py_None);
1338 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001339}
Guido van Rossum21142a01999-01-08 21:05:37 +00001340
1341static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001342posix_1str(const char *func_name, PyObject *args, char *format,
1343 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344{
Victor Stinner292c8352012-10-30 02:17:38 +01001345 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001347 memset(&path, 0, sizeof(path));
1348 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001350 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001353 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001355 if (res < 0) {
1356 path_error(&path);
1357 path_cleanup(&path);
1358 return NULL;
1359 }
1360 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 Py_INCREF(Py_None);
1362 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001363}
1364
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001366#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001367/* This is a reimplementation of the C library's chdir function,
1368 but one that produces Win32 errors instead of DOS error codes.
1369 chdir is essentially a wrapper around SetCurrentDirectory; however,
1370 it also needs to set "magic" environment variables indicating
1371 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001372static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373win32_chdir(LPCSTR path)
1374{
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 char new_path[MAX_PATH+1];
1376 int result;
1377 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 if(!SetCurrentDirectoryA(path))
1380 return FALSE;
1381 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1382 if (!result)
1383 return FALSE;
1384 /* In the ANSI API, there should not be any paths longer
1385 than MAX_PATH. */
1386 assert(result <= MAX_PATH+1);
1387 if (strncmp(new_path, "\\\\", 2) == 0 ||
1388 strncmp(new_path, "//", 2) == 0)
1389 /* UNC path, nothing to do. */
1390 return TRUE;
1391 env[1] = new_path[0];
1392 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001393}
1394
1395/* The Unicode version differs from the ANSI version
1396 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001397static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398win32_wchdir(LPCWSTR path)
1399{
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1401 int result;
1402 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 if(!SetCurrentDirectoryW(path))
1405 return FALSE;
1406 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1407 if (!result)
1408 return FALSE;
1409 if (result > MAX_PATH+1) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001410 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 if (!new_path) {
1412 SetLastError(ERROR_OUTOFMEMORY);
1413 return FALSE;
1414 }
1415 result = GetCurrentDirectoryW(result, new_path);
1416 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001417 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 return FALSE;
1419 }
1420 }
1421 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1422 wcsncmp(new_path, L"//", 2) == 0)
1423 /* UNC path, nothing to do. */
1424 return TRUE;
1425 env[1] = new_path[0];
1426 result = SetEnvironmentVariableW(env, new_path);
1427 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001428 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430}
1431#endif
1432
Martin v. Löwis14694662006-02-03 12:54:16 +00001433#ifdef MS_WINDOWS
1434/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1435 - time stamps are restricted to second resolution
1436 - file modification times suffer from forth-and-back conversions between
1437 UTC and local time
1438 Therefore, we implement our own stat, based on the Win32 API directly.
1439*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001440#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001441
1442struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001443 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001444 __int64 st_ino;
1445 unsigned short st_mode;
1446 int st_nlink;
1447 int st_uid;
1448 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001449 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001451 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001453 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001454 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001455 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001456 int st_ctime_nsec;
1457};
1458
1459static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1460
1461static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001462FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001463{
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1465 /* Cannot simply cast and dereference in_ptr,
1466 since it might not be aligned properly */
1467 __int64 in;
1468 memcpy(&in, in_ptr, sizeof(in));
1469 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001470 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001471}
1472
Thomas Wouters477c8d52006-05-27 19:21:47 +00001473static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001474time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475{
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 /* XXX endianness */
1477 __int64 out;
1478 out = time_in + secs_between_epochs;
1479 out = out * 10000000 + nsec_in / 100;
1480 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001481}
1482
Martin v. Löwis14694662006-02-03 12:54:16 +00001483/* Below, we *know* that ugo+r is 0444 */
1484#if _S_IREAD != 0400
1485#error Unsupported C library
1486#endif
1487static int
1488attributes_to_mode(DWORD attr)
1489{
Victor Stinner8c62be82010-05-06 00:08:46 +00001490 int m = 0;
1491 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1492 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1493 else
1494 m |= _S_IFREG;
1495 if (attr & FILE_ATTRIBUTE_READONLY)
1496 m |= 0444;
1497 else
1498 m |= 0666;
1499 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001500}
1501
1502static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001503attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001504{
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 memset(result, 0, sizeof(*result));
1506 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1507 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001508 result->st_dev = info->dwVolumeSerialNumber;
1509 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001510 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1511 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1512 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001513 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001514 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001515 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1516 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001517 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001518 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001519 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001520 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001521
Victor Stinner8c62be82010-05-06 00:08:46 +00001522 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001523}
1524
Guido van Rossumd8faa362007-04-27 19:54:29 +00001525static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001527{
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 HANDLE hFindFile;
1529 WIN32_FIND_DATAA FileData;
1530 hFindFile = FindFirstFileA(pszFile, &FileData);
1531 if (hFindFile == INVALID_HANDLE_VALUE)
1532 return FALSE;
1533 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001534 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001535 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 info->dwFileAttributes = FileData.dwFileAttributes;
1537 info->ftCreationTime = FileData.ftCreationTime;
1538 info->ftLastAccessTime = FileData.ftLastAccessTime;
1539 info->ftLastWriteTime = FileData.ftLastWriteTime;
1540 info->nFileSizeHigh = FileData.nFileSizeHigh;
1541 info->nFileSizeLow = FileData.nFileSizeLow;
1542/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001543 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1544 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001545 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001546}
1547
1548static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001549attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001550{
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 HANDLE hFindFile;
1552 WIN32_FIND_DATAW FileData;
1553 hFindFile = FindFirstFileW(pszFile, &FileData);
1554 if (hFindFile == INVALID_HANDLE_VALUE)
1555 return FALSE;
1556 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001557 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001558 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001559 info->dwFileAttributes = FileData.dwFileAttributes;
1560 info->ftCreationTime = FileData.ftCreationTime;
1561 info->ftLastAccessTime = FileData.ftLastAccessTime;
1562 info->ftLastWriteTime = FileData.ftLastWriteTime;
1563 info->nFileSizeHigh = FileData.nFileSizeHigh;
1564 info->nFileSizeLow = FileData.nFileSizeLow;
1565/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001566 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1567 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001569}
1570
Brian Curtind25aef52011-06-13 15:16:04 -05001571/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001572static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001573static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1574 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575static int
Brian Curtind25aef52011-06-13 15:16:04 -05001576check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001577{
Brian Curtind25aef52011-06-13 15:16:04 -05001578 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001579 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1580 DWORD);
1581
Brian Curtind25aef52011-06-13 15:16:04 -05001582 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001583 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001584 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001585 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001586 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1587 "GetFinalPathNameByHandleA");
1588 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1589 "GetFinalPathNameByHandleW");
1590 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1591 Py_GetFinalPathNameByHandleW;
1592 }
1593 return has_GetFinalPathNameByHandle;
1594}
1595
1596static BOOL
1597get_target_path(HANDLE hdl, wchar_t **target_path)
1598{
1599 int buf_size, result_length;
1600 wchar_t *buf;
1601
1602 /* We have a good handle to the target, use it to determine
1603 the target path name (then we'll call lstat on it). */
1604 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1605 VOLUME_NAME_DOS);
1606 if(!buf_size)
1607 return FALSE;
1608
Victor Stinnerb6404912013-07-07 16:21:41 +02001609 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001610 if (!buf) {
1611 SetLastError(ERROR_OUTOFMEMORY);
1612 return FALSE;
1613 }
1614
Brian Curtind25aef52011-06-13 15:16:04 -05001615 result_length = Py_GetFinalPathNameByHandleW(hdl,
1616 buf, buf_size, VOLUME_NAME_DOS);
1617
1618 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001619 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001620 return FALSE;
1621 }
1622
1623 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001624 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001625 return FALSE;
1626 }
1627
1628 buf[result_length] = 0;
1629
1630 *target_path = buf;
1631 return TRUE;
1632}
1633
1634static int
1635win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1636 BOOL traverse);
1637static int
1638win32_xstat_impl(const char *path, struct win32_stat *result,
1639 BOOL traverse)
1640{
Victor Stinner26de69d2011-06-17 15:15:38 +02001641 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001642 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001643 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001644 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001645 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001646 const char *dot;
1647
Brian Curtind25aef52011-06-13 15:16:04 -05001648 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001649 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1650 traverse reparse point. */
1651 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001652 }
1653
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 hFile = CreateFileA(
1655 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001656 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 0, /* share mode */
1658 NULL, /* security attributes */
1659 OPEN_EXISTING,
1660 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001661 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1662 Because of this, calls like GetFinalPathNameByHandle will return
1663 the symlink path agin and not the actual final path. */
1664 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1665 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 NULL);
1667
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 /* Either the target doesn't exist, or we don't have access to
1670 get a handle to it. If the former, we need to return an error.
1671 If the latter, we can use attributes_from_dir. */
1672 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673 return -1;
1674 /* Could not get attributes on open file. Fall back to
1675 reading the directory. */
1676 if (!attributes_from_dir(path, &info, &reparse_tag))
1677 /* Very strange. This should not fail now */
1678 return -1;
1679 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1680 if (traverse) {
1681 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001684 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686 } else {
1687 if (!GetFileInformationByHandle(hFile, &info)) {
1688 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001689 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001690 }
1691 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001692 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1693 return -1;
1694
1695 /* Close the outer open file handle now that we're about to
1696 reopen it with different flags. */
1697 if (!CloseHandle(hFile))
1698 return -1;
1699
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001701 /* In order to call GetFinalPathNameByHandle we need to open
1702 the file without the reparse handling flag set. */
1703 hFile2 = CreateFileA(
1704 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1705 NULL, OPEN_EXISTING,
1706 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1707 NULL);
1708 if (hFile2 == INVALID_HANDLE_VALUE)
1709 return -1;
1710
1711 if (!get_target_path(hFile2, &target_path))
1712 return -1;
1713
1714 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001715 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 return code;
1717 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001718 } else
1719 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722
1723 /* Set S_IEXEC if it is an .exe, .bat, ... */
1724 dot = strrchr(path, '.');
1725 if (dot) {
1726 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1727 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1728 result->st_mode |= 0111;
1729 }
1730 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731}
1732
1733static int
Brian Curtind25aef52011-06-13 15:16:04 -05001734win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1735 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736{
1737 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001738 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001740 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001741 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001742 const wchar_t *dot;
1743
Brian Curtind25aef52011-06-13 15:16:04 -05001744 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001745 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1746 traverse reparse point. */
1747 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001748 }
1749
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750 hFile = CreateFileW(
1751 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001752 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001753 0, /* share mode */
1754 NULL, /* security attributes */
1755 OPEN_EXISTING,
1756 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001757 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1758 Because of this, calls like GetFinalPathNameByHandle will return
1759 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001760 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001761 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001762 NULL);
1763
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001764 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001765 /* Either the target doesn't exist, or we don't have access to
1766 get a handle to it. If the former, we need to return an error.
1767 If the latter, we can use attributes_from_dir. */
1768 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001769 return -1;
1770 /* Could not get attributes on open file. Fall back to
1771 reading the directory. */
1772 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1773 /* Very strange. This should not fail now */
1774 return -1;
1775 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1776 if (traverse) {
1777 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001780 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001781 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 } else {
1783 if (!GetFileInformationByHandle(hFile, &info)) {
1784 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001785 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001786 }
1787 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001788 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1789 return -1;
1790
1791 /* Close the outer open file handle now that we're about to
1792 reopen it with different flags. */
1793 if (!CloseHandle(hFile))
1794 return -1;
1795
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001796 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001797 /* In order to call GetFinalPathNameByHandle we need to open
1798 the file without the reparse handling flag set. */
1799 hFile2 = CreateFileW(
1800 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1801 NULL, OPEN_EXISTING,
1802 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1803 NULL);
1804 if (hFile2 == INVALID_HANDLE_VALUE)
1805 return -1;
1806
1807 if (!get_target_path(hFile2, &target_path))
1808 return -1;
1809
1810 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001811 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001812 return code;
1813 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001814 } else
1815 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001816 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001817 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818
1819 /* Set S_IEXEC if it is an .exe, .bat, ... */
1820 dot = wcsrchr(path, '.');
1821 if (dot) {
1822 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1823 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1824 result->st_mode |= 0111;
1825 }
1826 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001827}
1828
1829static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001830win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001831{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001832 /* Protocol violation: we explicitly clear errno, instead of
1833 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001834 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001835 errno = 0;
1836 return code;
1837}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001838
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001839static int
1840win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1841{
1842 /* Protocol violation: we explicitly clear errno, instead of
1843 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001844 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001845 errno = 0;
1846 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001847}
Brian Curtind25aef52011-06-13 15:16:04 -05001848/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001849
1850 In Posix, stat automatically traverses symlinks and returns the stat
1851 structure for the target. In Windows, the equivalent GetFileAttributes by
1852 default does not traverse symlinks and instead returns attributes for
1853 the symlink.
1854
1855 Therefore, win32_lstat will get the attributes traditionally, and
1856 win32_stat will first explicitly resolve the symlink target and then will
1857 call win32_lstat on that result.
1858
Ezio Melotti4969f702011-03-15 05:59:46 +02001859 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001860
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001861static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001862win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001863{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001865}
1866
Victor Stinner8c62be82010-05-06 00:08:46 +00001867static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001868win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001869{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001870 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001871}
1872
1873static int
1874win32_stat(const char* path, struct win32_stat *result)
1875{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001876 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001877}
1878
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001879static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001880win32_stat_w(const wchar_t* path, struct win32_stat *result)
1881{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001883}
1884
1885static int
1886win32_fstat(int file_number, struct win32_stat *result)
1887{
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 BY_HANDLE_FILE_INFORMATION info;
1889 HANDLE h;
1890 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001891
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001892 if (!_PyVerify_fd(file_number))
1893 h = INVALID_HANDLE_VALUE;
1894 else
1895 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 /* Protocol violation: we explicitly clear errno, instead of
1898 setting it to a POSIX error. Callers should use GetLastError. */
1899 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001900
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 if (h == INVALID_HANDLE_VALUE) {
1902 /* This is really a C library error (invalid file handle).
1903 We set the Win32 error to the closes one matching. */
1904 SetLastError(ERROR_INVALID_HANDLE);
1905 return -1;
1906 }
1907 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001908
Victor Stinner8c62be82010-05-06 00:08:46 +00001909 type = GetFileType(h);
1910 if (type == FILE_TYPE_UNKNOWN) {
1911 DWORD error = GetLastError();
1912 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001913 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 }
1915 /* else: valid but unknown file */
1916 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001917
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 if (type != FILE_TYPE_DISK) {
1919 if (type == FILE_TYPE_CHAR)
1920 result->st_mode = _S_IFCHR;
1921 else if (type == FILE_TYPE_PIPE)
1922 result->st_mode = _S_IFIFO;
1923 return 0;
1924 }
1925
1926 if (!GetFileInformationByHandle(h, &info)) {
1927 return -1;
1928 }
1929
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001930 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1933 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001934}
1935
1936#endif /* MS_WINDOWS */
1937
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001938PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001939"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001940This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001941 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1943\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001944Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1945or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001946\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001947See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948
1949static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 {"st_mode", "protection bits"},
1951 {"st_ino", "inode"},
1952 {"st_dev", "device"},
1953 {"st_nlink", "number of hard links"},
1954 {"st_uid", "user ID of owner"},
1955 {"st_gid", "group ID of owner"},
1956 {"st_size", "total size, in bytes"},
1957 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1958 {NULL, "integer time of last access"},
1959 {NULL, "integer time of last modification"},
1960 {NULL, "integer time of last change"},
1961 {"st_atime", "time of last access"},
1962 {"st_mtime", "time of last modification"},
1963 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001964 {"st_atime_ns", "time of last access in nanoseconds"},
1965 {"st_mtime_ns", "time of last modification in nanoseconds"},
1966 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001967#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001970#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001976#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001978#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001979#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001981#endif
1982#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001984#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986};
1987
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001988#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001989#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001990#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001991#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#endif
1993
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001994#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1996#else
1997#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1998#endif
1999
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002000#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002001#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2002#else
2003#define ST_RDEV_IDX ST_BLOCKS_IDX
2004#endif
2005
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002006#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2007#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2008#else
2009#define ST_FLAGS_IDX ST_RDEV_IDX
2010#endif
2011
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002012#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002013#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002015#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#endif
2017
2018#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2019#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2020#else
2021#define ST_BIRTHTIME_IDX ST_GEN_IDX
2022#endif
2023
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 "stat_result", /* name */
2026 stat_result__doc__, /* doc */
2027 stat_result_fields,
2028 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029};
2030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002032"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2033This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002035or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002036\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038
2039static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 {"f_bsize", },
2041 {"f_frsize", },
2042 {"f_blocks", },
2043 {"f_bfree", },
2044 {"f_bavail", },
2045 {"f_files", },
2046 {"f_ffree", },
2047 {"f_favail", },
2048 {"f_flag", },
2049 {"f_namemax",},
2050 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051};
2052
2053static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 "statvfs_result", /* name */
2055 statvfs_result__doc__, /* doc */
2056 statvfs_result_fields,
2057 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002058};
2059
Ross Lagerwall7807c352011-03-17 20:20:30 +02002060#if defined(HAVE_WAITID) && !defined(__APPLE__)
2061PyDoc_STRVAR(waitid_result__doc__,
2062"waitid_result: Result from waitid.\n\n\
2063This object may be accessed either as a tuple of\n\
2064 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2065or via the attributes si_pid, si_uid, and so on.\n\
2066\n\
2067See os.waitid for more information.");
2068
2069static PyStructSequence_Field waitid_result_fields[] = {
2070 {"si_pid", },
2071 {"si_uid", },
2072 {"si_signo", },
2073 {"si_status", },
2074 {"si_code", },
2075 {0}
2076};
2077
2078static PyStructSequence_Desc waitid_result_desc = {
2079 "waitid_result", /* name */
2080 waitid_result__doc__, /* doc */
2081 waitid_result_fields,
2082 5
2083};
2084static PyTypeObject WaitidResultType;
2085#endif
2086
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002087static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002088static PyTypeObject StatResultType;
2089static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002090#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002091static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002092#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002093static newfunc structseq_new;
2094
2095static PyObject *
2096statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2097{
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 PyStructSequence *result;
2099 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002100
Victor Stinner8c62be82010-05-06 00:08:46 +00002101 result = (PyStructSequence*)structseq_new(type, args, kwds);
2102 if (!result)
2103 return NULL;
2104 /* If we have been initialized from a tuple,
2105 st_?time might be set to None. Initialize it
2106 from the int slots. */
2107 for (i = 7; i <= 9; i++) {
2108 if (result->ob_item[i+3] == Py_None) {
2109 Py_DECREF(Py_None);
2110 Py_INCREF(result->ob_item[i]);
2111 result->ob_item[i+3] = result->ob_item[i];
2112 }
2113 }
2114 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002115}
2116
2117
2118
2119/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002120static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002121
2122PyDoc_STRVAR(stat_float_times__doc__,
2123"stat_float_times([newval]) -> oldval\n\n\
2124Determine whether os.[lf]stat represents time stamps as float objects.\n\
2125If newval is True, future calls to stat() return floats, if it is False,\n\
2126future calls return ints. \n\
2127If newval is omitted, return the current setting.\n");
2128
2129static PyObject*
2130stat_float_times(PyObject* self, PyObject *args)
2131{
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 int newval = -1;
2133 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2134 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002135 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2136 "stat_float_times() is deprecated",
2137 1))
2138 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002139 if (newval == -1)
2140 /* Return old value */
2141 return PyBool_FromLong(_stat_float_times);
2142 _stat_float_times = newval;
2143 Py_INCREF(Py_None);
2144 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002145}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002146
Larry Hastings6fe20b32012-04-19 15:07:49 -07002147static PyObject *billion = NULL;
2148
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002149static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002150fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002151{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002152 PyObject *s = _PyLong_FromTime_t(sec);
2153 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2154 PyObject *s_in_ns = NULL;
2155 PyObject *ns_total = NULL;
2156 PyObject *float_s = NULL;
2157
2158 if (!(s && ns_fractional))
2159 goto exit;
2160
2161 s_in_ns = PyNumber_Multiply(s, billion);
2162 if (!s_in_ns)
2163 goto exit;
2164
2165 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2166 if (!ns_total)
2167 goto exit;
2168
Victor Stinner4195b5c2012-02-08 23:03:19 +01002169 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002170 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2171 if (!float_s)
2172 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002173 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002174 else {
2175 float_s = s;
2176 Py_INCREF(float_s);
2177 }
2178
2179 PyStructSequence_SET_ITEM(v, index, s);
2180 PyStructSequence_SET_ITEM(v, index+3, float_s);
2181 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2182 s = NULL;
2183 float_s = NULL;
2184 ns_total = NULL;
2185exit:
2186 Py_XDECREF(s);
2187 Py_XDECREF(ns_fractional);
2188 Py_XDECREF(s_in_ns);
2189 Py_XDECREF(ns_total);
2190 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002191}
2192
Tim Peters5aa91602002-01-30 05:46:57 +00002193/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002194 (used by posix_stat() and posix_fstat()) */
2195static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002196_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002197{
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 unsigned long ansec, mnsec, cnsec;
2199 PyObject *v = PyStructSequence_New(&StatResultType);
2200 if (v == NULL)
2201 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002202
Victor Stinner8c62be82010-05-06 00:08:46 +00002203 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002204#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, 1,
2206 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002207#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002208 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002209#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002210#ifdef MS_WINDOWS
2211 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2212#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002213 PyStructSequence_SET_ITEM(v, 2,
2214 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002215#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002216 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002217#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002219#if defined(MS_WINDOWS)
2220 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2221 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2222#else
2223 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2224 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2225#endif
Fred Drake699f3522000-06-29 21:12:41 +00002226#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 PyStructSequence_SET_ITEM(v, 6,
2228 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002229#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002231#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002232
Martin v. Löwis14694662006-02-03 12:54:16 +00002233#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002234 ansec = st->st_atim.tv_nsec;
2235 mnsec = st->st_mtim.tv_nsec;
2236 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002237#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 ansec = st->st_atimespec.tv_nsec;
2239 mnsec = st->st_mtimespec.tv_nsec;
2240 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002241#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 ansec = st->st_atime_nsec;
2243 mnsec = st->st_mtime_nsec;
2244 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002245#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002247#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002248 fill_time(v, 7, st->st_atime, ansec);
2249 fill_time(v, 8, st->st_mtime, mnsec);
2250 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002251
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002252#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002253 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2254 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002255#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002256#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002257 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2258 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002259#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002260#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002261 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2262 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002263#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002264#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002265 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2266 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002267#endif
2268#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002269 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002270 PyObject *val;
2271 unsigned long bsec,bnsec;
2272 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002273#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002274 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002276 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002277#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002278 if (_stat_float_times) {
2279 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2280 } else {
2281 val = PyLong_FromLong((long)bsec);
2282 }
2283 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2284 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002285 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002286#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002287#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2289 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002290#endif
Fred Drake699f3522000-06-29 21:12:41 +00002291
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 if (PyErr_Occurred()) {
2293 Py_DECREF(v);
2294 return NULL;
2295 }
Fred Drake699f3522000-06-29 21:12:41 +00002296
Victor Stinner8c62be82010-05-06 00:08:46 +00002297 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002298}
2299
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002300/* POSIX methods */
2301
Guido van Rossum94f6f721999-01-06 18:42:14 +00002302
2303static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002304posix_do_stat(char *function_name, path_t *path,
2305 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002306{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002307 STRUCT_STAT st;
2308 int result;
2309
2310#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2311 if (follow_symlinks_specified(function_name, follow_symlinks))
2312 return NULL;
2313#endif
2314
2315 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2316 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2317 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2318 return NULL;
2319
2320 Py_BEGIN_ALLOW_THREADS
2321 if (path->fd != -1)
2322 result = FSTAT(path->fd, &st);
2323 else
2324#ifdef MS_WINDOWS
2325 if (path->wide) {
2326 if (follow_symlinks)
2327 result = win32_stat_w(path->wide, &st);
2328 else
2329 result = win32_lstat_w(path->wide, &st);
2330 }
2331 else
2332#endif
2333#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2334 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2335 result = LSTAT(path->narrow, &st);
2336 else
2337#endif
2338#ifdef HAVE_FSTATAT
2339 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2340 result = fstatat(dir_fd, path->narrow, &st,
2341 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2342 else
2343#endif
2344 result = STAT(path->narrow, &st);
2345 Py_END_ALLOW_THREADS
2346
Victor Stinner292c8352012-10-30 02:17:38 +01002347 if (result != 0) {
2348 return path_error(path);
2349 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002350
2351 return _pystat_fromstructstat(&st);
2352}
2353
2354PyDoc_STRVAR(posix_stat__doc__,
2355"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2356Perform a stat system call on the given path.\n\
2357\n\
2358path may be specified as either a string or as an open file descriptor.\n\
2359\n\
2360If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2361 and path should be relative; path will then be relative to that directory.\n\
2362 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2363 it will raise a NotImplementedError.\n\
2364If follow_symlinks is False, and the last element of the path is a symbolic\n\
2365 link, stat will examine the symbolic link itself instead of the file the\n\
2366 link points to.\n\
2367It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2368 an open file descriptor.");
2369
2370static PyObject *
2371posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2372{
2373 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2374 path_t path;
2375 int dir_fd = DEFAULT_DIR_FD;
2376 int follow_symlinks = 1;
2377 PyObject *return_value;
2378
2379 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002380 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002381 path.allow_fd = 1;
2382 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2383 path_converter, &path,
2384#ifdef HAVE_FSTATAT
2385 dir_fd_converter, &dir_fd,
2386#else
2387 dir_fd_unavailable, &dir_fd,
2388#endif
2389 &follow_symlinks))
2390 return NULL;
2391 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2392 path_cleanup(&path);
2393 return return_value;
2394}
2395
2396PyDoc_STRVAR(posix_lstat__doc__,
2397"lstat(path, *, dir_fd=None) -> stat result\n\n\
2398Like stat(), but do not follow symbolic links.\n\
2399Equivalent to stat(path, follow_symlinks=False).");
2400
2401static PyObject *
2402posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2403{
2404 static char *keywords[] = {"path", "dir_fd", NULL};
2405 path_t path;
2406 int dir_fd = DEFAULT_DIR_FD;
2407 int follow_symlinks = 0;
2408 PyObject *return_value;
2409
2410 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002411 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002412 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2413 path_converter, &path,
2414#ifdef HAVE_FSTATAT
2415 dir_fd_converter, &dir_fd
2416#else
2417 dir_fd_unavailable, &dir_fd
2418#endif
2419 ))
2420 return NULL;
2421 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2422 path_cleanup(&path);
2423 return return_value;
2424}
2425
2426PyDoc_STRVAR(posix_access__doc__,
2427"access(path, mode, *, dir_fd=None, effective_ids=False,\
2428 follow_symlinks=True)\n\n\
2429Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2430False otherwise.\n\
2431\n\
2432If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2433 and path should be relative; path will then be relative to that directory.\n\
2434If effective_ids is True, access will use the effective uid/gid instead of\n\
2435 the real uid/gid.\n\
2436If follow_symlinks is False, and the last element of the path is a symbolic\n\
2437 link, access will examine the symbolic link itself instead of the file the\n\
2438 link points to.\n\
2439dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2440 on your platform. If they are unavailable, using them will raise a\n\
2441 NotImplementedError.\n\
2442\n\
2443Note that most operations will use the effective uid/gid, therefore this\n\
2444 routine can be used in a suid/sgid environment to test if the invoking user\n\
2445 has the specified access to the path.\n\
2446The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2447 of R_OK, W_OK, and X_OK.");
2448
2449static PyObject *
2450posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2451{
2452 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2453 "follow_symlinks", NULL};
2454 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002455 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002456 int dir_fd = DEFAULT_DIR_FD;
2457 int effective_ids = 0;
2458 int follow_symlinks = 1;
2459 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002460
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002461#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002462 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002463#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002464 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002465#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002466
2467 memset(&path, 0, sizeof(path));
2468 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2469 path_converter, &path, &mode,
2470#ifdef HAVE_FACCESSAT
2471 dir_fd_converter, &dir_fd,
2472#else
2473 dir_fd_unavailable, &dir_fd,
2474#endif
2475 &effective_ids, &follow_symlinks))
2476 return NULL;
2477
2478#ifndef HAVE_FACCESSAT
2479 if (follow_symlinks_specified("access", follow_symlinks))
2480 goto exit;
2481
2482 if (effective_ids) {
2483 argument_unavailable_error("access", "effective_ids");
2484 goto exit;
2485 }
2486#endif
2487
2488#ifdef MS_WINDOWS
2489 Py_BEGIN_ALLOW_THREADS
2490 if (path.wide != NULL)
2491 attr = GetFileAttributesW(path.wide);
2492 else
2493 attr = GetFileAttributesA(path.narrow);
2494 Py_END_ALLOW_THREADS
2495
2496 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002497 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498 * * we didn't get a -1, and
2499 * * write access wasn't requested,
2500 * * or the file isn't read-only,
2501 * * or it's a directory.
2502 * (Directories cannot be read-only on Windows.)
2503 */
2504 return_value = PyBool_FromLong(
2505 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002506 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002507 !(attr & FILE_ATTRIBUTE_READONLY) ||
2508 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2509#else
2510
2511 Py_BEGIN_ALLOW_THREADS
2512#ifdef HAVE_FACCESSAT
2513 if ((dir_fd != DEFAULT_DIR_FD) ||
2514 effective_ids ||
2515 !follow_symlinks) {
2516 int flags = 0;
2517 if (!follow_symlinks)
2518 flags |= AT_SYMLINK_NOFOLLOW;
2519 if (effective_ids)
2520 flags |= AT_EACCESS;
2521 result = faccessat(dir_fd, path.narrow, mode, flags);
2522 }
2523 else
2524#endif
2525 result = access(path.narrow, mode);
2526 Py_END_ALLOW_THREADS
2527 return_value = PyBool_FromLong(!result);
2528#endif
2529
2530#ifndef HAVE_FACCESSAT
2531exit:
2532#endif
2533 path_cleanup(&path);
2534 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002535}
2536
Guido van Rossumd371ff11999-01-25 16:12:23 +00002537#ifndef F_OK
2538#define F_OK 0
2539#endif
2540#ifndef R_OK
2541#define R_OK 4
2542#endif
2543#ifndef W_OK
2544#define W_OK 2
2545#endif
2546#ifndef X_OK
2547#define X_OK 1
2548#endif
2549
2550#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002551PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002552"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002553Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002554
2555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002556posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002557{
Victor Stinner8c62be82010-05-06 00:08:46 +00002558 int id;
2559 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002560
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2562 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002563
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002564#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 /* file descriptor 0 only, the default input device (stdin) */
2566 if (id == 0) {
2567 ret = ttyname();
2568 }
2569 else {
2570 ret = NULL;
2571 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002572#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002574#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002575 if (ret == NULL)
2576 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002577 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002578}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002579#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002580
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002581#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002582PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002583"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002584Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002585
2586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002587posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002588{
Victor Stinner8c62be82010-05-06 00:08:46 +00002589 char *ret;
2590 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002591
Greg Wardb48bc172000-03-01 21:51:56 +00002592#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002594#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002596#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 if (ret == NULL)
2598 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002599 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002600}
2601#endif
2602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002604"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605Change the current working directory to the specified path.\n\
2606\n\
2607path may always be specified as a string.\n\
2608On some platforms, path may also be specified as an open file descriptor.\n\
2609 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Barry Warsaw53699e91996-12-10 23:23:01 +00002611static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002613{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002614 path_t path;
2615 int result;
2616 PyObject *return_value = NULL;
2617 static char *keywords[] = {"path", NULL};
2618
2619 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002620 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621#ifdef HAVE_FCHDIR
2622 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002623#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2625 path_converter, &path
2626 ))
2627 return NULL;
2628
2629 Py_BEGIN_ALLOW_THREADS
2630#ifdef MS_WINDOWS
2631 if (path.wide)
2632 result = win32_wchdir(path.wide);
2633 else
2634 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002635 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636#else
2637#ifdef HAVE_FCHDIR
2638 if (path.fd != -1)
2639 result = fchdir(path.fd);
2640 else
2641#endif
2642 result = chdir(path.narrow);
2643#endif
2644 Py_END_ALLOW_THREADS
2645
2646 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002647 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648 goto exit;
2649 }
2650
2651 return_value = Py_None;
2652 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002653
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654exit:
2655 path_cleanup(&path);
2656 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657}
2658
Fred Drake4d1e64b2002-04-15 19:40:07 +00002659#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002660PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002661"fchdir(fd)\n\n\
2662Change to the directory of the given file descriptor. fd must be\n\
2663opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002664
2665static PyObject *
2666posix_fchdir(PyObject *self, PyObject *fdobj)
2667{
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002669}
2670#endif /* HAVE_FCHDIR */
2671
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002673PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2675Change the access permissions of a file.\n\
2676\n\
2677path may always be specified as a string.\n\
2678On some platforms, path may also be specified as an open file descriptor.\n\
2679 If this functionality is unavailable, using it raises an exception.\n\
2680If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2681 and path should be relative; path will then be relative to that directory.\n\
2682If follow_symlinks is False, and the last element of the path is a symbolic\n\
2683 link, chmod will modify the symbolic link itself instead of the file the\n\
2684 link points to.\n\
2685It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2686 an open file descriptor.\n\
2687dir_fd and follow_symlinks may not be implemented on your platform.\n\
2688 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002689
Barry Warsaw53699e91996-12-10 23:23:01 +00002690static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002691posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002692{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002693 path_t path;
2694 int mode;
2695 int dir_fd = DEFAULT_DIR_FD;
2696 int follow_symlinks = 1;
2697 int result;
2698 PyObject *return_value = NULL;
2699 static char *keywords[] = {"path", "mode", "dir_fd",
2700 "follow_symlinks", NULL};
2701
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002702#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002703 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002705
Larry Hastings9cf065c2012-06-22 16:30:09 -07002706#ifdef HAVE_FCHMODAT
2707 int fchmodat_nofollow_unsupported = 0;
2708#endif
2709
2710 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002711 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#ifdef HAVE_FCHMOD
2713 path.allow_fd = 1;
2714#endif
2715 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2716 path_converter, &path,
2717 &mode,
2718#ifdef HAVE_FCHMODAT
2719 dir_fd_converter, &dir_fd,
2720#else
2721 dir_fd_unavailable, &dir_fd,
2722#endif
2723 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002724 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002725
2726#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2727 if (follow_symlinks_specified("chmod", follow_symlinks))
2728 goto exit;
2729#endif
2730
2731#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002732 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 if (path.wide)
2734 attr = GetFileAttributesW(path.wide);
2735 else
2736 attr = GetFileAttributesA(path.narrow);
2737 if (attr == 0xFFFFFFFF)
2738 result = 0;
2739 else {
2740 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002741 attr &= ~FILE_ATTRIBUTE_READONLY;
2742 else
2743 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002744 if (path.wide)
2745 result = SetFileAttributesW(path.wide, attr);
2746 else
2747 result = SetFileAttributesA(path.narrow, attr);
2748 }
2749 Py_END_ALLOW_THREADS
2750
2751 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002752 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753 goto exit;
2754 }
2755#else /* MS_WINDOWS */
2756 Py_BEGIN_ALLOW_THREADS
2757#ifdef HAVE_FCHMOD
2758 if (path.fd != -1)
2759 result = fchmod(path.fd, mode);
2760 else
2761#endif
2762#ifdef HAVE_LCHMOD
2763 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2764 result = lchmod(path.narrow, mode);
2765 else
2766#endif
2767#ifdef HAVE_FCHMODAT
2768 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2769 /*
2770 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2771 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002772 * and then says it isn't implemented yet.
2773 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 *
2775 * Once it is supported, os.chmod will automatically
2776 * support dir_fd and follow_symlinks=False. (Hopefully.)
2777 * Until then, we need to be careful what exception we raise.
2778 */
2779 result = fchmodat(dir_fd, path.narrow, mode,
2780 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2781 /*
2782 * But wait! We can't throw the exception without allowing threads,
2783 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2784 */
2785 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002786 result &&
2787 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2788 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002789 }
2790 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002791#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792 result = chmod(path.narrow, mode);
2793 Py_END_ALLOW_THREADS
2794
2795 if (result) {
2796#ifdef HAVE_FCHMODAT
2797 if (fchmodat_nofollow_unsupported) {
2798 if (dir_fd != DEFAULT_DIR_FD)
2799 dir_fd_and_follow_symlinks_invalid("chmod",
2800 dir_fd, follow_symlinks);
2801 else
2802 follow_symlinks_specified("chmod", follow_symlinks);
2803 }
2804 else
2805#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002806 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 goto exit;
2808 }
2809#endif
2810
2811 Py_INCREF(Py_None);
2812 return_value = Py_None;
2813exit:
2814 path_cleanup(&path);
2815 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002816}
2817
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818
Christian Heimes4e30a842007-11-30 22:12:06 +00002819#ifdef HAVE_FCHMOD
2820PyDoc_STRVAR(posix_fchmod__doc__,
2821"fchmod(fd, mode)\n\n\
2822Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002824
2825static PyObject *
2826posix_fchmod(PyObject *self, PyObject *args)
2827{
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 int fd, mode, res;
2829 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2830 return NULL;
2831 Py_BEGIN_ALLOW_THREADS
2832 res = fchmod(fd, mode);
2833 Py_END_ALLOW_THREADS
2834 if (res < 0)
2835 return posix_error();
2836 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002837}
2838#endif /* HAVE_FCHMOD */
2839
2840#ifdef HAVE_LCHMOD
2841PyDoc_STRVAR(posix_lchmod__doc__,
2842"lchmod(path, mode)\n\n\
2843Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844affects the link itself rather than the target.\n\
2845Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002846
2847static PyObject *
2848posix_lchmod(PyObject *self, PyObject *args)
2849{
Victor Stinner292c8352012-10-30 02:17:38 +01002850 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 int i;
2852 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002853 memset(&path, 0, sizeof(path));
2854 path.function_name = "lchmod";
2855 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2856 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002859 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002860 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002861 if (res < 0) {
2862 path_error(&path);
2863 path_cleanup(&path);
2864 return NULL;
2865 }
2866 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002867 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002868}
2869#endif /* HAVE_LCHMOD */
2870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002871
Thomas Wouterscf297e42007-02-23 15:07:44 +00002872#ifdef HAVE_CHFLAGS
2873PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874"chflags(path, flags, *, follow_symlinks=True)\n\n\
2875Set file flags.\n\
2876\n\
2877If follow_symlinks is False, and the last element of the path is a symbolic\n\
2878 link, chflags will change flags on the symbolic link itself instead of the\n\
2879 file the link points to.\n\
2880follow_symlinks may not be implemented on your platform. If it is\n\
2881unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002882
2883static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002885{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888 int follow_symlinks = 1;
2889 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02002890 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2892
2893 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002894 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2896 path_converter, &path,
2897 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002898 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899
2900#ifndef HAVE_LCHFLAGS
2901 if (follow_symlinks_specified("chflags", follow_symlinks))
2902 goto exit;
2903#endif
2904
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906#ifdef HAVE_LCHFLAGS
2907 if (!follow_symlinks)
2908 result = lchflags(path.narrow, flags);
2909 else
2910#endif
2911 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002912 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913
2914 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002915 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916 goto exit;
2917 }
2918
2919 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921
2922exit:
2923 path_cleanup(&path);
2924 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002925}
2926#endif /* HAVE_CHFLAGS */
2927
2928#ifdef HAVE_LCHFLAGS
2929PyDoc_STRVAR(posix_lchflags__doc__,
2930"lchflags(path, flags)\n\n\
2931Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002932This function will not follow symbolic links.\n\
2933Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002934
2935static PyObject *
2936posix_lchflags(PyObject *self, PyObject *args)
2937{
Victor Stinner292c8352012-10-30 02:17:38 +01002938 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 unsigned long flags;
2940 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002941 memset(&path, 0, sizeof(path));
2942 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002944 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002945 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002947 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002949 if (res < 0) {
2950 path_error(&path);
2951 path_cleanup(&path);
2952 return NULL;
2953 }
2954 path_cleanup(&path);
2955 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002956}
2957#endif /* HAVE_LCHFLAGS */
2958
Martin v. Löwis244edc82001-10-04 22:44:26 +00002959#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002960PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002961"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002962Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002963
2964static PyObject *
2965posix_chroot(PyObject *self, PyObject *args)
2966{
Victor Stinner292c8352012-10-30 02:17:38 +01002967 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002968}
2969#endif
2970
Guido van Rossum21142a01999-01-08 21:05:37 +00002971#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002972PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002973"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002974force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002975
2976static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002977posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002978{
Stefan Krah0e803b32010-11-26 16:16:47 +00002979 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002980}
2981#endif /* HAVE_FSYNC */
2982
Ross Lagerwall7807c352011-03-17 20:20:30 +02002983#ifdef HAVE_SYNC
2984PyDoc_STRVAR(posix_sync__doc__,
2985"sync()\n\n\
2986Force write of everything to disk.");
2987
2988static PyObject *
2989posix_sync(PyObject *self, PyObject *noargs)
2990{
2991 Py_BEGIN_ALLOW_THREADS
2992 sync();
2993 Py_END_ALLOW_THREADS
2994 Py_RETURN_NONE;
2995}
2996#endif
2997
Guido van Rossum21142a01999-01-08 21:05:37 +00002998#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002999
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003000#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003001extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3002#endif
3003
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003004PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003005"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003006force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003007 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003008
3009static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003010posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003011{
Stefan Krah0e803b32010-11-26 16:16:47 +00003012 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003013}
3014#endif /* HAVE_FDATASYNC */
3015
3016
Fredrik Lundh10723342000-07-10 16:38:09 +00003017#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003019"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3020Change the owner and group id of path to the numeric uid and gid.\n\
3021\n\
3022path may always be specified as a string.\n\
3023On some platforms, path may also be specified as an open file descriptor.\n\
3024 If this functionality is unavailable, using it raises an exception.\n\
3025If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3026 and path should be relative; path will then be relative to that directory.\n\
3027If follow_symlinks is False, and the last element of the path is a symbolic\n\
3028 link, chown will modify the symbolic link itself instead of the file the\n\
3029 link points to.\n\
3030It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3031 an open file descriptor.\n\
3032dir_fd and follow_symlinks may not be implemented on your platform.\n\
3033 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003034
Barry Warsaw53699e91996-12-10 23:23:01 +00003035static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003036posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003037{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003039 uid_t uid;
3040 gid_t gid;
3041 int dir_fd = DEFAULT_DIR_FD;
3042 int follow_symlinks = 1;
3043 int result;
3044 PyObject *return_value = NULL;
3045 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3046 "follow_symlinks", NULL};
3047
3048 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003049 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050#ifdef HAVE_FCHOWN
3051 path.allow_fd = 1;
3052#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003053 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003054 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003055 _Py_Uid_Converter, &uid,
3056 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003057#ifdef HAVE_FCHOWNAT
3058 dir_fd_converter, &dir_fd,
3059#else
3060 dir_fd_unavailable, &dir_fd,
3061#endif
3062 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003063 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064
3065#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3066 if (follow_symlinks_specified("chown", follow_symlinks))
3067 goto exit;
3068#endif
3069 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3070 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3071 goto exit;
3072
3073#ifdef __APPLE__
3074 /*
3075 * This is for Mac OS X 10.3, which doesn't have lchown.
3076 * (But we still have an lchown symbol because of weak-linking.)
3077 * It doesn't have fchownat either. So there's no possibility
3078 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003079 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080 if ((!follow_symlinks) && (lchown == NULL)) {
3081 follow_symlinks_specified("chown", follow_symlinks);
3082 goto exit;
3083 }
3084#endif
3085
Victor Stinner8c62be82010-05-06 00:08:46 +00003086 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087#ifdef HAVE_FCHOWN
3088 if (path.fd != -1)
3089 result = fchown(path.fd, uid, gid);
3090 else
3091#endif
3092#ifdef HAVE_LCHOWN
3093 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3094 result = lchown(path.narrow, uid, gid);
3095 else
3096#endif
3097#ifdef HAVE_FCHOWNAT
3098 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3099 result = fchownat(dir_fd, path.narrow, uid, gid,
3100 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3101 else
3102#endif
3103 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105
3106 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003107 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108 goto exit;
3109 }
3110
3111 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113
3114exit:
3115 path_cleanup(&path);
3116 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003118#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119
Christian Heimes4e30a842007-11-30 22:12:06 +00003120#ifdef HAVE_FCHOWN
3121PyDoc_STRVAR(posix_fchown__doc__,
3122"fchown(fd, uid, gid)\n\n\
3123Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003125
3126static PyObject *
3127posix_fchown(PyObject *self, PyObject *args)
3128{
Victor Stinner8c62be82010-05-06 00:08:46 +00003129 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003130 uid_t uid;
3131 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003132 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003133 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3134 _Py_Uid_Converter, &uid,
3135 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003136 return NULL;
3137 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003138 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 Py_END_ALLOW_THREADS
3140 if (res < 0)
3141 return posix_error();
3142 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003143}
3144#endif /* HAVE_FCHOWN */
3145
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003146#ifdef HAVE_LCHOWN
3147PyDoc_STRVAR(posix_lchown__doc__,
3148"lchown(path, uid, gid)\n\n\
3149Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150This function will not follow symbolic links.\n\
3151Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003152
3153static PyObject *
3154posix_lchown(PyObject *self, PyObject *args)
3155{
Victor Stinner292c8352012-10-30 02:17:38 +01003156 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003157 uid_t uid;
3158 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003160 memset(&path, 0, sizeof(path));
3161 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003162 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003163 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003164 _Py_Uid_Converter, &uid,
3165 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003167 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003168 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003169 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003170 if (res < 0) {
3171 path_error(&path);
3172 path_cleanup(&path);
3173 return NULL;
3174 }
3175 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 Py_INCREF(Py_None);
3177 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003178}
3179#endif /* HAVE_LCHOWN */
3180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Guido van Rossum36bc6801995-06-14 22:54:23 +00003182#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003183static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003184posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003185{
Victor Stinner8c62be82010-05-06 00:08:46 +00003186 char buf[1026];
3187 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003188
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003189#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 if (!use_bytes) {
3191 wchar_t wbuf[1026];
3192 wchar_t *wbuf2 = wbuf;
3193 PyObject *resobj;
3194 DWORD len;
3195 Py_BEGIN_ALLOW_THREADS
3196 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3197 /* If the buffer is large enough, len does not include the
3198 terminating \0. If the buffer is too small, len includes
3199 the space needed for the terminator. */
3200 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003201 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 if (wbuf2)
3203 len = GetCurrentDirectoryW(len, wbuf2);
3204 }
3205 Py_END_ALLOW_THREADS
3206 if (!wbuf2) {
3207 PyErr_NoMemory();
3208 return NULL;
3209 }
3210 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003211 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003212 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003213 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 }
3215 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003216 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003217 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 return resobj;
3219 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003220
3221 if (win32_warn_bytes_api())
3222 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003223#endif
3224
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 Py_END_ALLOW_THREADS
3228 if (res == NULL)
3229 return posix_error();
3230 if (use_bytes)
3231 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003232 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003233}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003234
3235PyDoc_STRVAR(posix_getcwd__doc__,
3236"getcwd() -> path\n\n\
3237Return a unicode string representing the current working directory.");
3238
3239static PyObject *
3240posix_getcwd_unicode(PyObject *self)
3241{
3242 return posix_getcwd(0);
3243}
3244
3245PyDoc_STRVAR(posix_getcwdb__doc__,
3246"getcwdb() -> path\n\n\
3247Return a bytes string representing the current working directory.");
3248
3249static PyObject *
3250posix_getcwd_bytes(PyObject *self)
3251{
3252 return posix_getcwd(1);
3253}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003254#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003255
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3257#define HAVE_LINK 1
3258#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003259
Guido van Rossumb6775db1994-08-01 11:34:53 +00003260#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003261PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003262"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3263Create a hard link to a file.\n\
3264\n\
3265If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3266 descriptor open to a directory, and the respective path string (src or dst)\n\
3267 should be relative; the path will then be relative to that directory.\n\
3268If follow_symlinks is False, and the last element of src is a symbolic\n\
3269 link, link will create a link to the symbolic link itself instead of the\n\
3270 file the link points to.\n\
3271src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3272 platform. If they are unavailable, using them will raise a\n\
3273 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003274
Barry Warsaw53699e91996-12-10 23:23:01 +00003275static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003276posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003277{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003278 path_t src, dst;
3279 int src_dir_fd = DEFAULT_DIR_FD;
3280 int dst_dir_fd = DEFAULT_DIR_FD;
3281 int follow_symlinks = 1;
3282 PyObject *return_value = NULL;
3283 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3284 "follow_symlinks", NULL};
3285#ifdef MS_WINDOWS
3286 BOOL result;
3287#else
3288 int result;
3289#endif
3290
3291 memset(&src, 0, sizeof(src));
3292 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003293 src.function_name = "link";
3294 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3296 path_converter, &src,
3297 path_converter, &dst,
3298 dir_fd_converter, &src_dir_fd,
3299 dir_fd_converter, &dst_dir_fd,
3300 &follow_symlinks))
3301 return NULL;
3302
3303#ifndef HAVE_LINKAT
3304 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3305 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3306 goto exit;
3307 }
3308#endif
3309
3310 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3311 PyErr_SetString(PyExc_NotImplementedError,
3312 "link: src and dst must be the same type");
3313 goto exit;
3314 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003315
Brian Curtin1b9df392010-11-24 20:24:31 +00003316#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317 Py_BEGIN_ALLOW_THREADS
3318 if (src.wide)
3319 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3320 else
3321 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3322 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003323
Larry Hastings9cf065c2012-06-22 16:30:09 -07003324 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003325 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003326 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003327 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328#else
3329 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003330#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3332 (dst_dir_fd != DEFAULT_DIR_FD) ||
3333 (!follow_symlinks))
3334 result = linkat(src_dir_fd, src.narrow,
3335 dst_dir_fd, dst.narrow,
3336 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3337 else
3338#endif
3339 result = link(src.narrow, dst.narrow);
3340 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003341
Larry Hastings9cf065c2012-06-22 16:30:09 -07003342 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003343 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003345 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346#endif
3347
3348 return_value = Py_None;
3349 Py_INCREF(Py_None);
3350
3351exit:
3352 path_cleanup(&src);
3353 path_cleanup(&dst);
3354 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003355}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356#endif
3357
Brian Curtin1b9df392010-11-24 20:24:31 +00003358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003359
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003360PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003361"listdir(path='.') -> list_of_filenames\n\n\
3362Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003363The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364entries '.' and '..' even if they are present in the directory.\n\
3365\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003366path can be specified as either str or bytes. If path is bytes,\n\
3367 the filenames returned will also be bytes; in all other circumstances\n\
3368 the filenames returned will be str.\n\
3369On some platforms, path may also be specified as an open file descriptor;\n\
3370 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003372
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003373#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003374static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003375_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003376{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378 PyObject *v;
3379 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3380 BOOL result;
3381 WIN32_FIND_DATA FileData;
3382 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3383 char *bufptr = namebuf;
3384 /* only claim to have space for MAX_PATH */
3385 Py_ssize_t len = sizeof(namebuf)-5;
3386 PyObject *po = NULL;
3387 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388
Gregory P. Smith40a21602013-03-20 20:52:50 -07003389 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003392
Gregory P. Smith40a21602013-03-20 20:52:50 -07003393 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003394 po_wchars = L".";
3395 len = 1;
3396 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003397 po_wchars = path->wide;
3398 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003399 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003401 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 if (!wnamebuf) {
3403 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003406 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003408 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 if (wch != L'/' && wch != L'\\' && wch != L':')
3410 wnamebuf[len++] = L'\\';
3411 wcscpy(wnamebuf + len, L"*.*");
3412 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413 if ((list = PyList_New(0)) == NULL) {
3414 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003416 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003418 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 if (hFindFile == INVALID_HANDLE_VALUE) {
3420 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 if (error == ERROR_FILE_NOT_FOUND)
3422 goto exit;
3423 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003424 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 }
3427 do {
3428 /* Skip over . and .. */
3429 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3430 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 v = PyUnicode_FromWideChar(wFileData.cFileName,
3432 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_DECREF(list);
3435 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 break;
3437 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 Py_DECREF(list);
3441 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 break;
3443 }
3444 Py_DECREF(v);
3445 }
3446 Py_BEGIN_ALLOW_THREADS
3447 result = FindNextFileW(hFindFile, &wFileData);
3448 Py_END_ALLOW_THREADS
3449 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3450 it got to the end of the directory. */
3451 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003453 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 }
3456 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003457
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003460 strcpy(namebuf, path->narrow);
3461 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 if (len > 0) {
3463 char ch = namebuf[len-1];
3464 if (ch != SEP && ch != ALTSEP && ch != ':')
3465 namebuf[len++] = '/';
3466 strcpy(namebuf + len, "*.*");
3467 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003468
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003471
Antoine Pitroub73caab2010-08-09 23:39:31 +00003472 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003473 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003474 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 if (hFindFile == INVALID_HANDLE_VALUE) {
3476 int error = GetLastError();
3477 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 goto exit;
3479 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003480 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 }
3483 do {
3484 /* Skip over . and .. */
3485 if (strcmp(FileData.cFileName, ".") != 0 &&
3486 strcmp(FileData.cFileName, "..") != 0) {
3487 v = PyBytes_FromString(FileData.cFileName);
3488 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 Py_DECREF(list);
3490 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 break;
3492 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 Py_DECREF(list);
3496 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 break;
3498 }
3499 Py_DECREF(v);
3500 }
3501 Py_BEGIN_ALLOW_THREADS
3502 result = FindNextFile(hFindFile, &FileData);
3503 Py_END_ALLOW_THREADS
3504 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3505 it got to the end of the directory. */
3506 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003508 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 }
3511 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003512
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513exit:
3514 if (hFindFile != INVALID_HANDLE_VALUE) {
3515 if (FindClose(hFindFile) == FALSE) {
3516 if (list != NULL) {
3517 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003518 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 }
3520 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003522 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003523
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003525} /* end of _listdir_windows_no_opendir */
3526
3527#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3528
3529static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003530_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003531{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003532 PyObject *v;
3533 DIR *dirp = NULL;
3534 struct dirent *ep;
3535 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003536#ifdef HAVE_FDOPENDIR
3537 int fd = -1;
3538#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003542 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003544 Py_BEGIN_ALLOW_THREADS
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 fd = dup(path->fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003546 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547
3548 if (fd == -1) {
3549 list = posix_error();
3550 goto exit;
3551 }
3552
Larry Hastingsfdaea062012-06-25 04:42:23 -07003553 return_str = 1;
3554
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 Py_BEGIN_ALLOW_THREADS
3556 dirp = fdopendir(fd);
3557 Py_END_ALLOW_THREADS
3558 }
3559 else
3560#endif
3561 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003562 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003563 if (path->narrow) {
3564 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003565 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003566 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003567 }
3568 else {
3569 name = ".";
3570 return_str = 1;
3571 }
3572
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 Py_BEGIN_ALLOW_THREADS
3574 dirp = opendir(name);
3575 Py_END_ALLOW_THREADS
3576 }
3577
3578 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003579 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003580#ifdef HAVE_FDOPENDIR
3581 if (fd != -1) {
3582 Py_BEGIN_ALLOW_THREADS
3583 close(fd);
3584 Py_END_ALLOW_THREADS
3585 }
3586#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 goto exit;
3588 }
3589 if ((list = PyList_New(0)) == NULL) {
3590 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 }
3592 for (;;) {
3593 errno = 0;
3594 Py_BEGIN_ALLOW_THREADS
3595 ep = readdir(dirp);
3596 Py_END_ALLOW_THREADS
3597 if (ep == NULL) {
3598 if (errno == 0) {
3599 break;
3600 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003602 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 }
3605 }
3606 if (ep->d_name[0] == '.' &&
3607 (NAMLEN(ep) == 1 ||
3608 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3609 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003610 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003611 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3612 else
3613 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 break;
3617 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 break;
3622 }
3623 Py_DECREF(v);
3624 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003625
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626exit:
3627 if (dirp != NULL) {
3628 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003629#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 if (fd > -1)
3631 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003632#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 closedir(dirp);
3634 Py_END_ALLOW_THREADS
3635 }
3636
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003638} /* end of _posix_listdir */
3639#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003640
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003641static PyObject *
3642posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3643{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003644 path_t path;
3645 PyObject *list = NULL;
3646 static char *keywords[] = {"path", NULL};
3647 PyObject *return_value;
3648
3649 memset(&path, 0, sizeof(path));
3650 path.function_name = "listdir";
3651 path.nullable = 1;
3652#ifdef HAVE_FDOPENDIR
3653 path.allow_fd = 1;
3654 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003655#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003656
3657 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3658 path_converter, &path)) {
3659 return NULL;
3660 }
3661
3662#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3663 return_value = _listdir_windows_no_opendir(&path, list);
3664#else
3665 return_value = _posix_listdir(&path, list);
3666#endif
3667 path_cleanup(&path);
3668 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003669}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003670
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003671#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003672/* A helper function for abspath on win32 */
3673static PyObject *
3674posix__getfullpathname(PyObject *self, PyObject *args)
3675{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003676 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 char outbuf[MAX_PATH*2];
3678 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003679 PyObject *po;
3680
3681 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3682 {
3683 wchar_t *wpath;
3684 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3685 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 DWORD result;
3687 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003688
3689 wpath = PyUnicode_AsUnicode(po);
3690 if (wpath == NULL)
3691 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003693 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003695 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003696 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 if (!woutbufp)
3698 return PyErr_NoMemory();
3699 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3700 }
3701 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003702 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003704 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003706 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 return v;
3708 }
3709 /* Drop the argument parsing error as narrow strings
3710 are also valid. */
3711 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003712
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003713 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3714 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003716 if (win32_warn_bytes_api())
3717 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003718 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 outbuf, &temp)) {
3720 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003721 return NULL;
3722 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3724 return PyUnicode_Decode(outbuf, strlen(outbuf),
3725 Py_FileSystemDefaultEncoding, NULL);
3726 }
3727 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003728} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003729
Brian Curtind25aef52011-06-13 15:16:04 -05003730
Brian Curtinf5e76d02010-11-24 13:14:05 +00003731
Brian Curtind40e6f72010-07-08 21:39:08 +00003732/* A helper function for samepath on windows */
3733static PyObject *
3734posix__getfinalpathname(PyObject *self, PyObject *args)
3735{
3736 HANDLE hFile;
3737 int buf_size;
3738 wchar_t *target_path;
3739 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003741 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003742
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003745 path = PyUnicode_AsUnicode(po);
3746 if (path == NULL)
3747 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003748
3749 if(!check_GetFinalPathNameByHandle()) {
3750 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3751 NotImplementedError. */
3752 return PyErr_Format(PyExc_NotImplementedError,
3753 "GetFinalPathNameByHandle not available on this platform");
3754 }
3755
3756 hFile = CreateFileW(
3757 path,
3758 0, /* desired access */
3759 0, /* share mode */
3760 NULL, /* security attributes */
3761 OPEN_EXISTING,
3762 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3763 FILE_FLAG_BACKUP_SEMANTICS,
3764 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003765
Victor Stinnereb5657a2011-09-30 01:44:27 +02003766 if(hFile == INVALID_HANDLE_VALUE)
3767 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003768
3769 /* We have a good handle to the target, use it to determine the
3770 target path name. */
3771 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3772
3773 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003775
Victor Stinnerb6404912013-07-07 16:21:41 +02003776 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003777 if(!target_path)
3778 return PyErr_NoMemory();
3779
3780 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3781 buf_size, VOLUME_NAME_DOS);
3782 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003783 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003784
3785 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003786 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003787
3788 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003789 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003790 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003791 return result;
3792
3793} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003794
Brian Curtin95d028f2011-06-09 09:10:38 -05003795PyDoc_STRVAR(posix__isdir__doc__,
3796"Return true if the pathname refers to an existing directory.");
3797
Brian Curtin9c669cc2011-06-08 18:17:18 -05003798static PyObject *
3799posix__isdir(PyObject *self, PyObject *args)
3800{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003801 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003802 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003803 DWORD attributes;
3804
3805 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003806 wchar_t *wpath = PyUnicode_AsUnicode(po);
3807 if (wpath == NULL)
3808 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003809
3810 attributes = GetFileAttributesW(wpath);
3811 if (attributes == INVALID_FILE_ATTRIBUTES)
3812 Py_RETURN_FALSE;
3813 goto check;
3814 }
3815 /* Drop the argument parsing error as narrow strings
3816 are also valid. */
3817 PyErr_Clear();
3818
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003819 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003820 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003821 if (win32_warn_bytes_api())
3822 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003823 attributes = GetFileAttributesA(path);
3824 if (attributes == INVALID_FILE_ATTRIBUTES)
3825 Py_RETURN_FALSE;
3826
3827check:
3828 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3829 Py_RETURN_TRUE;
3830 else
3831 Py_RETURN_FALSE;
3832}
Tim Golden6b528062013-08-01 12:44:00 +01003833
3834PyDoc_STRVAR(posix__getvolumepathname__doc__,
3835"Return volume mount point of the specified path.");
3836
3837/* A helper function for ismount on windows */
3838static PyObject *
3839posix__getvolumepathname(PyObject *self, PyObject *args)
3840{
3841 PyObject *po, *result;
3842 wchar_t *path, *mountpath=NULL;
3843 size_t bufsize;
3844 BOOL ret;
3845
3846 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
3847 return NULL;
3848 path = PyUnicode_AsUnicode(po);
3849 if (path == NULL)
3850 return NULL;
3851
3852 /* Volume path should be shorter than entire path */
3853 bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
3854 mountpath = (wchar_t *)PyMem_Malloc(bufsize);
3855 if (mountpath == NULL)
3856 return PyErr_NoMemory();
3857
3858 Py_BEGIN_ALLOW_THREADS
3859 ret = GetVolumePathNameW(path, mountpath, bufsize);
3860 Py_END_ALLOW_THREADS
3861
3862 if (!ret) {
3863 result = win32_error_object("_getvolumepathname", po);
3864 goto exit;
3865 }
3866 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3867
3868exit:
3869 PyMem_Free(mountpath);
3870 return result;
3871}
3872/* end of posix__getvolumepathname */
3873
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003874#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003876PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003877"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3878Create a directory.\n\
3879\n\
3880If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3881 and path should be relative; path will then be relative to that directory.\n\
3882dir_fd may not be implemented on your platform.\n\
3883 If it is unavailable, using it will raise a NotImplementedError.\n\
3884\n\
3885The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Barry Warsaw53699e91996-12-10 23:23:01 +00003887static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003888posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003889{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003890 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003892 int dir_fd = DEFAULT_DIR_FD;
3893 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3894 PyObject *return_value = NULL;
3895 int result;
3896
3897 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003898 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003899 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3900 path_converter, &path, &mode,
3901#ifdef HAVE_MKDIRAT
3902 dir_fd_converter, &dir_fd
3903#else
3904 dir_fd_unavailable, &dir_fd
3905#endif
3906 ))
3907 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003908
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003909#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003911 if (path.wide)
3912 result = CreateDirectoryW(path.wide, NULL);
3913 else
3914 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003916
Larry Hastings9cf065c2012-06-22 16:30:09 -07003917 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003918 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 goto exit;
3920 }
3921#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923#if HAVE_MKDIRAT
3924 if (dir_fd != DEFAULT_DIR_FD)
3925 result = mkdirat(dir_fd, path.narrow, mode);
3926 else
3927#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003928#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003929 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003931 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003932#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003934 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003935 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003936 goto exit;
3937 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003938#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003939 return_value = Py_None;
3940 Py_INCREF(Py_None);
3941exit:
3942 path_cleanup(&path);
3943 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003944}
3945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003946
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003947/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3948#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003949#include <sys/resource.h>
3950#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003951
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003952
3953#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003954PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003955"nice(inc) -> new_priority\n\n\
3956Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003957
Barry Warsaw53699e91996-12-10 23:23:01 +00003958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003959posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003960{
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003962
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3964 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003965
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 /* There are two flavours of 'nice': one that returns the new
3967 priority (as required by almost all standards out there) and the
3968 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3969 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003970
Victor Stinner8c62be82010-05-06 00:08:46 +00003971 If we are of the nice family that returns the new priority, we
3972 need to clear errno before the call, and check if errno is filled
3973 before calling posix_error() on a returnvalue of -1, because the
3974 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003975
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 errno = 0;
3977 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003978#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 if (value == 0)
3980 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003981#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003982 if (value == -1 && errno != 0)
3983 /* either nice() or getpriority() returned an error */
3984 return posix_error();
3985 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003986}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003987#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003988
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003989
3990#ifdef HAVE_GETPRIORITY
3991PyDoc_STRVAR(posix_getpriority__doc__,
3992"getpriority(which, who) -> current_priority\n\n\
3993Get program scheduling priority.");
3994
3995static PyObject *
3996posix_getpriority(PyObject *self, PyObject *args)
3997{
3998 int which, who, retval;
3999
4000 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4001 return NULL;
4002 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004003 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004004 if (errno != 0)
4005 return posix_error();
4006 return PyLong_FromLong((long)retval);
4007}
4008#endif /* HAVE_GETPRIORITY */
4009
4010
4011#ifdef HAVE_SETPRIORITY
4012PyDoc_STRVAR(posix_setpriority__doc__,
4013"setpriority(which, who, prio) -> None\n\n\
4014Set program scheduling priority.");
4015
4016static PyObject *
4017posix_setpriority(PyObject *self, PyObject *args)
4018{
4019 int which, who, prio, retval;
4020
4021 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4022 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004023 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004024 if (retval == -1)
4025 return posix_error();
4026 Py_RETURN_NONE;
4027}
4028#endif /* HAVE_SETPRIORITY */
4029
4030
Barry Warsaw53699e91996-12-10 23:23:01 +00004031static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004032internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004033{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034 char *function_name = is_replace ? "replace" : "rename";
4035 path_t src;
4036 path_t dst;
4037 int src_dir_fd = DEFAULT_DIR_FD;
4038 int dst_dir_fd = DEFAULT_DIR_FD;
4039 int dir_fd_specified;
4040 PyObject *return_value = NULL;
4041 char format[24];
4042 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4043
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004044#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004046 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004047#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004048 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004049#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004050
4051 memset(&src, 0, sizeof(src));
4052 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004053 src.function_name = function_name;
4054 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 strcpy(format, "O&O&|$O&O&:");
4056 strcat(format, function_name);
4057 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4058 path_converter, &src,
4059 path_converter, &dst,
4060 dir_fd_converter, &src_dir_fd,
4061 dir_fd_converter, &dst_dir_fd))
4062 return NULL;
4063
4064 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4065 (dst_dir_fd != DEFAULT_DIR_FD);
4066#ifndef HAVE_RENAMEAT
4067 if (dir_fd_specified) {
4068 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4069 goto exit;
4070 }
4071#endif
4072
4073 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4074 PyErr_Format(PyExc_ValueError,
4075 "%s: src and dst must be the same type", function_name);
4076 goto exit;
4077 }
4078
4079#ifdef MS_WINDOWS
4080 Py_BEGIN_ALLOW_THREADS
4081 if (src.wide)
4082 result = MoveFileExW(src.wide, dst.wide, flags);
4083 else
4084 result = MoveFileExA(src.narrow, dst.narrow, flags);
4085 Py_END_ALLOW_THREADS
4086
4087 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004088 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 goto exit;
4090 }
4091
4092#else
4093 Py_BEGIN_ALLOW_THREADS
4094#ifdef HAVE_RENAMEAT
4095 if (dir_fd_specified)
4096 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4097 else
4098#endif
4099 result = rename(src.narrow, dst.narrow);
4100 Py_END_ALLOW_THREADS
4101
4102 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004103 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 goto exit;
4105 }
4106#endif
4107
4108 Py_INCREF(Py_None);
4109 return_value = Py_None;
4110exit:
4111 path_cleanup(&src);
4112 path_cleanup(&dst);
4113 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004114}
4115
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004116PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004117"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4118Rename a file or directory.\n\
4119\n\
4120If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4121 descriptor open to a directory, and the respective path string (src or dst)\n\
4122 should be relative; the path will then be relative to that directory.\n\
4123src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4124 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004125
4126static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004128{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004130}
4131
4132PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4134Rename a file or directory, overwriting the destination.\n\
4135\n\
4136If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4137 descriptor open to a directory, and the respective path string (src or dst)\n\
4138 should be relative; the path will then be relative to that directory.\n\
4139src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4140 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004141
4142static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004144{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004146}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004148PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004149"rmdir(path, *, dir_fd=None)\n\n\
4150Remove a directory.\n\
4151\n\
4152If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4153 and path should be relative; path will then be relative to that directory.\n\
4154dir_fd may not be implemented on your platform.\n\
4155 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004156
Barry Warsaw53699e91996-12-10 23:23:01 +00004157static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004158posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004159{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004160 path_t path;
4161 int dir_fd = DEFAULT_DIR_FD;
4162 static char *keywords[] = {"path", "dir_fd", NULL};
4163 int result;
4164 PyObject *return_value = NULL;
4165
4166 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004167 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4169 path_converter, &path,
4170#ifdef HAVE_UNLINKAT
4171 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004172#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004173 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004174#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004175 ))
4176 return NULL;
4177
4178 Py_BEGIN_ALLOW_THREADS
4179#ifdef MS_WINDOWS
4180 if (path.wide)
4181 result = RemoveDirectoryW(path.wide);
4182 else
4183 result = RemoveDirectoryA(path.narrow);
4184 result = !result; /* Windows, success=1, UNIX, success=0 */
4185#else
4186#ifdef HAVE_UNLINKAT
4187 if (dir_fd != DEFAULT_DIR_FD)
4188 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4189 else
4190#endif
4191 result = rmdir(path.narrow);
4192#endif
4193 Py_END_ALLOW_THREADS
4194
4195 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004196 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004197 goto exit;
4198 }
4199
4200 return_value = Py_None;
4201 Py_INCREF(Py_None);
4202
4203exit:
4204 path_cleanup(&path);
4205 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004206}
4207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004208
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004209#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004210PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004211"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004212Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004213
Barry Warsaw53699e91996-12-10 23:23:01 +00004214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004215posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004216{
Victor Stinner8c62be82010-05-06 00:08:46 +00004217 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004218#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004219 wchar_t *command;
4220 if (!PyArg_ParseTuple(args, "u:system", &command))
4221 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004222
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 Py_BEGIN_ALLOW_THREADS
4224 sts = _wsystem(command);
4225 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004226#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 PyObject *command_obj;
4228 char *command;
4229 if (!PyArg_ParseTuple(args, "O&:system",
4230 PyUnicode_FSConverter, &command_obj))
4231 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004232
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 command = PyBytes_AsString(command_obj);
4234 Py_BEGIN_ALLOW_THREADS
4235 sts = system(command);
4236 Py_END_ALLOW_THREADS
4237 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004240}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004241#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004243
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004244PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004245"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004246Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004247
Barry Warsaw53699e91996-12-10 23:23:01 +00004248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004249posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004250{
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 int i;
4252 if (!PyArg_ParseTuple(args, "i:umask", &i))
4253 return NULL;
4254 i = (int)umask(i);
4255 if (i < 0)
4256 return posix_error();
4257 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004258}
4259
Brian Curtind40e6f72010-07-08 21:39:08 +00004260#ifdef MS_WINDOWS
4261
4262/* override the default DeleteFileW behavior so that directory
4263symlinks can be removed with this function, the same as with
4264Unix symlinks */
4265BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4266{
4267 WIN32_FILE_ATTRIBUTE_DATA info;
4268 WIN32_FIND_DATAW find_data;
4269 HANDLE find_data_handle;
4270 int is_directory = 0;
4271 int is_link = 0;
4272
4273 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4274 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004275
Brian Curtind40e6f72010-07-08 21:39:08 +00004276 /* Get WIN32_FIND_DATA structure for the path to determine if
4277 it is a symlink */
4278 if(is_directory &&
4279 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4280 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4281
4282 if(find_data_handle != INVALID_HANDLE_VALUE) {
4283 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4284 FindClose(find_data_handle);
4285 }
4286 }
4287 }
4288
4289 if (is_directory && is_link)
4290 return RemoveDirectoryW(lpFileName);
4291
4292 return DeleteFileW(lpFileName);
4293}
4294#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004297"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004298Remove a file (same as remove()).\n\
4299\n\
4300If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4301 and path should be relative; path will then be relative to that directory.\n\
4302dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004303 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004306"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004307Remove a file (same as unlink()).\n\
4308\n\
4309If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4310 and path should be relative; path will then be relative to that directory.\n\
4311dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004312 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004313
Barry Warsaw53699e91996-12-10 23:23:01 +00004314static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004316{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317 path_t path;
4318 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004319 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004320 int result;
4321 PyObject *return_value = NULL;
4322
4323 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004324 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326 path_converter, &path,
4327#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004328 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004329#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004330 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004331#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004332 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004333 return NULL;
4334
4335 Py_BEGIN_ALLOW_THREADS
4336#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004337 if (path.wide)
4338 result = Py_DeleteFileW(path.wide);
4339 else
4340 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341 result = !result; /* Windows, success=1, UNIX, success=0 */
4342#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343#ifdef HAVE_UNLINKAT
4344 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004345 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346 else
4347#endif /* HAVE_UNLINKAT */
4348 result = unlink(path.narrow);
4349#endif
4350 Py_END_ALLOW_THREADS
4351
4352 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004353 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354 goto exit;
4355 }
4356
4357 return_value = Py_None;
4358 Py_INCREF(Py_None);
4359
4360exit:
4361 path_cleanup(&path);
4362 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004363}
4364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004366PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004367"uname() -> uname_result\n\n\
4368Return an object identifying the current operating system.\n\
4369The object behaves like a named tuple with the following fields:\n\
4370 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004371
Larry Hastings605a62d2012-06-24 04:33:36 -07004372static PyStructSequence_Field uname_result_fields[] = {
4373 {"sysname", "operating system name"},
4374 {"nodename", "name of machine on network (implementation-defined)"},
4375 {"release", "operating system release"},
4376 {"version", "operating system version"},
4377 {"machine", "hardware identifier"},
4378 {NULL}
4379};
4380
4381PyDoc_STRVAR(uname_result__doc__,
4382"uname_result: Result from os.uname().\n\n\
4383This object may be accessed either as a tuple of\n\
4384 (sysname, nodename, release, version, machine),\n\
4385or via the attributes sysname, nodename, release, version, and machine.\n\
4386\n\
4387See os.uname for more information.");
4388
4389static PyStructSequence_Desc uname_result_desc = {
4390 "uname_result", /* name */
4391 uname_result__doc__, /* doc */
4392 uname_result_fields,
4393 5
4394};
4395
4396static PyTypeObject UnameResultType;
4397
4398
4399#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004400static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004401posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004402{
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 struct utsname u;
4404 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004405 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004406
Victor Stinner8c62be82010-05-06 00:08:46 +00004407 Py_BEGIN_ALLOW_THREADS
4408 res = uname(&u);
4409 Py_END_ALLOW_THREADS
4410 if (res < 0)
4411 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004412
4413 value = PyStructSequence_New(&UnameResultType);
4414 if (value == NULL)
4415 return NULL;
4416
4417#define SET(i, field) \
4418 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004419 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004420 if (!o) { \
4421 Py_DECREF(value); \
4422 return NULL; \
4423 } \
4424 PyStructSequence_SET_ITEM(value, i, o); \
4425 } \
4426
4427 SET(0, u.sysname);
4428 SET(1, u.nodename);
4429 SET(2, u.release);
4430 SET(3, u.version);
4431 SET(4, u.machine);
4432
4433#undef SET
4434
4435 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004436}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004437#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004438
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004439
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440PyDoc_STRVAR(posix_utime__doc__,
4441"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4442Set the access and modified time of path.\n\
4443\n\
4444path may always be specified as a string.\n\
4445On some platforms, path may also be specified as an open file descriptor.\n\
4446 If this functionality is unavailable, using it raises an exception.\n\
4447\n\
4448If times is not None, it must be a tuple (atime, mtime);\n\
4449 atime and mtime should be expressed as float seconds since the epoch.\n\
4450If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4451 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4452 since the epoch.\n\
4453If both times and ns are None, utime uses the current time.\n\
4454Specifying tuples for both times and ns is an error.\n\
4455\n\
4456If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4457 and path should be relative; path will then be relative to that directory.\n\
4458If follow_symlinks is False, and the last element of the path is a symbolic\n\
4459 link, utime will modify the symbolic link itself instead of the file the\n\
4460 link points to.\n\
4461It is an error to use dir_fd or follow_symlinks when specifying path\n\
4462 as an open file descriptor.\n\
4463dir_fd and follow_symlinks may not be available on your platform.\n\
4464 If they are unavailable, using them will raise a NotImplementedError.");
4465
4466typedef struct {
4467 int now;
4468 time_t atime_s;
4469 long atime_ns;
4470 time_t mtime_s;
4471 long mtime_ns;
4472} utime_t;
4473
4474/*
4475 * these macros assume that "utime" is a pointer to a utime_t
4476 * they also intentionally leak the declaration of a pointer named "time"
4477 */
4478#define UTIME_TO_TIMESPEC \
4479 struct timespec ts[2]; \
4480 struct timespec *time; \
4481 if (utime->now) \
4482 time = NULL; \
4483 else { \
4484 ts[0].tv_sec = utime->atime_s; \
4485 ts[0].tv_nsec = utime->atime_ns; \
4486 ts[1].tv_sec = utime->mtime_s; \
4487 ts[1].tv_nsec = utime->mtime_ns; \
4488 time = ts; \
4489 } \
4490
4491#define UTIME_TO_TIMEVAL \
4492 struct timeval tv[2]; \
4493 struct timeval *time; \
4494 if (utime->now) \
4495 time = NULL; \
4496 else { \
4497 tv[0].tv_sec = utime->atime_s; \
4498 tv[0].tv_usec = utime->atime_ns / 1000; \
4499 tv[1].tv_sec = utime->mtime_s; \
4500 tv[1].tv_usec = utime->mtime_ns / 1000; \
4501 time = tv; \
4502 } \
4503
4504#define UTIME_TO_UTIMBUF \
4505 struct utimbuf u[2]; \
4506 struct utimbuf *time; \
4507 if (utime->now) \
4508 time = NULL; \
4509 else { \
4510 u.actime = utime->atime_s; \
4511 u.modtime = utime->mtime_s; \
4512 time = u; \
4513 }
4514
4515#define UTIME_TO_TIME_T \
4516 time_t timet[2]; \
4517 struct timet time; \
4518 if (utime->now) \
4519 time = NULL; \
4520 else { \
4521 timet[0] = utime->atime_s; \
4522 timet[1] = utime->mtime_s; \
4523 time = &timet; \
4524 } \
4525
4526
4527#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4528
4529#if UTIME_HAVE_DIR_FD
4530
4531static int
4532utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4533{
4534#ifdef HAVE_UTIMENSAT
4535 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4536 UTIME_TO_TIMESPEC;
4537 return utimensat(dir_fd, path, time, flags);
4538#elif defined(HAVE_FUTIMESAT)
4539 UTIME_TO_TIMEVAL;
4540 /*
4541 * follow_symlinks will never be false here;
4542 * we only allow !follow_symlinks and dir_fd together
4543 * if we have utimensat()
4544 */
4545 assert(follow_symlinks);
4546 return futimesat(dir_fd, path, time);
4547#endif
4548}
4549
4550#endif
4551
4552#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4553
4554#if UTIME_HAVE_FD
4555
4556static int
4557utime_fd(utime_t *utime, int fd)
4558{
4559#ifdef HAVE_FUTIMENS
4560 UTIME_TO_TIMESPEC;
4561 return futimens(fd, time);
4562#else
4563 UTIME_TO_TIMEVAL;
4564 return futimes(fd, time);
4565#endif
4566}
4567
4568#endif
4569
4570
4571#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4572 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4573
4574#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4575
4576static int
4577utime_nofollow_symlinks(utime_t *utime, char *path)
4578{
4579#ifdef HAVE_UTIMENSAT
4580 UTIME_TO_TIMESPEC;
4581 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4582#else
4583 UTIME_TO_TIMEVAL;
4584 return lutimes(path, time);
4585#endif
4586}
4587
4588#endif
4589
4590#ifndef MS_WINDOWS
4591
4592static int
4593utime_default(utime_t *utime, char *path)
4594{
4595#ifdef HAVE_UTIMENSAT
4596 UTIME_TO_TIMESPEC;
4597 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4598#elif defined(HAVE_UTIMES)
4599 UTIME_TO_TIMEVAL;
4600 return utimes(path, time);
4601#elif defined(HAVE_UTIME_H)
4602 UTIME_TO_UTIMBUF;
4603 return utime(path, time);
4604#else
4605 UTIME_TO_TIME_T;
4606 return utime(path, time);
4607#endif
4608}
4609
4610#endif
4611
Larry Hastings76ad59b2012-05-03 00:30:07 -07004612static int
4613split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4614{
4615 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004616 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004617 divmod = PyNumber_Divmod(py_long, billion);
4618 if (!divmod)
4619 goto exit;
4620 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4621 if ((*s == -1) && PyErr_Occurred())
4622 goto exit;
4623 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004624 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625 goto exit;
4626
4627 result = 1;
4628exit:
4629 Py_XDECREF(divmod);
4630 return result;
4631}
4632
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633static PyObject *
4634posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004635{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 PyObject *times = NULL;
4638 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 int dir_fd = DEFAULT_DIR_FD;
4640 int follow_symlinks = 1;
4641 char *keywords[] = {"path", "times", "ns", "dir_fd",
4642 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004643
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646#ifdef MS_WINDOWS
4647 HANDLE hFile;
4648 FILETIME atime, mtime;
4649#else
4650 int result;
4651#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004654
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004656 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004657 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658#if UTIME_HAVE_FD
4659 path.allow_fd = 1;
4660#endif
4661 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4662 "O&|O$OO&p:utime", keywords,
4663 path_converter, &path,
4664 &times, &ns,
4665#if UTIME_HAVE_DIR_FD
4666 dir_fd_converter, &dir_fd,
4667#else
4668 dir_fd_unavailable, &dir_fd,
4669#endif
4670 &follow_symlinks
4671 ))
4672 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004673
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 if (times && (times != Py_None) && ns) {
4675 PyErr_SetString(PyExc_ValueError,
4676 "utime: you may specify either 'times'"
4677 " or 'ns' but not both");
4678 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004679 }
4680
4681 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004682 time_t a_sec, m_sec;
4683 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004684 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685 PyErr_SetString(PyExc_TypeError,
4686 "utime: 'times' must be either"
4687 " a tuple of two ints or None");
4688 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004689 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004691 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004692 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004693 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004694 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004696 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004697 utime.atime_s = a_sec;
4698 utime.atime_ns = a_nsec;
4699 utime.mtime_s = m_sec;
4700 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704 PyErr_SetString(PyExc_TypeError,
4705 "utime: 'ns' must be a tuple of two ints");
4706 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004707 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004709 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004711 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 &utime.mtime_s, &utime.mtime_ns)) {
4713 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004714 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 }
4716 else {
4717 /* times and ns are both None/unspecified. use "now". */
4718 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719 }
4720
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4722 if (follow_symlinks_specified("utime", follow_symlinks))
4723 goto exit;
4724#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004725
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4727 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4728 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4729 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731#if !defined(HAVE_UTIMENSAT)
4732 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004733 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 "utime: cannot use dir_fd and follow_symlinks "
4735 "together on this platform");
4736 goto exit;
4737 }
4738#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004740#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 Py_BEGIN_ALLOW_THREADS
4742 if (path.wide)
4743 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 NULL, OPEN_EXISTING,
4745 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 else
4747 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004748 NULL, OPEN_EXISTING,
4749 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 Py_END_ALLOW_THREADS
4751 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004752 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004754 }
4755
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 SYSTEMTIME now;
4758 GetSystemTime(&now);
4759 if (!SystemTimeToFileTime(&now, &mtime) ||
4760 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004761 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004763 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004764 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004765 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4767 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004768 }
4769 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4770 /* Avoid putting the file name into the error here,
4771 as that may confuse the user into believing that
4772 something is wrong with the file, when it also
4773 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004774 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004777#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004779
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4781 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4782 result = utime_nofollow_symlinks(&utime, path.narrow);
4783 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004784#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785
4786#if UTIME_HAVE_DIR_FD
4787 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4788 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4789 else
4790#endif
4791
4792#if UTIME_HAVE_FD
4793 if (path.fd != -1)
4794 result = utime_fd(&utime, path.fd);
4795 else
4796#endif
4797
4798 result = utime_default(&utime, path.narrow);
4799
4800 Py_END_ALLOW_THREADS
4801
4802 if (result < 0) {
4803 /* see previous comment about not putting filename in error here */
4804 return_value = posix_error();
4805 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004807
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004808#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809
4810 Py_INCREF(Py_None);
4811 return_value = Py_None;
4812
4813exit:
4814 path_cleanup(&path);
4815#ifdef MS_WINDOWS
4816 if (hFile != INVALID_HANDLE_VALUE)
4817 CloseHandle(hFile);
4818#endif
4819 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004820}
4821
Guido van Rossum3b066191991-06-04 19:40:25 +00004822/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004824PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004825"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004826Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004827
Barry Warsaw53699e91996-12-10 23:23:01 +00004828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004829posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004830{
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 int sts;
4832 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4833 return NULL;
4834 _exit(sts);
4835 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004836}
4837
Martin v. Löwis114619e2002-10-07 06:44:21 +00004838#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4839static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004840free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004841{
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 Py_ssize_t i;
4843 for (i = 0; i < count; i++)
4844 PyMem_Free(array[i]);
4845 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004846}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004847
Antoine Pitrou69f71142009-05-24 21:25:49 +00004848static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004849int fsconvert_strdup(PyObject *o, char**out)
4850{
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 PyObject *bytes;
4852 Py_ssize_t size;
4853 if (!PyUnicode_FSConverter(o, &bytes))
4854 return 0;
4855 size = PyBytes_GET_SIZE(bytes);
4856 *out = PyMem_Malloc(size+1);
4857 if (!*out)
4858 return 0;
4859 memcpy(*out, PyBytes_AsString(bytes), size+1);
4860 Py_DECREF(bytes);
4861 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004862}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004863#endif
4864
Ross Lagerwall7807c352011-03-17 20:20:30 +02004865#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004866static char**
4867parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4868{
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 char **envlist;
4870 Py_ssize_t i, pos, envc;
4871 PyObject *keys=NULL, *vals=NULL;
4872 PyObject *key, *val, *key2, *val2;
4873 char *p, *k, *v;
4874 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004875
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 i = PyMapping_Size(env);
4877 if (i < 0)
4878 return NULL;
4879 envlist = PyMem_NEW(char *, i + 1);
4880 if (envlist == NULL) {
4881 PyErr_NoMemory();
4882 return NULL;
4883 }
4884 envc = 0;
4885 keys = PyMapping_Keys(env);
4886 vals = PyMapping_Values(env);
4887 if (!keys || !vals)
4888 goto error;
4889 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4890 PyErr_Format(PyExc_TypeError,
4891 "env.keys() or env.values() is not a list");
4892 goto error;
4893 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004894
Victor Stinner8c62be82010-05-06 00:08:46 +00004895 for (pos = 0; pos < i; pos++) {
4896 key = PyList_GetItem(keys, pos);
4897 val = PyList_GetItem(vals, pos);
4898 if (!key || !val)
4899 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004900
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 if (PyUnicode_FSConverter(key, &key2) == 0)
4902 goto error;
4903 if (PyUnicode_FSConverter(val, &val2) == 0) {
4904 Py_DECREF(key2);
4905 goto error;
4906 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004907
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 k = PyBytes_AsString(key2);
4909 v = PyBytes_AsString(val2);
4910 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004911
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 p = PyMem_NEW(char, len);
4913 if (p == NULL) {
4914 PyErr_NoMemory();
4915 Py_DECREF(key2);
4916 Py_DECREF(val2);
4917 goto error;
4918 }
4919 PyOS_snprintf(p, len, "%s=%s", k, v);
4920 envlist[envc++] = p;
4921 Py_DECREF(key2);
4922 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 }
4924 Py_DECREF(vals);
4925 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004926
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 envlist[envc] = 0;
4928 *envc_ptr = envc;
4929 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004930
4931error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 Py_XDECREF(keys);
4933 Py_XDECREF(vals);
4934 while (--envc >= 0)
4935 PyMem_DEL(envlist[envc]);
4936 PyMem_DEL(envlist);
4937 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004938}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004939
Ross Lagerwall7807c352011-03-17 20:20:30 +02004940static char**
4941parse_arglist(PyObject* argv, Py_ssize_t *argc)
4942{
4943 int i;
4944 char **argvlist = PyMem_NEW(char *, *argc+1);
4945 if (argvlist == NULL) {
4946 PyErr_NoMemory();
4947 return NULL;
4948 }
4949 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004950 PyObject* item = PySequence_ITEM(argv, i);
4951 if (item == NULL)
4952 goto fail;
4953 if (!fsconvert_strdup(item, &argvlist[i])) {
4954 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004955 goto fail;
4956 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004957 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004958 }
4959 argvlist[*argc] = NULL;
4960 return argvlist;
4961fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004962 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 free_string_array(argvlist, *argc);
4964 return NULL;
4965}
4966#endif
4967
4968#ifdef HAVE_EXECV
4969PyDoc_STRVAR(posix_execv__doc__,
4970"execv(path, args)\n\n\
4971Execute an executable path with arguments, replacing current process.\n\
4972\n\
4973 path: path of executable file\n\
4974 args: tuple or list of strings");
4975
4976static PyObject *
4977posix_execv(PyObject *self, PyObject *args)
4978{
4979 PyObject *opath;
4980 char *path;
4981 PyObject *argv;
4982 char **argvlist;
4983 Py_ssize_t argc;
4984
4985 /* execv has two arguments: (path, argv), where
4986 argv is a list or tuple of strings. */
4987
4988 if (!PyArg_ParseTuple(args, "O&O:execv",
4989 PyUnicode_FSConverter,
4990 &opath, &argv))
4991 return NULL;
4992 path = PyBytes_AsString(opath);
4993 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4994 PyErr_SetString(PyExc_TypeError,
4995 "execv() arg 2 must be a tuple or list");
4996 Py_DECREF(opath);
4997 return NULL;
4998 }
4999 argc = PySequence_Size(argv);
5000 if (argc < 1) {
5001 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5002 Py_DECREF(opath);
5003 return NULL;
5004 }
5005
5006 argvlist = parse_arglist(argv, &argc);
5007 if (argvlist == NULL) {
5008 Py_DECREF(opath);
5009 return NULL;
5010 }
5011
5012 execv(path, argvlist);
5013
5014 /* If we get here it's definitely an error */
5015
5016 free_string_array(argvlist, argc);
5017 Py_DECREF(opath);
5018 return posix_error();
5019}
5020
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005021PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005022"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005023Execute a path with arguments and environment, replacing current process.\n\
5024\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 path: path of executable file\n\
5026 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027 env: dictionary of strings mapping to strings\n\
5028\n\
5029On some platforms, you may specify an open file descriptor for path;\n\
5030 execve will execute the program the file descriptor is open to.\n\
5031 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005032
Barry Warsaw53699e91996-12-10 23:23:01 +00005033static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005035{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005040 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005042
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 /* execve has three arguments: (path, argv, env), where
5044 argv is a list or tuple of strings and env is a dictionary
5045 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005046
Larry Hastings9cf065c2012-06-22 16:30:09 -07005047 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005048 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005049#ifdef HAVE_FEXECVE
5050 path.allow_fd = 1;
5051#endif
5052 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5053 path_converter, &path,
5054 &argv, &env
5055 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005056 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057
Ross Lagerwall7807c352011-03-17 20:20:30 +02005058 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005060 "execve: argv must be a tuple or list");
5061 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 if (!PyMapping_Check(env)) {
5065 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005066 "execve: environment must be a mapping object");
5067 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005069
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005072 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 envlist = parse_envlist(env, &envc);
5076 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077 goto fail;
5078
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079#ifdef HAVE_FEXECVE
5080 if (path.fd > -1)
5081 fexecve(path.fd, argvlist, envlist);
5082 else
5083#endif
5084 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005085
5086 /* If we get here it's definitely an error */
5087
Victor Stinner292c8352012-10-30 02:17:38 +01005088 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005089
5090 while (--envc >= 0)
5091 PyMem_DEL(envlist[envc]);
5092 PyMem_DEL(envlist);
5093 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005094 if (argvlist)
5095 free_string_array(argvlist, argc);
5096 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 return NULL;
5098}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005099#endif /* HAVE_EXECV */
5100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005101
Guido van Rossuma1065681999-01-25 23:20:23 +00005102#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005103PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005104"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005105Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005106\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 mode: mode of process creation\n\
5108 path: path of executable file\n\
5109 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005110
5111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005112posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005113{
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 PyObject *opath;
5115 char *path;
5116 PyObject *argv;
5117 char **argvlist;
5118 int mode, i;
5119 Py_ssize_t argc;
5120 Py_intptr_t spawnval;
5121 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 /* spawnv has three arguments: (mode, path, argv), where
5124 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5127 PyUnicode_FSConverter,
5128 &opath, &argv))
5129 return NULL;
5130 path = PyBytes_AsString(opath);
5131 if (PyList_Check(argv)) {
5132 argc = PyList_Size(argv);
5133 getitem = PyList_GetItem;
5134 }
5135 else if (PyTuple_Check(argv)) {
5136 argc = PyTuple_Size(argv);
5137 getitem = PyTuple_GetItem;
5138 }
5139 else {
5140 PyErr_SetString(PyExc_TypeError,
5141 "spawnv() arg 2 must be a tuple or list");
5142 Py_DECREF(opath);
5143 return NULL;
5144 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005145
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 argvlist = PyMem_NEW(char *, argc+1);
5147 if (argvlist == NULL) {
5148 Py_DECREF(opath);
5149 return PyErr_NoMemory();
5150 }
5151 for (i = 0; i < argc; i++) {
5152 if (!fsconvert_strdup((*getitem)(argv, i),
5153 &argvlist[i])) {
5154 free_string_array(argvlist, i);
5155 PyErr_SetString(
5156 PyExc_TypeError,
5157 "spawnv() arg 2 must contain only strings");
5158 Py_DECREF(opath);
5159 return NULL;
5160 }
5161 }
5162 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 if (mode == _OLD_P_OVERLAY)
5165 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005166
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 Py_BEGIN_ALLOW_THREADS
5168 spawnval = _spawnv(mode, path, argvlist);
5169 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005170
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 free_string_array(argvlist, argc);
5172 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005173
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 if (spawnval == -1)
5175 return posix_error();
5176 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005177 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005178}
5179
5180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005181PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005182"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005183Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005184\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 mode: mode of process creation\n\
5186 path: path of executable file\n\
5187 args: tuple or list of arguments\n\
5188 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
5190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005191posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005192{
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 PyObject *opath;
5194 char *path;
5195 PyObject *argv, *env;
5196 char **argvlist;
5197 char **envlist;
5198 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005199 int mode;
5200 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 Py_intptr_t spawnval;
5202 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5203 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 /* spawnve has four arguments: (mode, path, argv, env), where
5206 argv is a list or tuple of strings and env is a dictionary
5207 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5210 PyUnicode_FSConverter,
5211 &opath, &argv, &env))
5212 return NULL;
5213 path = PyBytes_AsString(opath);
5214 if (PyList_Check(argv)) {
5215 argc = PyList_Size(argv);
5216 getitem = PyList_GetItem;
5217 }
5218 else if (PyTuple_Check(argv)) {
5219 argc = PyTuple_Size(argv);
5220 getitem = PyTuple_GetItem;
5221 }
5222 else {
5223 PyErr_SetString(PyExc_TypeError,
5224 "spawnve() arg 2 must be a tuple or list");
5225 goto fail_0;
5226 }
5227 if (!PyMapping_Check(env)) {
5228 PyErr_SetString(PyExc_TypeError,
5229 "spawnve() arg 3 must be a mapping object");
5230 goto fail_0;
5231 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005232
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 argvlist = PyMem_NEW(char *, argc+1);
5234 if (argvlist == NULL) {
5235 PyErr_NoMemory();
5236 goto fail_0;
5237 }
5238 for (i = 0; i < argc; i++) {
5239 if (!fsconvert_strdup((*getitem)(argv, i),
5240 &argvlist[i]))
5241 {
5242 lastarg = i;
5243 goto fail_1;
5244 }
5245 }
5246 lastarg = argc;
5247 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005248
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 envlist = parse_envlist(env, &envc);
5250 if (envlist == NULL)
5251 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005252
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 if (mode == _OLD_P_OVERLAY)
5254 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005255
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 Py_BEGIN_ALLOW_THREADS
5257 spawnval = _spawnve(mode, path, argvlist, envlist);
5258 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005259
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 if (spawnval == -1)
5261 (void) posix_error();
5262 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005263 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005264
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 while (--envc >= 0)
5266 PyMem_DEL(envlist[envc]);
5267 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005268 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005270 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 Py_DECREF(opath);
5272 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005273}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005274
Guido van Rossuma1065681999-01-25 23:20:23 +00005275#endif /* HAVE_SPAWNV */
5276
5277
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005278#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005279PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005280"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005281Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5282\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005283Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005284
5285static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005286posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005287{
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 pid_t pid;
5289 int result = 0;
5290 _PyImport_AcquireLock();
5291 pid = fork1();
5292 if (pid == 0) {
5293 /* child: this clobbers and resets the import lock. */
5294 PyOS_AfterFork();
5295 } else {
5296 /* parent: release the import lock. */
5297 result = _PyImport_ReleaseLock();
5298 }
5299 if (pid == -1)
5300 return posix_error();
5301 if (result < 0) {
5302 /* Don't clobber the OSError if the fork failed. */
5303 PyErr_SetString(PyExc_RuntimeError,
5304 "not holding the import lock");
5305 return NULL;
5306 }
5307 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005308}
5309#endif
5310
5311
Guido van Rossumad0ee831995-03-01 10:34:45 +00005312#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005313PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005314"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005315Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005317
Barry Warsaw53699e91996-12-10 23:23:01 +00005318static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005319posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005320{
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 pid_t pid;
5322 int result = 0;
5323 _PyImport_AcquireLock();
5324 pid = fork();
5325 if (pid == 0) {
5326 /* child: this clobbers and resets the import lock. */
5327 PyOS_AfterFork();
5328 } else {
5329 /* parent: release the import lock. */
5330 result = _PyImport_ReleaseLock();
5331 }
5332 if (pid == -1)
5333 return posix_error();
5334 if (result < 0) {
5335 /* Don't clobber the OSError if the fork failed. */
5336 PyErr_SetString(PyExc_RuntimeError,
5337 "not holding the import lock");
5338 return NULL;
5339 }
5340 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005341}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005342#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005343
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005344#ifdef HAVE_SCHED_H
5345
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005346#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5347
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005348PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5349"sched_get_priority_max(policy)\n\n\
5350Get the maximum scheduling priority for *policy*.");
5351
5352static PyObject *
5353posix_sched_get_priority_max(PyObject *self, PyObject *args)
5354{
5355 int policy, max;
5356
5357 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5358 return NULL;
5359 max = sched_get_priority_max(policy);
5360 if (max < 0)
5361 return posix_error();
5362 return PyLong_FromLong(max);
5363}
5364
5365PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5366"sched_get_priority_min(policy)\n\n\
5367Get the minimum scheduling priority for *policy*.");
5368
5369static PyObject *
5370posix_sched_get_priority_min(PyObject *self, PyObject *args)
5371{
5372 int policy, min;
5373
5374 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5375 return NULL;
5376 min = sched_get_priority_min(policy);
5377 if (min < 0)
5378 return posix_error();
5379 return PyLong_FromLong(min);
5380}
5381
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005382#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5383
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005384#ifdef HAVE_SCHED_SETSCHEDULER
5385
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005386PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5387"sched_getscheduler(pid)\n\n\
5388Get the scheduling policy for the process with a PID of *pid*.\n\
5389Passing a PID of 0 returns the scheduling policy for the calling process.");
5390
5391static PyObject *
5392posix_sched_getscheduler(PyObject *self, PyObject *args)
5393{
5394 pid_t pid;
5395 int policy;
5396
5397 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5398 return NULL;
5399 policy = sched_getscheduler(pid);
5400 if (policy < 0)
5401 return posix_error();
5402 return PyLong_FromLong(policy);
5403}
5404
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005405#endif
5406
5407#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5408
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005409static PyObject *
5410sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5411{
5412 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005413 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005414
5415 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5416 return NULL;
5417 res = PyStructSequence_New(type);
5418 if (!res)
5419 return NULL;
5420 Py_INCREF(priority);
5421 PyStructSequence_SET_ITEM(res, 0, priority);
5422 return res;
5423}
5424
5425PyDoc_STRVAR(sched_param__doc__,
5426"sched_param(sched_priority): A scheduling parameter.\n\n\
5427Current has only one field: sched_priority");
5428
5429static PyStructSequence_Field sched_param_fields[] = {
5430 {"sched_priority", "the scheduling priority"},
5431 {0}
5432};
5433
5434static PyStructSequence_Desc sched_param_desc = {
5435 "sched_param", /* name */
5436 sched_param__doc__, /* doc */
5437 sched_param_fields,
5438 1
5439};
5440
5441static int
5442convert_sched_param(PyObject *param, struct sched_param *res)
5443{
5444 long priority;
5445
5446 if (Py_TYPE(param) != &SchedParamType) {
5447 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5448 return 0;
5449 }
5450 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5451 if (priority == -1 && PyErr_Occurred())
5452 return 0;
5453 if (priority > INT_MAX || priority < INT_MIN) {
5454 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5455 return 0;
5456 }
5457 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5458 return 1;
5459}
5460
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005461#endif
5462
5463#ifdef HAVE_SCHED_SETSCHEDULER
5464
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5466"sched_setscheduler(pid, policy, param)\n\n\
5467Set the scheduling policy, *policy*, for *pid*.\n\
5468If *pid* is 0, the calling process is changed.\n\
5469*param* is an instance of sched_param.");
5470
5471static PyObject *
5472posix_sched_setscheduler(PyObject *self, PyObject *args)
5473{
5474 pid_t pid;
5475 int policy;
5476 struct sched_param param;
5477
5478 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5479 &pid, &policy, &convert_sched_param, &param))
5480 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005481
5482 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005483 ** sched_setscheduler() returns 0 in Linux, but the previous
5484 ** scheduling policy under Solaris/Illumos, and others.
5485 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005486 */
5487 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005488 return posix_error();
5489 Py_RETURN_NONE;
5490}
5491
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005492#endif
5493
5494#ifdef HAVE_SCHED_SETPARAM
5495
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496PyDoc_STRVAR(posix_sched_getparam__doc__,
5497"sched_getparam(pid) -> sched_param\n\n\
5498Returns scheduling parameters for the process with *pid* as an instance of the\n\
5499sched_param class. A PID of 0 means the calling process.");
5500
5501static PyObject *
5502posix_sched_getparam(PyObject *self, PyObject *args)
5503{
5504 pid_t pid;
5505 struct sched_param param;
5506 PyObject *res, *priority;
5507
5508 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5509 return NULL;
5510 if (sched_getparam(pid, &param))
5511 return posix_error();
5512 res = PyStructSequence_New(&SchedParamType);
5513 if (!res)
5514 return NULL;
5515 priority = PyLong_FromLong(param.sched_priority);
5516 if (!priority) {
5517 Py_DECREF(res);
5518 return NULL;
5519 }
5520 PyStructSequence_SET_ITEM(res, 0, priority);
5521 return res;
5522}
5523
5524PyDoc_STRVAR(posix_sched_setparam__doc__,
5525"sched_setparam(pid, param)\n\n\
5526Set scheduling parameters for a process with PID *pid*.\n\
5527A PID of 0 means the calling process.");
5528
5529static PyObject *
5530posix_sched_setparam(PyObject *self, PyObject *args)
5531{
5532 pid_t pid;
5533 struct sched_param param;
5534
5535 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5536 &pid, &convert_sched_param, &param))
5537 return NULL;
5538 if (sched_setparam(pid, &param))
5539 return posix_error();
5540 Py_RETURN_NONE;
5541}
5542
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005543#endif
5544
5545#ifdef HAVE_SCHED_RR_GET_INTERVAL
5546
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5548"sched_rr_get_interval(pid) -> float\n\n\
5549Return the round-robin quantum for the process with PID *pid* in seconds.");
5550
5551static PyObject *
5552posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5553{
5554 pid_t pid;
5555 struct timespec interval;
5556
5557 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5558 return NULL;
5559 if (sched_rr_get_interval(pid, &interval))
5560 return posix_error();
5561 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5562}
5563
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005564#endif
5565
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005566PyDoc_STRVAR(posix_sched_yield__doc__,
5567"sched_yield()\n\n\
5568Voluntarily relinquish the CPU.");
5569
5570static PyObject *
5571posix_sched_yield(PyObject *self, PyObject *noargs)
5572{
5573 if (sched_yield())
5574 return posix_error();
5575 Py_RETURN_NONE;
5576}
5577
Benjamin Peterson2740af82011-08-02 17:41:34 -05005578#ifdef HAVE_SCHED_SETAFFINITY
5579
Antoine Pitrou84869872012-08-04 16:16:35 +02005580/* The minimum number of CPUs allocated in a cpu_set_t */
5581static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005582
5583PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5584"sched_setaffinity(pid, cpu_set)\n\n\
5585Set the affinity of the process with PID *pid* to *cpu_set*.");
5586
5587static PyObject *
5588posix_sched_setaffinity(PyObject *self, PyObject *args)
5589{
5590 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005591 int ncpus;
5592 size_t setsize;
5593 cpu_set_t *mask = NULL;
5594 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005595
Antoine Pitrou84869872012-08-04 16:16:35 +02005596 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5597 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005598 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005599
5600 iterator = PyObject_GetIter(iterable);
5601 if (iterator == NULL)
5602 return NULL;
5603
5604 ncpus = NCPUS_START;
5605 setsize = CPU_ALLOC_SIZE(ncpus);
5606 mask = CPU_ALLOC(ncpus);
5607 if (mask == NULL) {
5608 PyErr_NoMemory();
5609 goto error;
5610 }
5611 CPU_ZERO_S(setsize, mask);
5612
5613 while ((item = PyIter_Next(iterator))) {
5614 long cpu;
5615 if (!PyLong_Check(item)) {
5616 PyErr_Format(PyExc_TypeError,
5617 "expected an iterator of ints, "
5618 "but iterator yielded %R",
5619 Py_TYPE(item));
5620 Py_DECREF(item);
5621 goto error;
5622 }
5623 cpu = PyLong_AsLong(item);
5624 Py_DECREF(item);
5625 if (cpu < 0) {
5626 if (!PyErr_Occurred())
5627 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5628 goto error;
5629 }
5630 if (cpu > INT_MAX - 1) {
5631 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5632 goto error;
5633 }
5634 if (cpu >= ncpus) {
5635 /* Grow CPU mask to fit the CPU number */
5636 int newncpus = ncpus;
5637 cpu_set_t *newmask;
5638 size_t newsetsize;
5639 while (newncpus <= cpu) {
5640 if (newncpus > INT_MAX / 2)
5641 newncpus = cpu + 1;
5642 else
5643 newncpus = newncpus * 2;
5644 }
5645 newmask = CPU_ALLOC(newncpus);
5646 if (newmask == NULL) {
5647 PyErr_NoMemory();
5648 goto error;
5649 }
5650 newsetsize = CPU_ALLOC_SIZE(newncpus);
5651 CPU_ZERO_S(newsetsize, newmask);
5652 memcpy(newmask, mask, setsize);
5653 CPU_FREE(mask);
5654 setsize = newsetsize;
5655 mask = newmask;
5656 ncpus = newncpus;
5657 }
5658 CPU_SET_S(cpu, setsize, mask);
5659 }
5660 Py_CLEAR(iterator);
5661
5662 if (sched_setaffinity(pid, setsize, mask)) {
5663 posix_error();
5664 goto error;
5665 }
5666 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005667 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005668
5669error:
5670 if (mask)
5671 CPU_FREE(mask);
5672 Py_XDECREF(iterator);
5673 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005674}
5675
5676PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5677"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5678Return the affinity of the process with PID *pid*.\n\
5679The returned cpu_set will be of size *ncpus*.");
5680
5681static PyObject *
5682posix_sched_getaffinity(PyObject *self, PyObject *args)
5683{
5684 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005685 int cpu, ncpus, count;
5686 size_t setsize;
5687 cpu_set_t *mask = NULL;
5688 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005689
Antoine Pitrou84869872012-08-04 16:16:35 +02005690 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5691 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005692 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005693
5694 ncpus = NCPUS_START;
5695 while (1) {
5696 setsize = CPU_ALLOC_SIZE(ncpus);
5697 mask = CPU_ALLOC(ncpus);
5698 if (mask == NULL)
5699 return PyErr_NoMemory();
5700 if (sched_getaffinity(pid, setsize, mask) == 0)
5701 break;
5702 CPU_FREE(mask);
5703 if (errno != EINVAL)
5704 return posix_error();
5705 if (ncpus > INT_MAX / 2) {
5706 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5707 "a large enough CPU set");
5708 return NULL;
5709 }
5710 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005711 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005712
5713 res = PySet_New(NULL);
5714 if (res == NULL)
5715 goto error;
5716 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5717 if (CPU_ISSET_S(cpu, setsize, mask)) {
5718 PyObject *cpu_num = PyLong_FromLong(cpu);
5719 --count;
5720 if (cpu_num == NULL)
5721 goto error;
5722 if (PySet_Add(res, cpu_num)) {
5723 Py_DECREF(cpu_num);
5724 goto error;
5725 }
5726 Py_DECREF(cpu_num);
5727 }
5728 }
5729 CPU_FREE(mask);
5730 return res;
5731
5732error:
5733 if (mask)
5734 CPU_FREE(mask);
5735 Py_XDECREF(res);
5736 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005737}
5738
Benjamin Peterson2740af82011-08-02 17:41:34 -05005739#endif /* HAVE_SCHED_SETAFFINITY */
5740
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005741#endif /* HAVE_SCHED_H */
5742
Neal Norwitzb59798b2003-03-21 01:43:31 +00005743/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005744/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5745#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005746#define DEV_PTY_FILE "/dev/ptc"
5747#define HAVE_DEV_PTMX
5748#else
5749#define DEV_PTY_FILE "/dev/ptmx"
5750#endif
5751
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005752#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005753#ifdef HAVE_PTY_H
5754#include <pty.h>
5755#else
5756#ifdef HAVE_LIBUTIL_H
5757#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005758#else
5759#ifdef HAVE_UTIL_H
5760#include <util.h>
5761#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005762#endif /* HAVE_LIBUTIL_H */
5763#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005764#ifdef HAVE_STROPTS_H
5765#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005766#endif
5767#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005768
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005769#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005771"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005773
5774static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005775posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005776{
Victor Stinner8c62be82010-05-06 00:08:46 +00005777 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005778#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005780#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005781#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005783#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005785#endif
5786#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005787
Thomas Wouters70c21a12000-07-14 14:28:33 +00005788#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5790 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005791#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5793 if (slave_name == NULL)
5794 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005795
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 slave_fd = open(slave_name, O_RDWR);
5797 if (slave_fd < 0)
5798 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005799#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5801 if (master_fd < 0)
5802 return posix_error();
5803 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5804 /* change permission of slave */
5805 if (grantpt(master_fd) < 0) {
5806 PyOS_setsig(SIGCHLD, sig_saved);
5807 return posix_error();
5808 }
5809 /* unlock slave */
5810 if (unlockpt(master_fd) < 0) {
5811 PyOS_setsig(SIGCHLD, sig_saved);
5812 return posix_error();
5813 }
5814 PyOS_setsig(SIGCHLD, sig_saved);
5815 slave_name = ptsname(master_fd); /* get name of slave */
5816 if (slave_name == NULL)
5817 return posix_error();
5818 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5819 if (slave_fd < 0)
5820 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005821#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005822 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5823 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005824#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005826#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005827#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005828#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005829
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005831
Fred Drake8cef4cf2000-06-28 16:40:38 +00005832}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005833#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005834
5835#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005836PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005837"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005838Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5839Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005840To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005841
5842static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005843posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005844{
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 int master_fd = -1, result = 0;
5846 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005847
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 _PyImport_AcquireLock();
5849 pid = forkpty(&master_fd, NULL, NULL, NULL);
5850 if (pid == 0) {
5851 /* child: this clobbers and resets the import lock. */
5852 PyOS_AfterFork();
5853 } else {
5854 /* parent: release the import lock. */
5855 result = _PyImport_ReleaseLock();
5856 }
5857 if (pid == -1)
5858 return posix_error();
5859 if (result < 0) {
5860 /* Don't clobber the OSError if the fork failed. */
5861 PyErr_SetString(PyExc_RuntimeError,
5862 "not holding the import lock");
5863 return NULL;
5864 }
5865 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005866}
5867#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005868
Ross Lagerwall7807c352011-03-17 20:20:30 +02005869
Guido van Rossumad0ee831995-03-01 10:34:45 +00005870#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005872"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005873Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005874
Barry Warsaw53699e91996-12-10 23:23:01 +00005875static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005876posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005877{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005878 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005879}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005880#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005881
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005882
Guido van Rossumad0ee831995-03-01 10:34:45 +00005883#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005885"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005886Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005887
Barry Warsaw53699e91996-12-10 23:23:01 +00005888static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005889posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005890{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005891 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005892}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005893#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005895
Guido van Rossumad0ee831995-03-01 10:34:45 +00005896#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005897PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005898"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005899Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005900
Barry Warsaw53699e91996-12-10 23:23:01 +00005901static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005902posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005903{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005904 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005905}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005906#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005909PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005910"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005911Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005912
Barry Warsaw53699e91996-12-10 23:23:01 +00005913static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005914posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005915{
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005917}
5918
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005919#ifdef HAVE_GETGROUPLIST
5920PyDoc_STRVAR(posix_getgrouplist__doc__,
5921"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5922Returns a list of groups to which a user belongs.\n\n\
5923 user: username to lookup\n\
5924 group: base group id of the user");
5925
5926static PyObject *
5927posix_getgrouplist(PyObject *self, PyObject *args)
5928{
5929#ifdef NGROUPS_MAX
5930#define MAX_GROUPS NGROUPS_MAX
5931#else
5932 /* defined to be 16 on Solaris7, so this should be a small number */
5933#define MAX_GROUPS 64
5934#endif
5935
5936 const char *user;
5937 int i, ngroups;
5938 PyObject *list;
5939#ifdef __APPLE__
5940 int *groups, basegid;
5941#else
5942 gid_t *groups, basegid;
5943#endif
5944 ngroups = MAX_GROUPS;
5945
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005946#ifdef __APPLE__
5947 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005948 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005949#else
5950 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5951 _Py_Gid_Converter, &basegid))
5952 return NULL;
5953#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005954
5955#ifdef __APPLE__
5956 groups = PyMem_Malloc(ngroups * sizeof(int));
5957#else
5958 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5959#endif
5960 if (groups == NULL)
5961 return PyErr_NoMemory();
5962
5963 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5964 PyMem_Del(groups);
5965 return posix_error();
5966 }
5967
5968 list = PyList_New(ngroups);
5969 if (list == NULL) {
5970 PyMem_Del(groups);
5971 return NULL;
5972 }
5973
5974 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005975#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005976 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005977#else
5978 PyObject *o = _PyLong_FromGid(groups[i]);
5979#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005980 if (o == NULL) {
5981 Py_DECREF(list);
5982 PyMem_Del(groups);
5983 return NULL;
5984 }
5985 PyList_SET_ITEM(list, i, o);
5986 }
5987
5988 PyMem_Del(groups);
5989
5990 return list;
5991}
5992#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005993
Fred Drakec9680921999-12-13 16:37:25 +00005994#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005996"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005997Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005998
5999static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006000posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006001{
6002 PyObject *result = NULL;
6003
Fred Drakec9680921999-12-13 16:37:25 +00006004#ifdef NGROUPS_MAX
6005#define MAX_GROUPS NGROUPS_MAX
6006#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006008#define MAX_GROUPS 64
6009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006011
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006012 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006013 * This is a helper variable to store the intermediate result when
6014 * that happens.
6015 *
6016 * To keep the code readable the OSX behaviour is unconditional,
6017 * according to the POSIX spec this should be safe on all unix-y
6018 * systems.
6019 */
6020 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006022
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006023#ifdef __APPLE__
6024 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6025 * there are more groups than can fit in grouplist. Therefore, on OS X
6026 * always first call getgroups with length 0 to get the actual number
6027 * of groups.
6028 */
6029 n = getgroups(0, NULL);
6030 if (n < 0) {
6031 return posix_error();
6032 } else if (n <= MAX_GROUPS) {
6033 /* groups will fit in existing array */
6034 alt_grouplist = grouplist;
6035 } else {
6036 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6037 if (alt_grouplist == NULL) {
6038 errno = EINVAL;
6039 return posix_error();
6040 }
6041 }
6042
6043 n = getgroups(n, alt_grouplist);
6044 if (n == -1) {
6045 if (alt_grouplist != grouplist) {
6046 PyMem_Free(alt_grouplist);
6047 }
6048 return posix_error();
6049 }
6050#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006051 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006052 if (n < 0) {
6053 if (errno == EINVAL) {
6054 n = getgroups(0, NULL);
6055 if (n == -1) {
6056 return posix_error();
6057 }
6058 if (n == 0) {
6059 /* Avoid malloc(0) */
6060 alt_grouplist = grouplist;
6061 } else {
6062 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6063 if (alt_grouplist == NULL) {
6064 errno = EINVAL;
6065 return posix_error();
6066 }
6067 n = getgroups(n, alt_grouplist);
6068 if (n == -1) {
6069 PyMem_Free(alt_grouplist);
6070 return posix_error();
6071 }
6072 }
6073 } else {
6074 return posix_error();
6075 }
6076 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006077#endif
6078
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006079 result = PyList_New(n);
6080 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 int i;
6082 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006083 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006085 Py_DECREF(result);
6086 result = NULL;
6087 break;
Fred Drakec9680921999-12-13 16:37:25 +00006088 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006089 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006090 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006091 }
6092
6093 if (alt_grouplist != grouplist) {
6094 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006096
Fred Drakec9680921999-12-13 16:37:25 +00006097 return result;
6098}
6099#endif
6100
Antoine Pitroub7572f02009-12-02 20:46:48 +00006101#ifdef HAVE_INITGROUPS
6102PyDoc_STRVAR(posix_initgroups__doc__,
6103"initgroups(username, gid) -> None\n\n\
6104Call the system initgroups() to initialize the group access list with all of\n\
6105the groups of which the specified username is a member, plus the specified\n\
6106group id.");
6107
6108static PyObject *
6109posix_initgroups(PyObject *self, PyObject *args)
6110{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006111 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006113 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006114#ifdef __APPLE__
6115 int gid;
6116#else
6117 gid_t gid;
6118#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006119
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006120#ifdef __APPLE__
6121 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6122 PyUnicode_FSConverter, &oname,
6123 &gid))
6124#else
6125 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6126 PyUnicode_FSConverter, &oname,
6127 _Py_Gid_Converter, &gid))
6128#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006130 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006131
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006132 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006133 Py_DECREF(oname);
6134 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006135 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006136
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 Py_INCREF(Py_None);
6138 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006139}
6140#endif
6141
Martin v. Löwis606edc12002-06-13 21:09:11 +00006142#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006143PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006144"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006145Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006146
6147static PyObject *
6148posix_getpgid(PyObject *self, PyObject *args)
6149{
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 pid_t pid, pgid;
6151 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6152 return NULL;
6153 pgid = getpgid(pid);
6154 if (pgid < 0)
6155 return posix_error();
6156 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006157}
6158#endif /* HAVE_GETPGID */
6159
6160
Guido van Rossumb6775db1994-08-01 11:34:53 +00006161#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006163"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006165
Barry Warsaw53699e91996-12-10 23:23:01 +00006166static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006167posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006168{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006169#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006171#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006173#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006174}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006175#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006177
Guido van Rossumb6775db1994-08-01 11:34:53 +00006178#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006179PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006180"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006181Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006182
Barry Warsaw53699e91996-12-10 23:23:01 +00006183static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006184posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006185{
Guido van Rossum64933891994-10-20 21:56:42 +00006186#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006187 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006188#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006189 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006190#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 return posix_error();
6192 Py_INCREF(Py_None);
6193 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006194}
6195
Guido van Rossumb6775db1994-08-01 11:34:53 +00006196#endif /* HAVE_SETPGRP */
6197
Guido van Rossumad0ee831995-03-01 10:34:45 +00006198#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006199
6200#ifdef MS_WINDOWS
6201#include <tlhelp32.h>
6202
6203static PyObject*
6204win32_getppid()
6205{
6206 HANDLE snapshot;
6207 pid_t mypid;
6208 PyObject* result = NULL;
6209 BOOL have_record;
6210 PROCESSENTRY32 pe;
6211
6212 mypid = getpid(); /* This function never fails */
6213
6214 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6215 if (snapshot == INVALID_HANDLE_VALUE)
6216 return PyErr_SetFromWindowsErr(GetLastError());
6217
6218 pe.dwSize = sizeof(pe);
6219 have_record = Process32First(snapshot, &pe);
6220 while (have_record) {
6221 if (mypid == (pid_t)pe.th32ProcessID) {
6222 /* We could cache the ulong value in a static variable. */
6223 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6224 break;
6225 }
6226
6227 have_record = Process32Next(snapshot, &pe);
6228 }
6229
6230 /* If our loop exits and our pid was not found (result will be NULL)
6231 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6232 * error anyway, so let's raise it. */
6233 if (!result)
6234 result = PyErr_SetFromWindowsErr(GetLastError());
6235
6236 CloseHandle(snapshot);
6237
6238 return result;
6239}
6240#endif /*MS_WINDOWS*/
6241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006242PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006243"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006244Return the parent's process id. If the parent process has already exited,\n\
6245Windows machines will still return its id; others systems will return the id\n\
6246of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006247
Barry Warsaw53699e91996-12-10 23:23:01 +00006248static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006249posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006250{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006251#ifdef MS_WINDOWS
6252 return win32_getppid();
6253#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006255#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006256}
6257#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006259
Fred Drake12c6e2d1999-12-14 21:25:03 +00006260#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006262"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006264
6265static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006266posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006267{
Victor Stinner8c62be82010-05-06 00:08:46 +00006268 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006269#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006270 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006271 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006272
6273 if (GetUserNameW(user_name, &num_chars)) {
6274 /* num_chars is the number of unicode chars plus null terminator */
6275 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006276 }
6277 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006278 result = PyErr_SetFromWindowsErr(GetLastError());
6279#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 char *name;
6281 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006282
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 errno = 0;
6284 name = getlogin();
6285 if (name == NULL) {
6286 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006287 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006288 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006289 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 }
6291 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006292 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006294#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006295 return result;
6296}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006297#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006298
Guido van Rossumad0ee831995-03-01 10:34:45 +00006299#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006302Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006303
Barry Warsaw53699e91996-12-10 23:23:01 +00006304static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006305posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006306{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006307 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006308}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006309#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006311
Guido van Rossumad0ee831995-03-01 10:34:45 +00006312#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006314"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006316
Barry Warsaw53699e91996-12-10 23:23:01 +00006317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006318posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006319{
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 pid_t pid;
6321 int sig;
6322 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6323 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (kill(pid, sig) == -1)
6325 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 Py_INCREF(Py_None);
6327 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006328}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006329#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006330
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006331#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006333"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006335
6336static PyObject *
6337posix_killpg(PyObject *self, PyObject *args)
6338{
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 int sig;
6340 pid_t pgid;
6341 /* XXX some man pages make the `pgid` parameter an int, others
6342 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6343 take the same type. Moreover, pid_t is always at least as wide as
6344 int (else compilation of this module fails), which is safe. */
6345 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6346 return NULL;
6347 if (killpg(pgid, sig) == -1)
6348 return posix_error();
6349 Py_INCREF(Py_None);
6350 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006351}
6352#endif
6353
Brian Curtineb24d742010-04-12 17:16:38 +00006354#ifdef MS_WINDOWS
6355PyDoc_STRVAR(win32_kill__doc__,
6356"kill(pid, sig)\n\n\
6357Kill a process with a signal.");
6358
6359static PyObject *
6360win32_kill(PyObject *self, PyObject *args)
6361{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006362 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006363 pid_t pid;
6364 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006366
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006367 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006369
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 /* Console processes which share a common console can be sent CTRL+C or
6371 CTRL+BREAK events, provided they handle said events. */
6372 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006373 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 err = GetLastError();
6375 PyErr_SetFromWindowsErr(err);
6376 }
6377 else
6378 Py_RETURN_NONE;
6379 }
Brian Curtineb24d742010-04-12 17:16:38 +00006380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6382 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006383 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 if (handle == NULL) {
6385 err = GetLastError();
6386 return PyErr_SetFromWindowsErr(err);
6387 }
Brian Curtineb24d742010-04-12 17:16:38 +00006388
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 if (TerminateProcess(handle, sig) == 0) {
6390 err = GetLastError();
6391 result = PyErr_SetFromWindowsErr(err);
6392 } else {
6393 Py_INCREF(Py_None);
6394 result = Py_None;
6395 }
Brian Curtineb24d742010-04-12 17:16:38 +00006396
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 CloseHandle(handle);
6398 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006399}
6400#endif /* MS_WINDOWS */
6401
Guido van Rossumc0125471996-06-28 18:55:32 +00006402#ifdef HAVE_PLOCK
6403
6404#ifdef HAVE_SYS_LOCK_H
6405#include <sys/lock.h>
6406#endif
6407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006408PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006409"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006410Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006411
Barry Warsaw53699e91996-12-10 23:23:01 +00006412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006413posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006414{
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 int op;
6416 if (!PyArg_ParseTuple(args, "i:plock", &op))
6417 return NULL;
6418 if (plock(op) == -1)
6419 return posix_error();
6420 Py_INCREF(Py_None);
6421 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006422}
6423#endif
6424
Guido van Rossumb6775db1994-08-01 11:34:53 +00006425#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006426PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006427"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006428Set the current process's user id.");
6429
Barry Warsaw53699e91996-12-10 23:23:01 +00006430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006431posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006432{
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006434 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 if (setuid(uid) < 0)
6437 return posix_error();
6438 Py_INCREF(Py_None);
6439 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006440}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006441#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006443
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006444#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006445PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006446"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006447Set the current process's effective user id.");
6448
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006449static PyObject *
6450posix_seteuid (PyObject *self, PyObject *args)
6451{
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006453 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 if (seteuid(euid) < 0) {
6456 return posix_error();
6457 } else {
6458 Py_INCREF(Py_None);
6459 return Py_None;
6460 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006461}
6462#endif /* HAVE_SETEUID */
6463
6464#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006465PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006466"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467Set the current process's effective group id.");
6468
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006469static PyObject *
6470posix_setegid (PyObject *self, PyObject *args)
6471{
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006473 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 if (setegid(egid) < 0) {
6476 return posix_error();
6477 } else {
6478 Py_INCREF(Py_None);
6479 return Py_None;
6480 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006481}
6482#endif /* HAVE_SETEGID */
6483
6484#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006485PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006486"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006487Set the current process's real and effective user ids.");
6488
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006489static PyObject *
6490posix_setreuid (PyObject *self, PyObject *args)
6491{
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006493 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6494 _Py_Uid_Converter, &ruid,
6495 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 if (setreuid(ruid, euid) < 0) {
6498 return posix_error();
6499 } else {
6500 Py_INCREF(Py_None);
6501 return Py_None;
6502 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006503}
6504#endif /* HAVE_SETREUID */
6505
6506#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006508"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006509Set the current process's real and effective group ids.");
6510
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006511static PyObject *
6512posix_setregid (PyObject *self, PyObject *args)
6513{
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006515 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6516 _Py_Gid_Converter, &rgid,
6517 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 if (setregid(rgid, egid) < 0) {
6520 return posix_error();
6521 } else {
6522 Py_INCREF(Py_None);
6523 return Py_None;
6524 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006525}
6526#endif /* HAVE_SETREGID */
6527
Guido van Rossumb6775db1994-08-01 11:34:53 +00006528#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006529PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006530"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006532
Barry Warsaw53699e91996-12-10 23:23:01 +00006533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006534posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006535{
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006537 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 if (setgid(gid) < 0)
6540 return posix_error();
6541 Py_INCREF(Py_None);
6542 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006543}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006544#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006545
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006546#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006548"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006549Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006550
6551static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006552posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006553{
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 int i, len;
6555 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006556
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 if (!PySequence_Check(groups)) {
6558 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6559 return NULL;
6560 }
6561 len = PySequence_Size(groups);
6562 if (len > MAX_GROUPS) {
6563 PyErr_SetString(PyExc_ValueError, "too many groups");
6564 return NULL;
6565 }
6566 for(i = 0; i < len; i++) {
6567 PyObject *elem;
6568 elem = PySequence_GetItem(groups, i);
6569 if (!elem)
6570 return NULL;
6571 if (!PyLong_Check(elem)) {
6572 PyErr_SetString(PyExc_TypeError,
6573 "groups must be integers");
6574 Py_DECREF(elem);
6575 return NULL;
6576 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006577 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 Py_DECREF(elem);
6579 return NULL;
6580 }
6581 }
6582 Py_DECREF(elem);
6583 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006584
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (setgroups(len, grouplist) < 0)
6586 return posix_error();
6587 Py_INCREF(Py_None);
6588 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006589}
6590#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006591
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006592#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6593static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006594wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006595{
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 PyObject *result;
6597 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006598 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006599
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 if (pid == -1)
6601 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006602
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 if (struct_rusage == NULL) {
6604 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6605 if (m == NULL)
6606 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006607 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 Py_DECREF(m);
6609 if (struct_rusage == NULL)
6610 return NULL;
6611 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6614 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6615 if (!result)
6616 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006617
6618#ifndef doubletime
6619#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6620#endif
6621
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006623 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006625 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006626#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6628 SET_INT(result, 2, ru->ru_maxrss);
6629 SET_INT(result, 3, ru->ru_ixrss);
6630 SET_INT(result, 4, ru->ru_idrss);
6631 SET_INT(result, 5, ru->ru_isrss);
6632 SET_INT(result, 6, ru->ru_minflt);
6633 SET_INT(result, 7, ru->ru_majflt);
6634 SET_INT(result, 8, ru->ru_nswap);
6635 SET_INT(result, 9, ru->ru_inblock);
6636 SET_INT(result, 10, ru->ru_oublock);
6637 SET_INT(result, 11, ru->ru_msgsnd);
6638 SET_INT(result, 12, ru->ru_msgrcv);
6639 SET_INT(result, 13, ru->ru_nsignals);
6640 SET_INT(result, 14, ru->ru_nvcsw);
6641 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006642#undef SET_INT
6643
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 if (PyErr_Occurred()) {
6645 Py_DECREF(result);
6646 return NULL;
6647 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006648
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006650}
6651#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6652
6653#ifdef HAVE_WAIT3
6654PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006655"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006656Wait for completion of a child process.");
6657
6658static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006659posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006660{
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 pid_t pid;
6662 int options;
6663 struct rusage ru;
6664 WAIT_TYPE status;
6665 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006666
Victor Stinner4195b5c2012-02-08 23:03:19 +01006667 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006669
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 Py_BEGIN_ALLOW_THREADS
6671 pid = wait3(&status, options, &ru);
6672 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006673
Victor Stinner4195b5c2012-02-08 23:03:19 +01006674 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006675}
6676#endif /* HAVE_WAIT3 */
6677
6678#ifdef HAVE_WAIT4
6679PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006680"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006681Wait for completion of a given child process.");
6682
6683static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006684posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006685{
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 pid_t pid;
6687 int options;
6688 struct rusage ru;
6689 WAIT_TYPE status;
6690 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691
Victor Stinner4195b5c2012-02-08 23:03:19 +01006692 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006694
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 Py_BEGIN_ALLOW_THREADS
6696 pid = wait4(pid, &status, options, &ru);
6697 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006698
Victor Stinner4195b5c2012-02-08 23:03:19 +01006699 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006700}
6701#endif /* HAVE_WAIT4 */
6702
Ross Lagerwall7807c352011-03-17 20:20:30 +02006703#if defined(HAVE_WAITID) && !defined(__APPLE__)
6704PyDoc_STRVAR(posix_waitid__doc__,
6705"waitid(idtype, id, options) -> waitid_result\n\n\
6706Wait for the completion of one or more child processes.\n\n\
6707idtype can be P_PID, P_PGID or P_ALL.\n\
6708id specifies the pid to wait on.\n\
6709options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6710or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6711Returns either waitid_result or None if WNOHANG is specified and there are\n\
6712no children in a waitable state.");
6713
6714static PyObject *
6715posix_waitid(PyObject *self, PyObject *args)
6716{
6717 PyObject *result;
6718 idtype_t idtype;
6719 id_t id;
6720 int options, res;
6721 siginfo_t si;
6722 si.si_pid = 0;
6723 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6724 return NULL;
6725 Py_BEGIN_ALLOW_THREADS
6726 res = waitid(idtype, id, &si, options);
6727 Py_END_ALLOW_THREADS
6728 if (res == -1)
6729 return posix_error();
6730
6731 if (si.si_pid == 0)
6732 Py_RETURN_NONE;
6733
6734 result = PyStructSequence_New(&WaitidResultType);
6735 if (!result)
6736 return NULL;
6737
6738 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006739 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006740 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6741 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6742 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6743 if (PyErr_Occurred()) {
6744 Py_DECREF(result);
6745 return NULL;
6746 }
6747
6748 return result;
6749}
6750#endif
6751
Guido van Rossumb6775db1994-08-01 11:34:53 +00006752#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006753PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006754"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006755Wait for completion of a given child process.");
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_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006759{
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 pid_t pid;
6761 int options;
6762 WAIT_TYPE status;
6763 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006764
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6766 return NULL;
6767 Py_BEGIN_ALLOW_THREADS
6768 pid = waitpid(pid, &status, options);
6769 Py_END_ALLOW_THREADS
6770 if (pid == -1)
6771 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006772
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006774}
6775
Tim Petersab034fa2002-02-01 11:27:43 +00006776#elif defined(HAVE_CWAIT)
6777
6778/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006779PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006780"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006781"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006782
6783static PyObject *
6784posix_waitpid(PyObject *self, PyObject *args)
6785{
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 Py_intptr_t pid;
6787 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006788
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006789 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 return NULL;
6791 Py_BEGIN_ALLOW_THREADS
6792 pid = _cwait(&status, pid, options);
6793 Py_END_ALLOW_THREADS
6794 if (pid == -1)
6795 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006796
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006798 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006799}
6800#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006801
Guido van Rossumad0ee831995-03-01 10:34:45 +00006802#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006803PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006804"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006805Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006806
Barry Warsaw53699e91996-12-10 23:23:01 +00006807static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006808posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006809{
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 pid_t pid;
6811 WAIT_TYPE status;
6812 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006813
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 Py_BEGIN_ALLOW_THREADS
6815 pid = wait(&status);
6816 Py_END_ALLOW_THREADS
6817 if (pid == -1)
6818 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006821}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006822#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006824
Larry Hastings9cf065c2012-06-22 16:30:09 -07006825#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6826PyDoc_STRVAR(readlink__doc__,
6827"readlink(path, *, dir_fd=None) -> path\n\n\
6828Return a string representing the path to which the symbolic link points.\n\
6829\n\
6830If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6831 and path should be relative; path will then be relative to that directory.\n\
6832dir_fd may not be implemented on your platform.\n\
6833 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006834#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006835
Guido van Rossumb6775db1994-08-01 11:34:53 +00006836#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006837
Barry Warsaw53699e91996-12-10 23:23:01 +00006838static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006839posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006840{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006841 path_t path;
6842 int dir_fd = DEFAULT_DIR_FD;
6843 char buffer[MAXPATHLEN];
6844 ssize_t length;
6845 PyObject *return_value = NULL;
6846 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006847
Larry Hastings9cf065c2012-06-22 16:30:09 -07006848 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006849 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006850 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6851 path_converter, &path,
6852#ifdef HAVE_READLINKAT
6853 dir_fd_converter, &dir_fd
6854#else
6855 dir_fd_unavailable, &dir_fd
6856#endif
6857 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006861#ifdef HAVE_READLINKAT
6862 if (dir_fd != DEFAULT_DIR_FD)
6863 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006864 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006865#endif
6866 length = readlink(path.narrow, buffer, sizeof(buffer));
6867 Py_END_ALLOW_THREADS
6868
6869 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006870 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006871 goto exit;
6872 }
6873
6874 if (PyUnicode_Check(path.object))
6875 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6876 else
6877 return_value = PyBytes_FromStringAndSize(buffer, length);
6878exit:
6879 path_cleanup(&path);
6880 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006881}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006882
6883
Guido van Rossumb6775db1994-08-01 11:34:53 +00006884#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006886
Larry Hastings9cf065c2012-06-22 16:30:09 -07006887#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006888PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006889"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6890Create a symbolic link pointing to src named dst.\n\n\
6891target_is_directory is required on Windows if the target is to be\n\
6892 interpreted as a directory. (On Windows, symlink requires\n\
6893 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6894 target_is_directory is ignored on non-Windows platforms.\n\
6895\n\
6896If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6897 and path should be relative; path will then be relative to that directory.\n\
6898dir_fd may not be implemented on your platform.\n\
6899 If it is unavailable, using it will raise a NotImplementedError.");
6900
6901#if defined(MS_WINDOWS)
6902
6903/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6904static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6905static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02006906
Larry Hastings9cf065c2012-06-22 16:30:09 -07006907static int
Victor Stinner31b3b922013-06-05 01:49:17 +02006908check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006909{
6910 HINSTANCE hKernel32;
6911 /* only recheck */
6912 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6913 return 1;
6914 hKernel32 = GetModuleHandleW(L"KERNEL32");
6915 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6916 "CreateSymbolicLinkW");
6917 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6918 "CreateSymbolicLinkA");
6919 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6920}
6921
Victor Stinner31b3b922013-06-05 01:49:17 +02006922/* Remove the last portion of the path */
6923static void
6924_dirnameW(WCHAR *path)
6925{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006926 WCHAR *ptr;
6927
6928 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02006929 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02006930 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04006931 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006932 }
6933 *ptr = 0;
6934}
6935
Victor Stinner31b3b922013-06-05 01:49:17 +02006936/* Remove the last portion of the path */
6937static void
6938_dirnameA(char *path)
6939{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006940 char *ptr;
6941
6942 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02006943 for(ptr = path + strlen(path); ptr != path; ptr--) {
6944 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04006945 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006946 }
6947 *ptr = 0;
6948}
6949
Victor Stinner31b3b922013-06-05 01:49:17 +02006950/* Is this path absolute? */
6951static int
6952_is_absW(const WCHAR *path)
6953{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006954 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
6955
6956}
6957
Victor Stinner31b3b922013-06-05 01:49:17 +02006958/* Is this path absolute? */
6959static int
6960_is_absA(const char *path)
6961{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006962 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
6963
6964}
6965
Victor Stinner31b3b922013-06-05 01:49:17 +02006966/* join root and rest with a backslash */
6967static void
6968_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
6969{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02006970 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006971
Victor Stinner31b3b922013-06-05 01:49:17 +02006972 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04006973 wcscpy(dest_path, rest);
6974 return;
6975 }
6976
6977 root_len = wcslen(root);
6978
6979 wcscpy(dest_path, root);
6980 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02006981 dest_path[root_len] = L'\\';
6982 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006983 }
6984 wcscpy(dest_path+root_len, rest);
6985}
6986
Victor Stinner31b3b922013-06-05 01:49:17 +02006987/* join root and rest with a backslash */
6988static void
6989_joinA(char *dest_path, const char *root, const char *rest)
6990{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02006991 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006992
Victor Stinner31b3b922013-06-05 01:49:17 +02006993 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04006994 strcpy(dest_path, rest);
6995 return;
6996 }
6997
6998 root_len = strlen(root);
6999
7000 strcpy(dest_path, root);
7001 if(root_len) {
7002 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007003 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007004 }
7005 strcpy(dest_path+root_len, rest);
7006}
7007
Victor Stinner31b3b922013-06-05 01:49:17 +02007008/* Return True if the path at src relative to dest is a directory */
7009static int
7010_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007011{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007012 WIN32_FILE_ATTRIBUTE_DATA src_info;
7013 WCHAR dest_parent[MAX_PATH];
7014 WCHAR src_resolved[MAX_PATH] = L"";
7015
7016 /* dest_parent = os.path.dirname(dest) */
7017 wcscpy(dest_parent, dest);
7018 _dirnameW(dest_parent);
7019 /* src_resolved = os.path.join(dest_parent, src) */
7020 _joinW(src_resolved, dest_parent, src);
7021 return (
7022 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7023 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7024 );
7025}
7026
Victor Stinner31b3b922013-06-05 01:49:17 +02007027/* Return True if the path at src relative to dest is a directory */
7028static int
7029_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007030{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007031 WIN32_FILE_ATTRIBUTE_DATA src_info;
7032 char dest_parent[MAX_PATH];
7033 char src_resolved[MAX_PATH] = "";
7034
7035 /* dest_parent = os.path.dirname(dest) */
7036 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007037 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007038 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007039 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007040 return (
7041 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7042 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7043 );
7044}
7045
Larry Hastings9cf065c2012-06-22 16:30:09 -07007046#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007047
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007048static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007049posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007050{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007051 path_t src;
7052 path_t dst;
7053 int dir_fd = DEFAULT_DIR_FD;
7054 int target_is_directory = 0;
7055 static char *keywords[] = {"src", "dst", "target_is_directory",
7056 "dir_fd", NULL};
7057 PyObject *return_value;
7058#ifdef MS_WINDOWS
7059 DWORD result;
7060#else
7061 int result;
7062#endif
7063
7064 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007065 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007066 src.argument_name = "src";
7067 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007068 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007069 dst.argument_name = "dst";
7070
7071#ifdef MS_WINDOWS
7072 if (!check_CreateSymbolicLink()) {
7073 PyErr_SetString(PyExc_NotImplementedError,
7074 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007075 return NULL;
7076 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007077 if (!win32_can_symlink) {
7078 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007079 return NULL;
7080 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081#endif
7082
7083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7084 keywords,
7085 path_converter, &src,
7086 path_converter, &dst,
7087 &target_is_directory,
7088#ifdef HAVE_SYMLINKAT
7089 dir_fd_converter, &dir_fd
7090#else
7091 dir_fd_unavailable, &dir_fd
7092#endif
7093 ))
7094 return NULL;
7095
7096 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7097 PyErr_SetString(PyExc_ValueError,
7098 "symlink: src and dst must be the same type");
7099 return_value = NULL;
7100 goto exit;
7101 }
7102
7103#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007104
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007106 if (dst.wide) {
7107 /* if src is a directory, ensure target_is_directory==1 */
7108 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007109 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7110 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007111 }
7112 else {
7113 /* if src is a directory, ensure target_is_directory==1 */
7114 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7116 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007117 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118 Py_END_ALLOW_THREADS
7119
7120 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007121 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 goto exit;
7123 }
7124
7125#else
7126
7127 Py_BEGIN_ALLOW_THREADS
7128#if HAVE_SYMLINKAT
7129 if (dir_fd != DEFAULT_DIR_FD)
7130 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7131 else
7132#endif
7133 result = symlink(src.narrow, dst.narrow);
7134 Py_END_ALLOW_THREADS
7135
7136 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007137 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138 goto exit;
7139 }
7140#endif
7141
7142 return_value = Py_None;
7143 Py_INCREF(Py_None);
7144 goto exit; /* silence "unused label" warning */
7145exit:
7146 path_cleanup(&src);
7147 path_cleanup(&dst);
7148 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007149}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007150
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007151#endif /* HAVE_SYMLINK */
7152
Larry Hastings9cf065c2012-06-22 16:30:09 -07007153
Brian Curtind40e6f72010-07-08 21:39:08 +00007154#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7155
Brian Curtind40e6f72010-07-08 21:39:08 +00007156static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007157win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007158{
7159 wchar_t *path;
7160 DWORD n_bytes_returned;
7161 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007162 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007163 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007164 HANDLE reparse_point_handle;
7165
7166 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7167 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7168 wchar_t *print_name;
7169
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 static char *keywords[] = {"path", "dir_fd", NULL};
7171
7172 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7173 &po,
7174 dir_fd_unavailable, &dir_fd
7175 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007176 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007177
Victor Stinnereb5657a2011-09-30 01:44:27 +02007178 path = PyUnicode_AsUnicode(po);
7179 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007180 return NULL;
7181
7182 /* First get a handle to the reparse point */
7183 Py_BEGIN_ALLOW_THREADS
7184 reparse_point_handle = CreateFileW(
7185 path,
7186 0,
7187 0,
7188 0,
7189 OPEN_EXISTING,
7190 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7191 0);
7192 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007193
Brian Curtind40e6f72010-07-08 21:39:08 +00007194 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007195 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007196
Brian Curtind40e6f72010-07-08 21:39:08 +00007197 Py_BEGIN_ALLOW_THREADS
7198 /* New call DeviceIoControl to read the reparse point */
7199 io_result = DeviceIoControl(
7200 reparse_point_handle,
7201 FSCTL_GET_REPARSE_POINT,
7202 0, 0, /* in buffer */
7203 target_buffer, sizeof(target_buffer),
7204 &n_bytes_returned,
7205 0 /* we're not using OVERLAPPED_IO */
7206 );
7207 CloseHandle(reparse_point_handle);
7208 Py_END_ALLOW_THREADS
7209
7210 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007211 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007212
7213 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7214 {
7215 PyErr_SetString(PyExc_ValueError,
7216 "not a symbolic link");
7217 return NULL;
7218 }
Brian Curtin74e45612010-07-09 15:58:59 +00007219 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7220 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7221
7222 result = PyUnicode_FromWideChar(print_name,
7223 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007224 return result;
7225}
7226
7227#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7228
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007229
Larry Hastings605a62d2012-06-24 04:33:36 -07007230static PyStructSequence_Field times_result_fields[] = {
7231 {"user", "user time"},
7232 {"system", "system time"},
7233 {"children_user", "user time of children"},
7234 {"children_system", "system time of children"},
7235 {"elapsed", "elapsed time since an arbitrary point in the past"},
7236 {NULL}
7237};
7238
7239PyDoc_STRVAR(times_result__doc__,
7240"times_result: Result from os.times().\n\n\
7241This object may be accessed either as a tuple of\n\
7242 (user, system, children_user, children_system, elapsed),\n\
7243or via the attributes user, system, children_user, children_system,\n\
7244and elapsed.\n\
7245\n\
7246See os.times for more information.");
7247
7248static PyStructSequence_Desc times_result_desc = {
7249 "times_result", /* name */
7250 times_result__doc__, /* doc */
7251 times_result_fields,
7252 5
7253};
7254
7255static PyTypeObject TimesResultType;
7256
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007257#ifdef MS_WINDOWS
7258#define HAVE_TIMES /* mandatory, for the method table */
7259#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007260
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007261#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007262
7263static PyObject *
7264build_times_result(double user, double system,
7265 double children_user, double children_system,
7266 double elapsed)
7267{
7268 PyObject *value = PyStructSequence_New(&TimesResultType);
7269 if (value == NULL)
7270 return NULL;
7271
7272#define SET(i, field) \
7273 { \
7274 PyObject *o = PyFloat_FromDouble(field); \
7275 if (!o) { \
7276 Py_DECREF(value); \
7277 return NULL; \
7278 } \
7279 PyStructSequence_SET_ITEM(value, i, o); \
7280 } \
7281
7282 SET(0, user);
7283 SET(1, system);
7284 SET(2, children_user);
7285 SET(3, children_system);
7286 SET(4, elapsed);
7287
7288#undef SET
7289
7290 return value;
7291}
7292
7293PyDoc_STRVAR(posix_times__doc__,
7294"times() -> times_result\n\n\
7295Return an object containing floating point numbers indicating process\n\
7296times. The object behaves like a named tuple with these fields:\n\
7297 (utime, stime, cutime, cstime, elapsed_time)");
7298
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007299#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007301posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007302{
Victor Stinner8c62be82010-05-06 00:08:46 +00007303 FILETIME create, exit, kernel, user;
7304 HANDLE hProc;
7305 hProc = GetCurrentProcess();
7306 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7307 /* The fields of a FILETIME structure are the hi and lo part
7308 of a 64-bit value expressed in 100 nanosecond units.
7309 1e7 is one second in such units; 1e-7 the inverse.
7310 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7311 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007312 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 (double)(user.dwHighDateTime*429.4967296 +
7314 user.dwLowDateTime*1e-7),
7315 (double)(kernel.dwHighDateTime*429.4967296 +
7316 kernel.dwLowDateTime*1e-7),
7317 (double)0,
7318 (double)0,
7319 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007320}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007321#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007322#define NEED_TICKS_PER_SECOND
7323static long ticks_per_second = -1;
7324static PyObject *
7325posix_times(PyObject *self, PyObject *noargs)
7326{
7327 struct tms t;
7328 clock_t c;
7329 errno = 0;
7330 c = times(&t);
7331 if (c == (clock_t) -1)
7332 return posix_error();
7333 return build_times_result(
7334 (double)t.tms_utime / ticks_per_second,
7335 (double)t.tms_stime / ticks_per_second,
7336 (double)t.tms_cutime / ticks_per_second,
7337 (double)t.tms_cstime / ticks_per_second,
7338 (double)c / ticks_per_second);
7339}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007340#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007341
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007342#endif /* HAVE_TIMES */
7343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007344
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007345#ifdef HAVE_GETSID
7346PyDoc_STRVAR(posix_getsid__doc__,
7347"getsid(pid) -> sid\n\n\
7348Call the system call getsid().");
7349
7350static PyObject *
7351posix_getsid(PyObject *self, PyObject *args)
7352{
Victor Stinner8c62be82010-05-06 00:08:46 +00007353 pid_t pid;
7354 int sid;
7355 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7356 return NULL;
7357 sid = getsid(pid);
7358 if (sid < 0)
7359 return posix_error();
7360 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007361}
7362#endif /* HAVE_GETSID */
7363
7364
Guido van Rossumb6775db1994-08-01 11:34:53 +00007365#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007366PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007367"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007368Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007369
Barry Warsaw53699e91996-12-10 23:23:01 +00007370static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007371posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007372{
Victor Stinner8c62be82010-05-06 00:08:46 +00007373 if (setsid() < 0)
7374 return posix_error();
7375 Py_INCREF(Py_None);
7376 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007377}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007378#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007379
Guido van Rossumb6775db1994-08-01 11:34:53 +00007380#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007381PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007382"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007383Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007384
Barry Warsaw53699e91996-12-10 23:23:01 +00007385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007386posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007387{
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 pid_t pid;
7389 int pgrp;
7390 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7391 return NULL;
7392 if (setpgid(pid, pgrp) < 0)
7393 return posix_error();
7394 Py_INCREF(Py_None);
7395 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007397#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007399
Guido van Rossumb6775db1994-08-01 11:34:53 +00007400#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007401PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007402"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007403Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007404
Barry Warsaw53699e91996-12-10 23:23:01 +00007405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007406posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007407{
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 int fd;
7409 pid_t pgid;
7410 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7411 return NULL;
7412 pgid = tcgetpgrp(fd);
7413 if (pgid < 0)
7414 return posix_error();
7415 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007416}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007417#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007419
Guido van Rossumb6775db1994-08-01 11:34:53 +00007420#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007421PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007422"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007423Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007424
Barry Warsaw53699e91996-12-10 23:23:01 +00007425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007426posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007427{
Victor Stinner8c62be82010-05-06 00:08:46 +00007428 int fd;
7429 pid_t pgid;
7430 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7431 return NULL;
7432 if (tcsetpgrp(fd, pgid) < 0)
7433 return posix_error();
7434 Py_INCREF(Py_None);
7435 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007436}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007437#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007438
Guido van Rossum687dd131993-05-17 08:34:16 +00007439/* Functions acting on file descriptors */
7440
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007441PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007442"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7443Open a file for low level IO. Returns a file handle (integer).\n\
7444\n\
7445If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7446 and path should be relative; path will then be relative to that directory.\n\
7447dir_fd may not be implemented on your platform.\n\
7448 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007449
Barry Warsaw53699e91996-12-10 23:23:01 +00007450static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007451posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007452{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007453 path_t path;
7454 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007455 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007456 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007457 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007458 PyObject *return_value = NULL;
7459 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007460
Larry Hastings9cf065c2012-06-22 16:30:09 -07007461 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007462 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007463 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7464 path_converter, &path,
7465 &flags, &mode,
7466#ifdef HAVE_OPENAT
7467 dir_fd_converter, &dir_fd
7468#else
7469 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007470#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007471 ))
7472 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007473
Victor Stinner8c62be82010-05-06 00:08:46 +00007474 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007475#ifdef MS_WINDOWS
7476 if (path.wide)
7477 fd = _wopen(path.wide, flags, mode);
7478 else
7479#endif
7480#ifdef HAVE_OPENAT
7481 if (dir_fd != DEFAULT_DIR_FD)
7482 fd = openat(dir_fd, path.narrow, flags, mode);
7483 else
7484#endif
7485 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007486 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007487
Larry Hastings9cf065c2012-06-22 16:30:09 -07007488 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007489 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007490 goto exit;
7491 }
7492
7493 return_value = PyLong_FromLong((long)fd);
7494
7495exit:
7496 path_cleanup(&path);
7497 return return_value;
7498}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007500PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007501"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007502Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007503
Barry Warsaw53699e91996-12-10 23:23:01 +00007504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007505posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007506{
Victor Stinner8c62be82010-05-06 00:08:46 +00007507 int fd, res;
7508 if (!PyArg_ParseTuple(args, "i:close", &fd))
7509 return NULL;
7510 if (!_PyVerify_fd(fd))
7511 return posix_error();
7512 Py_BEGIN_ALLOW_THREADS
7513 res = close(fd);
7514 Py_END_ALLOW_THREADS
7515 if (res < 0)
7516 return posix_error();
7517 Py_INCREF(Py_None);
7518 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007519}
7520
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007521
Victor Stinner8c62be82010-05-06 00:08:46 +00007522PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007523"closerange(fd_low, fd_high)\n\n\
7524Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7525
7526static PyObject *
7527posix_closerange(PyObject *self, PyObject *args)
7528{
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 int fd_from, fd_to, i;
7530 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7531 return NULL;
7532 Py_BEGIN_ALLOW_THREADS
7533 for (i = fd_from; i < fd_to; i++)
7534 if (_PyVerify_fd(i))
7535 close(i);
7536 Py_END_ALLOW_THREADS
7537 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007538}
7539
7540
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007541PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007542"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007543Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007544
Barry Warsaw53699e91996-12-10 23:23:01 +00007545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007546posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007547{
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 int fd;
7549 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7550 return NULL;
7551 if (!_PyVerify_fd(fd))
7552 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 if (fd < 0)
7555 return posix_error();
7556 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007557}
7558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007560PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007561"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007562Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007563
Barry Warsaw53699e91996-12-10 23:23:01 +00007564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007565posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007566{
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 int fd, fd2, res;
7568 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7569 return NULL;
7570 if (!_PyVerify_fd_dup2(fd, fd2))
7571 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 if (res < 0)
7574 return posix_error();
7575 Py_INCREF(Py_None);
7576 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007577}
7578
Ross Lagerwall7807c352011-03-17 20:20:30 +02007579#ifdef HAVE_LOCKF
7580PyDoc_STRVAR(posix_lockf__doc__,
7581"lockf(fd, cmd, len)\n\n\
7582Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7583fd is an open file descriptor.\n\
7584cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7585F_TEST.\n\
7586len specifies the section of the file to lock.");
7587
7588static PyObject *
7589posix_lockf(PyObject *self, PyObject *args)
7590{
7591 int fd, cmd, res;
7592 off_t len;
7593 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7594 &fd, &cmd, _parse_off_t, &len))
7595 return NULL;
7596
7597 Py_BEGIN_ALLOW_THREADS
7598 res = lockf(fd, cmd, len);
7599 Py_END_ALLOW_THREADS
7600
7601 if (res < 0)
7602 return posix_error();
7603
7604 Py_RETURN_NONE;
7605}
7606#endif
7607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007609PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007610"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007611Set the current position of a file descriptor.\n\
7612Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007613
Barry Warsaw53699e91996-12-10 23:23:01 +00007614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007615posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007616{
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007618#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007620#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007622#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007623 PyObject *posobj;
7624 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007626#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7628 switch (how) {
7629 case 0: how = SEEK_SET; break;
7630 case 1: how = SEEK_CUR; break;
7631 case 2: how = SEEK_END; break;
7632 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007633#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007634
Ross Lagerwall8e749672011-03-17 21:54:07 +02007635#if !defined(HAVE_LARGEFILE_SUPPORT)
7636 pos = PyLong_AsLong(posobj);
7637#else
7638 pos = PyLong_AsLongLong(posobj);
7639#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 if (PyErr_Occurred())
7641 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007642
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 if (!_PyVerify_fd(fd))
7644 return posix_error();
7645 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007646#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007648#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007650#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 Py_END_ALLOW_THREADS
7652 if (res < 0)
7653 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007654
7655#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007657#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007659#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007660}
7661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007663PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007664"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007665Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007666
Barry Warsaw53699e91996-12-10 23:23:01 +00007667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007668posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 int fd, size;
7671 Py_ssize_t n;
7672 PyObject *buffer;
7673 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7674 return NULL;
7675 if (size < 0) {
7676 errno = EINVAL;
7677 return posix_error();
7678 }
7679 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7680 if (buffer == NULL)
7681 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007682 if (!_PyVerify_fd(fd)) {
7683 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007685 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 Py_BEGIN_ALLOW_THREADS
7687 n = read(fd, PyBytes_AS_STRING(buffer), size);
7688 Py_END_ALLOW_THREADS
7689 if (n < 0) {
7690 Py_DECREF(buffer);
7691 return posix_error();
7692 }
7693 if (n != size)
7694 _PyBytes_Resize(&buffer, n);
7695 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007696}
7697
Ross Lagerwall7807c352011-03-17 20:20:30 +02007698#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7699 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007700static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007701iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7702{
7703 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007704 Py_ssize_t blen, total = 0;
7705
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007706 *iov = PyMem_New(struct iovec, cnt);
7707 if (*iov == NULL) {
7708 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007709 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007710 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007711
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007712 *buf = PyMem_New(Py_buffer, cnt);
7713 if (*buf == NULL) {
7714 PyMem_Del(*iov);
7715 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007716 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007717 }
7718
7719 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007720 PyObject *item = PySequence_GetItem(seq, i);
7721 if (item == NULL)
7722 goto fail;
7723 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7724 Py_DECREF(item);
7725 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007726 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007727 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007728 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007729 blen = (*buf)[i].len;
7730 (*iov)[i].iov_len = blen;
7731 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007732 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007733 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007734
7735fail:
7736 PyMem_Del(*iov);
7737 for (j = 0; j < i; j++) {
7738 PyBuffer_Release(&(*buf)[j]);
7739 }
7740 PyMem_Del(*buf);
7741 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007742}
7743
7744static void
7745iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7746{
7747 int i;
7748 PyMem_Del(iov);
7749 for (i = 0; i < cnt; i++) {
7750 PyBuffer_Release(&buf[i]);
7751 }
7752 PyMem_Del(buf);
7753}
7754#endif
7755
Ross Lagerwall7807c352011-03-17 20:20:30 +02007756#ifdef HAVE_READV
7757PyDoc_STRVAR(posix_readv__doc__,
7758"readv(fd, buffers) -> bytesread\n\n\
7759Read from a file descriptor into a number of writable buffers. buffers\n\
7760is an arbitrary sequence of writable buffers.\n\
7761Returns the total number of bytes read.");
7762
7763static PyObject *
7764posix_readv(PyObject *self, PyObject *args)
7765{
7766 int fd, cnt;
7767 Py_ssize_t n;
7768 PyObject *seq;
7769 struct iovec *iov;
7770 Py_buffer *buf;
7771
7772 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7773 return NULL;
7774 if (!PySequence_Check(seq)) {
7775 PyErr_SetString(PyExc_TypeError,
7776 "readv() arg 2 must be a sequence");
7777 return NULL;
7778 }
7779 cnt = PySequence_Size(seq);
7780
7781 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7782 return NULL;
7783
7784 Py_BEGIN_ALLOW_THREADS
7785 n = readv(fd, iov, cnt);
7786 Py_END_ALLOW_THREADS
7787
7788 iov_cleanup(iov, buf, cnt);
7789 return PyLong_FromSsize_t(n);
7790}
7791#endif
7792
7793#ifdef HAVE_PREAD
7794PyDoc_STRVAR(posix_pread__doc__,
7795"pread(fd, buffersize, offset) -> string\n\n\
7796Read from a file descriptor, fd, at a position of offset. It will read up\n\
7797to buffersize number of bytes. The file offset remains unchanged.");
7798
7799static PyObject *
7800posix_pread(PyObject *self, PyObject *args)
7801{
7802 int fd, size;
7803 off_t offset;
7804 Py_ssize_t n;
7805 PyObject *buffer;
7806 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7807 return NULL;
7808
7809 if (size < 0) {
7810 errno = EINVAL;
7811 return posix_error();
7812 }
7813 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7814 if (buffer == NULL)
7815 return NULL;
7816 if (!_PyVerify_fd(fd)) {
7817 Py_DECREF(buffer);
7818 return posix_error();
7819 }
7820 Py_BEGIN_ALLOW_THREADS
7821 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7822 Py_END_ALLOW_THREADS
7823 if (n < 0) {
7824 Py_DECREF(buffer);
7825 return posix_error();
7826 }
7827 if (n != size)
7828 _PyBytes_Resize(&buffer, n);
7829 return buffer;
7830}
7831#endif
7832
7833PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007834"write(fd, data) -> byteswritten\n\n\
7835Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007836
7837static PyObject *
7838posix_write(PyObject *self, PyObject *args)
7839{
7840 Py_buffer pbuf;
7841 int fd;
7842 Py_ssize_t size, len;
7843
7844 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7845 return NULL;
7846 if (!_PyVerify_fd(fd)) {
7847 PyBuffer_Release(&pbuf);
7848 return posix_error();
7849 }
7850 len = pbuf.len;
7851 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007852#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007853 if (len > INT_MAX)
7854 len = INT_MAX;
7855 size = write(fd, pbuf.buf, (int)len);
7856#else
7857 size = write(fd, pbuf.buf, len);
7858#endif
7859 Py_END_ALLOW_THREADS
7860 PyBuffer_Release(&pbuf);
7861 if (size < 0)
7862 return posix_error();
7863 return PyLong_FromSsize_t(size);
7864}
7865
7866#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007867PyDoc_STRVAR(posix_sendfile__doc__,
7868"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7869sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7870 -> byteswritten\n\
7871Copy nbytes bytes from file descriptor in to file descriptor out.");
7872
7873static PyObject *
7874posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7875{
7876 int in, out;
7877 Py_ssize_t ret;
7878 off_t offset;
7879
7880#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7881#ifndef __APPLE__
7882 Py_ssize_t len;
7883#endif
7884 PyObject *headers = NULL, *trailers = NULL;
7885 Py_buffer *hbuf, *tbuf;
7886 off_t sbytes;
7887 struct sf_hdtr sf;
7888 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007889 static char *keywords[] = {"out", "in",
7890 "offset", "count",
7891 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007892
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02007893 sf.headers = NULL;
7894 sf.trailers = NULL;
7895
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007896#ifdef __APPLE__
7897 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007898 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007899#else
7900 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007901 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007902#endif
7903 &headers, &trailers, &flags))
7904 return NULL;
7905 if (headers != NULL) {
7906 if (!PySequence_Check(headers)) {
7907 PyErr_SetString(PyExc_TypeError,
7908 "sendfile() headers must be a sequence or None");
7909 return NULL;
7910 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007911 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007912 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007913 if (sf.hdr_cnt > 0 &&
7914 !(i = iov_setup(&(sf.headers), &hbuf,
7915 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007916 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007917#ifdef __APPLE__
7918 sbytes += i;
7919#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007920 }
7921 }
7922 if (trailers != NULL) {
7923 if (!PySequence_Check(trailers)) {
7924 PyErr_SetString(PyExc_TypeError,
7925 "sendfile() trailers must be a sequence or None");
7926 return NULL;
7927 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007928 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007929 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007930 if (sf.trl_cnt > 0 &&
7931 !(i = iov_setup(&(sf.trailers), &tbuf,
7932 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007933 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007934#ifdef __APPLE__
7935 sbytes += i;
7936#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007937 }
7938 }
7939
7940 Py_BEGIN_ALLOW_THREADS
7941#ifdef __APPLE__
7942 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7943#else
7944 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7945#endif
7946 Py_END_ALLOW_THREADS
7947
7948 if (sf.headers != NULL)
7949 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7950 if (sf.trailers != NULL)
7951 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7952
7953 if (ret < 0) {
7954 if ((errno == EAGAIN) || (errno == EBUSY)) {
7955 if (sbytes != 0) {
7956 // some data has been sent
7957 goto done;
7958 }
7959 else {
7960 // no data has been sent; upper application is supposed
7961 // to retry on EAGAIN or EBUSY
7962 return posix_error();
7963 }
7964 }
7965 return posix_error();
7966 }
7967 goto done;
7968
7969done:
7970 #if !defined(HAVE_LARGEFILE_SUPPORT)
7971 return Py_BuildValue("l", sbytes);
7972 #else
7973 return Py_BuildValue("L", sbytes);
7974 #endif
7975
7976#else
7977 Py_ssize_t count;
7978 PyObject *offobj;
7979 static char *keywords[] = {"out", "in",
7980 "offset", "count", NULL};
7981 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7982 keywords, &out, &in, &offobj, &count))
7983 return NULL;
7984#ifdef linux
7985 if (offobj == Py_None) {
7986 Py_BEGIN_ALLOW_THREADS
7987 ret = sendfile(out, in, NULL, count);
7988 Py_END_ALLOW_THREADS
7989 if (ret < 0)
7990 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007991 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007992 }
7993#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007994 if (!_parse_off_t(offobj, &offset))
7995 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007996 Py_BEGIN_ALLOW_THREADS
7997 ret = sendfile(out, in, &offset, count);
7998 Py_END_ALLOW_THREADS
7999 if (ret < 0)
8000 return posix_error();
8001 return Py_BuildValue("n", ret);
8002#endif
8003}
8004#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008005
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008006PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008007"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008008Like stat(), but for an open file descriptor.\n\
8009Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008010
Barry Warsaw53699e91996-12-10 23:23:01 +00008011static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008012posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008013{
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 int fd;
8015 STRUCT_STAT st;
8016 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008017 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008019#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 /* on OpenVMS we must ensure that all bytes are written to the file */
8021 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008022#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 Py_BEGIN_ALLOW_THREADS
8024 res = FSTAT(fd, &st);
8025 Py_END_ALLOW_THREADS
8026 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008027#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008028 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008029#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008031#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 }
Tim Peters5aa91602002-01-30 05:46:57 +00008033
Victor Stinner4195b5c2012-02-08 23:03:19 +01008034 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008035}
8036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008037PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008038"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008039Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008040connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008041
8042static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008043posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008044{
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 int fd;
8046 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8047 return NULL;
8048 if (!_PyVerify_fd(fd))
8049 return PyBool_FromLong(0);
8050 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008051}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008052
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008053#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008054PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008055"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008056Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008057
Barry Warsaw53699e91996-12-10 23:23:01 +00008058static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008059posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008060{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008061#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 int fds[2];
8063 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 if (res != 0)
8066 return posix_error();
8067 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008068#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 HANDLE read, write;
8070 int read_fd, write_fd;
8071 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008074 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008075 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8076 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8077 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008078#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00008079}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008080#endif /* HAVE_PIPE */
8081
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008082#ifdef HAVE_PIPE2
8083PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008084"pipe2(flags) -> (read_end, write_end)\n\n\
8085Create a pipe with flags set atomically.\n\
8086flags can be constructed by ORing together one or more of these values:\n\
8087O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008088");
8089
8090static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008091posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008092{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008093 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008094 int fds[2];
8095 int res;
8096
Serhiy Storchaka78980432013-01-15 01:12:17 +02008097 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008098 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008099 return NULL;
8100
8101 res = pipe2(fds, flags);
8102 if (res != 0)
8103 return posix_error();
8104 return Py_BuildValue("(ii)", fds[0], fds[1]);
8105}
8106#endif /* HAVE_PIPE2 */
8107
Ross Lagerwall7807c352011-03-17 20:20:30 +02008108#ifdef HAVE_WRITEV
8109PyDoc_STRVAR(posix_writev__doc__,
8110"writev(fd, buffers) -> byteswritten\n\n\
8111Write the contents of buffers to a file descriptor, where buffers is an\n\
8112arbitrary sequence of buffers.\n\
8113Returns the total bytes written.");
8114
8115static PyObject *
8116posix_writev(PyObject *self, PyObject *args)
8117{
8118 int fd, cnt;
8119 Py_ssize_t res;
8120 PyObject *seq;
8121 struct iovec *iov;
8122 Py_buffer *buf;
8123 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8124 return NULL;
8125 if (!PySequence_Check(seq)) {
8126 PyErr_SetString(PyExc_TypeError,
8127 "writev() arg 2 must be a sequence");
8128 return NULL;
8129 }
8130 cnt = PySequence_Size(seq);
8131
8132 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8133 return NULL;
8134 }
8135
8136 Py_BEGIN_ALLOW_THREADS
8137 res = writev(fd, iov, cnt);
8138 Py_END_ALLOW_THREADS
8139
8140 iov_cleanup(iov, buf, cnt);
8141 return PyLong_FromSsize_t(res);
8142}
8143#endif
8144
8145#ifdef HAVE_PWRITE
8146PyDoc_STRVAR(posix_pwrite__doc__,
8147"pwrite(fd, string, offset) -> byteswritten\n\n\
8148Write string to a file descriptor, fd, from offset, leaving the file\n\
8149offset unchanged.");
8150
8151static PyObject *
8152posix_pwrite(PyObject *self, PyObject *args)
8153{
8154 Py_buffer pbuf;
8155 int fd;
8156 off_t offset;
8157 Py_ssize_t size;
8158
8159 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8160 return NULL;
8161
8162 if (!_PyVerify_fd(fd)) {
8163 PyBuffer_Release(&pbuf);
8164 return posix_error();
8165 }
8166 Py_BEGIN_ALLOW_THREADS
8167 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8168 Py_END_ALLOW_THREADS
8169 PyBuffer_Release(&pbuf);
8170 if (size < 0)
8171 return posix_error();
8172 return PyLong_FromSsize_t(size);
8173}
8174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008175
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008176#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008177PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008178"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8179Create a FIFO (a POSIX named pipe).\n\
8180\n\
8181If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8182 and path should be relative; path will then be relative to that directory.\n\
8183dir_fd may not be implemented on your platform.\n\
8184 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008185
Barry Warsaw53699e91996-12-10 23:23:01 +00008186static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008187posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008188{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008189 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008191 int dir_fd = DEFAULT_DIR_FD;
8192 int result;
8193 PyObject *return_value = NULL;
8194 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8195
8196 memset(&path, 0, sizeof(path));
8197 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8198 path_converter, &path,
8199 &mode,
8200#ifdef HAVE_MKFIFOAT
8201 dir_fd_converter, &dir_fd
8202#else
8203 dir_fd_unavailable, &dir_fd
8204#endif
8205 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008207
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008209#ifdef HAVE_MKFIFOAT
8210 if (dir_fd != DEFAULT_DIR_FD)
8211 result = mkfifoat(dir_fd, path.narrow, mode);
8212 else
8213#endif
8214 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008216
8217 if (result < 0) {
8218 return_value = posix_error();
8219 goto exit;
8220 }
8221
8222 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008224
8225exit:
8226 path_cleanup(&path);
8227 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008228}
8229#endif
8230
Neal Norwitz11690112002-07-30 01:08:28 +00008231#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008232PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008233"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008234Create a filesystem node (file, device special file or named pipe)\n\
8235named filename. mode specifies both the permissions to use and the\n\
8236type of node to be created, being combined (bitwise OR) with one of\n\
8237S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008238device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008239os.makedev()), otherwise it is ignored.\n\
8240\n\
8241If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8242 and path should be relative; path will then be relative to that directory.\n\
8243dir_fd may not be implemented on your platform.\n\
8244 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008245
8246
8247static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008248posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008249{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008250 path_t path;
8251 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008253 int dir_fd = DEFAULT_DIR_FD;
8254 int result;
8255 PyObject *return_value = NULL;
8256 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8257
8258 memset(&path, 0, sizeof(path));
8259 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8260 path_converter, &path,
8261 &mode, &device,
8262#ifdef HAVE_MKNODAT
8263 dir_fd_converter, &dir_fd
8264#else
8265 dir_fd_unavailable, &dir_fd
8266#endif
8267 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008269
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008271#ifdef HAVE_MKNODAT
8272 if (dir_fd != DEFAULT_DIR_FD)
8273 result = mknodat(dir_fd, path.narrow, mode, device);
8274 else
8275#endif
8276 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008278
8279 if (result < 0) {
8280 return_value = posix_error();
8281 goto exit;
8282 }
8283
8284 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008285 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008286
Larry Hastings9cf065c2012-06-22 16:30:09 -07008287exit:
8288 path_cleanup(&path);
8289 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008290}
8291#endif
8292
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008293#ifdef HAVE_DEVICE_MACROS
8294PyDoc_STRVAR(posix_major__doc__,
8295"major(device) -> major number\n\
8296Extracts a device major number from a raw device number.");
8297
8298static PyObject *
8299posix_major(PyObject *self, PyObject *args)
8300{
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 int device;
8302 if (!PyArg_ParseTuple(args, "i:major", &device))
8303 return NULL;
8304 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008305}
8306
8307PyDoc_STRVAR(posix_minor__doc__,
8308"minor(device) -> minor number\n\
8309Extracts a device minor number from a raw device number.");
8310
8311static PyObject *
8312posix_minor(PyObject *self, PyObject *args)
8313{
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 int device;
8315 if (!PyArg_ParseTuple(args, "i:minor", &device))
8316 return NULL;
8317 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008318}
8319
8320PyDoc_STRVAR(posix_makedev__doc__,
8321"makedev(major, minor) -> device number\n\
8322Composes a raw device number from the major and minor device numbers.");
8323
8324static PyObject *
8325posix_makedev(PyObject *self, PyObject *args)
8326{
Victor Stinner8c62be82010-05-06 00:08:46 +00008327 int major, minor;
8328 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8329 return NULL;
8330 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008331}
8332#endif /* device macros */
8333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008334
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008335#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008336PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008337"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008338Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008339
Barry Warsaw53699e91996-12-10 23:23:01 +00008340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008341posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008342{
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 int fd;
8344 off_t length;
8345 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008346
Ross Lagerwall7807c352011-03-17 20:20:30 +02008347 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008349
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 Py_BEGIN_ALLOW_THREADS
8351 res = ftruncate(fd, length);
8352 Py_END_ALLOW_THREADS
8353 if (res < 0)
8354 return posix_error();
8355 Py_INCREF(Py_None);
8356 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008357}
8358#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008359
Ross Lagerwall7807c352011-03-17 20:20:30 +02008360#ifdef HAVE_TRUNCATE
8361PyDoc_STRVAR(posix_truncate__doc__,
8362"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008363Truncate the file given by path to length bytes.\n\
8364On some platforms, path may also be specified as an open file descriptor.\n\
8365 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008366
8367static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008368posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008369{
Georg Brandl306336b2012-06-24 12:55:33 +02008370 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008371 off_t length;
8372 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008373 PyObject *result = NULL;
8374 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008375
Georg Brandl306336b2012-06-24 12:55:33 +02008376 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008377 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008378#ifdef HAVE_FTRUNCATE
8379 path.allow_fd = 1;
8380#endif
8381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8382 path_converter, &path,
8383 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008384 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008385
8386 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008387#ifdef HAVE_FTRUNCATE
8388 if (path.fd != -1)
8389 res = ftruncate(path.fd, length);
8390 else
8391#endif
8392 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008393 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008394 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008395 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008396 else {
8397 Py_INCREF(Py_None);
8398 result = Py_None;
8399 }
8400 path_cleanup(&path);
8401 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008402}
8403#endif
8404
8405#ifdef HAVE_POSIX_FALLOCATE
8406PyDoc_STRVAR(posix_posix_fallocate__doc__,
8407"posix_fallocate(fd, offset, len)\n\n\
8408Ensures that enough disk space is allocated for the file specified by fd\n\
8409starting from offset and continuing for len bytes.");
8410
8411static PyObject *
8412posix_posix_fallocate(PyObject *self, PyObject *args)
8413{
8414 off_t len, offset;
8415 int res, fd;
8416
8417 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8418 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8419 return NULL;
8420
8421 Py_BEGIN_ALLOW_THREADS
8422 res = posix_fallocate(fd, offset, len);
8423 Py_END_ALLOW_THREADS
8424 if (res != 0) {
8425 errno = res;
8426 return posix_error();
8427 }
8428 Py_RETURN_NONE;
8429}
8430#endif
8431
8432#ifdef HAVE_POSIX_FADVISE
8433PyDoc_STRVAR(posix_posix_fadvise__doc__,
8434"posix_fadvise(fd, offset, len, advice)\n\n\
8435Announces an intention to access data in a specific pattern thus allowing\n\
8436the kernel to make optimizations.\n\
8437The advice applies to the region of the file specified by fd starting at\n\
8438offset and continuing for len bytes.\n\
8439advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8440POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8441POSIX_FADV_DONTNEED.");
8442
8443static PyObject *
8444posix_posix_fadvise(PyObject *self, PyObject *args)
8445{
8446 off_t len, offset;
8447 int res, fd, advice;
8448
8449 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8450 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8451 return NULL;
8452
8453 Py_BEGIN_ALLOW_THREADS
8454 res = posix_fadvise(fd, offset, len, advice);
8455 Py_END_ALLOW_THREADS
8456 if (res != 0) {
8457 errno = res;
8458 return posix_error();
8459 }
8460 Py_RETURN_NONE;
8461}
8462#endif
8463
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008464#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008465PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008466"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008467Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008468
Fred Drake762e2061999-08-26 17:23:54 +00008469/* Save putenv() parameters as values here, so we can collect them when they
8470 * get re-set with another call for the same key. */
8471static PyObject *posix_putenv_garbage;
8472
Tim Peters5aa91602002-01-30 05:46:57 +00008473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008474posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008475{
Victor Stinner84ae1182010-05-06 22:05:07 +00008476 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008477#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008478 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008479 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008480
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008482 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008483 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008485
Victor Stinner65170952011-11-22 22:16:17 +01008486 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008487 if (newstr == NULL) {
8488 PyErr_NoMemory();
8489 goto error;
8490 }
Victor Stinner65170952011-11-22 22:16:17 +01008491 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8492 PyErr_Format(PyExc_ValueError,
8493 "the environment variable is longer than %u characters",
8494 _MAX_ENV);
8495 goto error;
8496 }
8497
Victor Stinner8c62be82010-05-06 00:08:46 +00008498 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008499 if (newenv == NULL)
8500 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008501 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008503 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008504 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008505#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008506 PyObject *os1, *os2;
8507 char *s1, *s2;
8508 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008509
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008510 if (!PyArg_ParseTuple(args,
8511 "O&O&:putenv",
8512 PyUnicode_FSConverter, &os1,
8513 PyUnicode_FSConverter, &os2))
8514 return NULL;
8515 s1 = PyBytes_AsString(os1);
8516 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008517
Victor Stinner65170952011-11-22 22:16:17 +01008518 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008519 if (newstr == NULL) {
8520 PyErr_NoMemory();
8521 goto error;
8522 }
8523
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008525 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008527 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008528 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008529#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008530
Victor Stinner8c62be82010-05-06 00:08:46 +00008531 /* Install the first arg and newstr in posix_putenv_garbage;
8532 * this will cause previous value to be collected. This has to
8533 * happen after the real putenv() call because the old value
8534 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008535 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008536 /* really not much we can do; just leak */
8537 PyErr_Clear();
8538 }
8539 else {
8540 Py_DECREF(newstr);
8541 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008542
Martin v. Löwis011e8422009-05-05 04:43:17 +00008543#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008544 Py_DECREF(os1);
8545 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008546#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008547 Py_RETURN_NONE;
8548
8549error:
8550#ifndef MS_WINDOWS
8551 Py_DECREF(os1);
8552 Py_DECREF(os2);
8553#endif
8554 Py_XDECREF(newstr);
8555 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008556}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008557#endif /* putenv */
8558
Guido van Rossumc524d952001-10-19 01:31:59 +00008559#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008560PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008561"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008562Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008563
8564static PyObject *
8565posix_unsetenv(PyObject *self, PyObject *args)
8566{
Victor Stinner65170952011-11-22 22:16:17 +01008567 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008568#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008569 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008570#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008571
8572 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008573
Victor Stinner65170952011-11-22 22:16:17 +01008574 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008575 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008576
Victor Stinner984890f2011-11-24 13:53:38 +01008577#ifdef HAVE_BROKEN_UNSETENV
8578 unsetenv(PyBytes_AS_STRING(name));
8579#else
Victor Stinner65170952011-11-22 22:16:17 +01008580 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008581 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008582 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008583 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008584 }
Victor Stinner984890f2011-11-24 13:53:38 +01008585#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008586
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 /* Remove the key from posix_putenv_garbage;
8588 * this will cause it to be collected. This has to
8589 * happen after the real unsetenv() call because the
8590 * old value was still accessible until then.
8591 */
Victor Stinner65170952011-11-22 22:16:17 +01008592 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008593 /* really not much we can do; just leak */
8594 PyErr_Clear();
8595 }
Victor Stinner65170952011-11-22 22:16:17 +01008596 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008597 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008598}
8599#endif /* unsetenv */
8600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008601PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008602"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008603Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008604
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008606posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008607{
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 int code;
8609 char *message;
8610 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8611 return NULL;
8612 message = strerror(code);
8613 if (message == NULL) {
8614 PyErr_SetString(PyExc_ValueError,
8615 "strerror() argument out of range");
8616 return NULL;
8617 }
Victor Stinner1b579672011-12-17 05:47:23 +01008618 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008619}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008620
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008621
Guido van Rossumc9641791998-08-04 15:26:23 +00008622#ifdef HAVE_SYS_WAIT_H
8623
Fred Drake106c1a02002-04-23 15:58:02 +00008624#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008625PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008626"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008627Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008628
8629static PyObject *
8630posix_WCOREDUMP(PyObject *self, PyObject *args)
8631{
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 WAIT_TYPE status;
8633 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008634
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8636 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008637
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008639}
8640#endif /* WCOREDUMP */
8641
8642#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008643PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008644"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008645Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008646job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008647
8648static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008649posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008650{
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 WAIT_TYPE status;
8652 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008653
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8655 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008656
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008658}
8659#endif /* WIFCONTINUED */
8660
Guido van Rossumc9641791998-08-04 15:26:23 +00008661#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008662PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008663"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008664Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008665
8666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008667posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008668{
Victor Stinner8c62be82010-05-06 00:08:46 +00008669 WAIT_TYPE status;
8670 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008671
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8673 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008674
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008676}
8677#endif /* WIFSTOPPED */
8678
8679#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008680PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008681"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008682Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008683
8684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008685posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008686{
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 WAIT_TYPE status;
8688 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008689
Victor Stinner8c62be82010-05-06 00:08:46 +00008690 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8691 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008692
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008694}
8695#endif /* WIFSIGNALED */
8696
8697#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008698PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008699"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008700Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008701system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008702
8703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008704posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008705{
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 WAIT_TYPE status;
8707 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008708
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8710 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008711
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008713}
8714#endif /* WIFEXITED */
8715
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008716#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008717PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008718"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008719Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008720
8721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008722posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008723{
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 WAIT_TYPE status;
8725 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008726
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8728 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008729
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008731}
8732#endif /* WEXITSTATUS */
8733
8734#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008735PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008736"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008737Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008738value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008739
8740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008741posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008742{
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 WAIT_TYPE status;
8744 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008745
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8747 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008748
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008750}
8751#endif /* WTERMSIG */
8752
8753#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008754PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008755"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008756Return the signal that stopped the process that provided\n\
8757the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008758
8759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008760posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008761{
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 WAIT_TYPE status;
8763 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008764
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8766 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008767
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008769}
8770#endif /* WSTOPSIG */
8771
8772#endif /* HAVE_SYS_WAIT_H */
8773
8774
Thomas Wouters477c8d52006-05-27 19:21:47 +00008775#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008776#ifdef _SCO_DS
8777/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8778 needed definitions in sys/statvfs.h */
8779#define _SVID3
8780#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008781#include <sys/statvfs.h>
8782
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008783static PyObject*
8784_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8786 if (v == NULL)
8787 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008788
8789#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8791 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8792 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8793 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8794 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8795 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8796 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8797 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8798 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8799 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008800#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8802 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8803 PyStructSequence_SET_ITEM(v, 2,
8804 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8805 PyStructSequence_SET_ITEM(v, 3,
8806 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8807 PyStructSequence_SET_ITEM(v, 4,
8808 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8809 PyStructSequence_SET_ITEM(v, 5,
8810 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8811 PyStructSequence_SET_ITEM(v, 6,
8812 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8813 PyStructSequence_SET_ITEM(v, 7,
8814 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8815 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8816 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008817#endif
8818
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008820}
8821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008822PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008823"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008824Perform an fstatvfs system call on the given fd.\n\
8825Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008826
8827static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008828posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008829{
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 int fd, res;
8831 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008832
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8834 return NULL;
8835 Py_BEGIN_ALLOW_THREADS
8836 res = fstatvfs(fd, &st);
8837 Py_END_ALLOW_THREADS
8838 if (res != 0)
8839 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008840
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008842}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008843#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008844
8845
Thomas Wouters477c8d52006-05-27 19:21:47 +00008846#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008847#include <sys/statvfs.h>
8848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008849PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008850"statvfs(path)\n\n\
8851Perform a statvfs system call on the given path.\n\
8852\n\
8853path may always be specified as a string.\n\
8854On some platforms, path may also be specified as an open file descriptor.\n\
8855 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008856
8857static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008858posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008859{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008860 static char *keywords[] = {"path", NULL};
8861 path_t path;
8862 int result;
8863 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008865
Larry Hastings9cf065c2012-06-22 16:30:09 -07008866 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008867 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008868#ifdef HAVE_FSTATVFS
8869 path.allow_fd = 1;
8870#endif
8871 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8872 path_converter, &path
8873 ))
8874 return NULL;
8875
8876 Py_BEGIN_ALLOW_THREADS
8877#ifdef HAVE_FSTATVFS
8878 if (path.fd != -1) {
8879#ifdef __APPLE__
8880 /* handle weak-linking on Mac OS X 10.3 */
8881 if (fstatvfs == NULL) {
8882 fd_specified("statvfs", path.fd);
8883 goto exit;
8884 }
8885#endif
8886 result = fstatvfs(path.fd, &st);
8887 }
8888 else
8889#endif
8890 result = statvfs(path.narrow, &st);
8891 Py_END_ALLOW_THREADS
8892
8893 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008894 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008895 goto exit;
8896 }
8897
8898 return_value = _pystatvfs_fromstructstatvfs(st);
8899
8900exit:
8901 path_cleanup(&path);
8902 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008903}
8904#endif /* HAVE_STATVFS */
8905
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008906#ifdef MS_WINDOWS
8907PyDoc_STRVAR(win32__getdiskusage__doc__,
8908"_getdiskusage(path) -> (total, free)\n\n\
8909Return disk usage statistics about the given path as (total, free) tuple.");
8910
8911static PyObject *
8912win32__getdiskusage(PyObject *self, PyObject *args)
8913{
8914 BOOL retval;
8915 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008916 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008917
Victor Stinner6139c1b2011-11-09 22:14:14 +01008918 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008919 return NULL;
8920
8921 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008922 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008923 Py_END_ALLOW_THREADS
8924 if (retval == 0)
8925 return PyErr_SetFromWindowsErr(0);
8926
8927 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8928}
8929#endif
8930
8931
Fred Drakec9680921999-12-13 16:37:25 +00008932/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8933 * It maps strings representing configuration variable names to
8934 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008935 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008936 * rarely-used constants. There are three separate tables that use
8937 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008938 *
8939 * This code is always included, even if none of the interfaces that
8940 * need it are included. The #if hackery needed to avoid it would be
8941 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008942 */
8943struct constdef {
8944 char *name;
8945 long value;
8946};
8947
Fred Drake12c6e2d1999-12-14 21:25:03 +00008948static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008949conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008950 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008951{
Christian Heimes217cfd12007-12-02 14:31:20 +00008952 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008953 *valuep = PyLong_AS_LONG(arg);
8954 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008955 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008956 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008957 /* look up the value in the table using a binary search */
8958 size_t lo = 0;
8959 size_t mid;
8960 size_t hi = tablesize;
8961 int cmp;
8962 const char *confname;
8963 if (!PyUnicode_Check(arg)) {
8964 PyErr_SetString(PyExc_TypeError,
8965 "configuration names must be strings or integers");
8966 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008968 confname = _PyUnicode_AsString(arg);
8969 if (confname == NULL)
8970 return 0;
8971 while (lo < hi) {
8972 mid = (lo + hi) / 2;
8973 cmp = strcmp(confname, table[mid].name);
8974 if (cmp < 0)
8975 hi = mid;
8976 else if (cmp > 0)
8977 lo = mid + 1;
8978 else {
8979 *valuep = table[mid].value;
8980 return 1;
8981 }
8982 }
8983 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8984 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008986}
8987
8988
8989#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8990static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008991#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008993#endif
8994#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008996#endif
Fred Drakec9680921999-12-13 16:37:25 +00008997#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
9003#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009005#endif
9006#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009008#endif
9009#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009011#endif
9012#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009014#endif
9015#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009017#endif
9018#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009020#endif
9021#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009023#endif
9024#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009026#endif
9027#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009029#endif
9030#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009032#endif
9033#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009035#endif
9036#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009038#endif
9039#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009041#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009042#ifdef _PC_ACL_ENABLED
9043 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9044#endif
9045#ifdef _PC_MIN_HOLE_SIZE
9046 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9047#endif
9048#ifdef _PC_ALLOC_SIZE_MIN
9049 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9050#endif
9051#ifdef _PC_REC_INCR_XFER_SIZE
9052 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9053#endif
9054#ifdef _PC_REC_MAX_XFER_SIZE
9055 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9056#endif
9057#ifdef _PC_REC_MIN_XFER_SIZE
9058 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9059#endif
9060#ifdef _PC_REC_XFER_ALIGN
9061 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9062#endif
9063#ifdef _PC_SYMLINK_MAX
9064 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9065#endif
9066#ifdef _PC_XATTR_ENABLED
9067 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9068#endif
9069#ifdef _PC_XATTR_EXISTS
9070 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9071#endif
9072#ifdef _PC_TIMESTAMP_RESOLUTION
9073 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9074#endif
Fred Drakec9680921999-12-13 16:37:25 +00009075};
9076
Fred Drakec9680921999-12-13 16:37:25 +00009077static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009078conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009079{
9080 return conv_confname(arg, valuep, posix_constants_pathconf,
9081 sizeof(posix_constants_pathconf)
9082 / sizeof(struct constdef));
9083}
9084#endif
9085
9086#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009087PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009088"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009089Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009090If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009091
9092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009093posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009094{
9095 PyObject *result = NULL;
9096 int name, fd;
9097
Fred Drake12c6e2d1999-12-14 21:25:03 +00009098 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9099 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009100 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009101
Stefan Krah0e803b32010-11-26 16:16:47 +00009102 errno = 0;
9103 limit = fpathconf(fd, name);
9104 if (limit == -1 && errno != 0)
9105 posix_error();
9106 else
9107 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009108 }
9109 return result;
9110}
9111#endif
9112
9113
9114#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009115PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009116"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009117Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009118If there is no limit, return -1.\n\
9119On some platforms, path may also be specified as an open file descriptor.\n\
9120 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009121
9122static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009123posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009124{
Georg Brandl306336b2012-06-24 12:55:33 +02009125 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009126 PyObject *result = NULL;
9127 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009128 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009129
Georg Brandl306336b2012-06-24 12:55:33 +02009130 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009131 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009132#ifdef HAVE_FPATHCONF
9133 path.allow_fd = 1;
9134#endif
9135 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9136 path_converter, &path,
9137 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009139
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009141#ifdef HAVE_FPATHCONF
9142 if (path.fd != -1)
9143 limit = fpathconf(path.fd, name);
9144 else
9145#endif
9146 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 if (limit == -1 && errno != 0) {
9148 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009149 /* could be a path or name problem */
9150 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009151 else
Victor Stinner292c8352012-10-30 02:17:38 +01009152 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 }
9154 else
9155 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009156 }
Georg Brandl306336b2012-06-24 12:55:33 +02009157 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009158 return result;
9159}
9160#endif
9161
9162#ifdef HAVE_CONFSTR
9163static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009164#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009166#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009167#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009169#endif
9170#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009172#endif
Fred Draked86ed291999-12-15 15:34:33 +00009173#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009175#endif
9176#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009178#endif
9179#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009181#endif
9182#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009184#endif
Fred Drakec9680921999-12-13 16:37:25 +00009185#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
Fred Draked86ed291999-12-15 15:34:33 +00009209#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009211#endif
Fred Drakec9680921999-12-13 16:37:25 +00009212#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
Fred Draked86ed291999-12-15 15:34:33 +00009215#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009217#endif
9218#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009220#endif
9221#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009223#endif
9224#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009226#endif
Fred Drakec9680921999-12-13 16:37:25 +00009227#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009229#endif
9230#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009232#endif
9233#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009235#endif
9236#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009237 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009238#endif
9239#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009241#endif
9242#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009244#endif
9245#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009247#endif
9248#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009250#endif
9251#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009253#endif
9254#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
9257#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009259#endif
9260#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
9263#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
9269#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
Fred Draked86ed291999-12-15 15:34:33 +00009275#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009277#endif
9278#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009280#endif
9281#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009283#endif
9284#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009286#endif
9287#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009289#endif
9290#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009292#endif
9293#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009295#endif
9296#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009298#endif
9299#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009301#endif
9302#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009304#endif
9305#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009307#endif
9308#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009310#endif
9311#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009313#endif
Fred Drakec9680921999-12-13 16:37:25 +00009314};
9315
9316static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009317conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009318{
9319 return conv_confname(arg, valuep, posix_constants_confstr,
9320 sizeof(posix_constants_confstr)
9321 / sizeof(struct constdef));
9322}
9323
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009324PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009325"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009326Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009327
9328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009329posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009330{
9331 PyObject *result = NULL;
9332 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009333 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009334 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009335
Victor Stinnercb043522010-09-10 23:49:04 +00009336 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9337 return NULL;
9338
9339 errno = 0;
9340 len = confstr(name, buffer, sizeof(buffer));
9341 if (len == 0) {
9342 if (errno) {
9343 posix_error();
9344 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009345 }
9346 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009347 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009348 }
9349 }
Victor Stinnercb043522010-09-10 23:49:04 +00009350
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009351 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009352 char *buf = PyMem_Malloc(len);
9353 if (buf == NULL)
9354 return PyErr_NoMemory();
9355 confstr(name, buf, len);
9356 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9357 PyMem_Free(buf);
9358 }
9359 else
9360 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009361 return result;
9362}
9363#endif
9364
9365
9366#ifdef HAVE_SYSCONF
9367static struct constdef posix_constants_sysconf[] = {
9368#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
Fred Draked86ed291999-12-15 15:34:33 +00009398#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009400#endif
9401#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009403#endif
Fred Drakec9680921999-12-13 16:37:25 +00009404#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
Fred Drakec9680921999-12-13 16:37:25 +00009407#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009409#endif
9410#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009412#endif
9413#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009415#endif
9416#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009418#endif
9419#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
Fred Draked86ed291999-12-15 15:34:33 +00009422#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009424#endif
Fred Drakec9680921999-12-13 16:37:25 +00009425#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009427#endif
9428#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009430#endif
9431#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009433#endif
9434#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009436#endif
9437#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
Fred Draked86ed291999-12-15 15:34:33 +00009440#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009442#endif
Fred Drakec9680921999-12-13 16:37:25 +00009443#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009445#endif
9446#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
9449#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
9476#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
9479#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009481#endif
9482#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009484#endif
9485#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009487#endif
9488#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009490#endif
9491#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
9500#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009502#endif
9503#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
9509#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
Fred Draked86ed291999-12-15 15:34:33 +00009512#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009514#endif
Fred Drakec9680921999-12-13 16:37:25 +00009515#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
9518#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
Fred Draked86ed291999-12-15 15:34:33 +00009524#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
Fred Drakec9680921999-12-13 16:37:25 +00009527#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
Fred Draked86ed291999-12-15 15:34:33 +00009530#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
Fred Drakec9680921999-12-13 16:37:25 +00009536#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
Fred Draked86ed291999-12-15 15:34:33 +00009548#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009550#endif
Fred Drakec9680921999-12-13 16:37:25 +00009551#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
Fred Draked86ed291999-12-15 15:34:33 +00009572#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
Fred Drakec9680921999-12-13 16:37:25 +00009575#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
Fred Draked86ed291999-12-15 15:34:33 +00009581#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009583#endif
Fred Drakec9680921999-12-13 16:37:25 +00009584#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
Fred Draked86ed291999-12-15 15:34:33 +00009611#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009613#endif
9614#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
Fred Drakec9680921999-12-13 16:37:25 +00009617#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
9650#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
9659#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
9662#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
9665#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
Fred Draked86ed291999-12-15 15:34:33 +00009722#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
Fred Drakec9680921999-12-13 16:37:25 +00009725#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860};
9861
9862static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009863conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009864{
9865 return conv_confname(arg, valuep, posix_constants_sysconf,
9866 sizeof(posix_constants_sysconf)
9867 / sizeof(struct constdef));
9868}
9869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009870PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009871"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009872Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009873
9874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009875posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009876{
9877 PyObject *result = NULL;
9878 int name;
9879
9880 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +02009881 long value;
Fred Drakec9680921999-12-13 16:37:25 +00009882
9883 errno = 0;
9884 value = sysconf(name);
9885 if (value == -1 && errno != 0)
9886 posix_error();
9887 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009888 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009889 }
9890 return result;
9891}
9892#endif
9893
9894
Fred Drakebec628d1999-12-15 18:31:10 +00009895/* This code is used to ensure that the tables of configuration value names
9896 * are in sorted order as required by conv_confname(), and also to build the
9897 * the exported dictionaries that are used to publish information about the
9898 * names available on the host platform.
9899 *
9900 * Sorting the table at runtime ensures that the table is properly ordered
9901 * when used, even for platforms we're not able to test on. It also makes
9902 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009903 */
Fred Drakebec628d1999-12-15 18:31:10 +00009904
9905static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009906cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009907{
9908 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009910 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009912
9913 return strcmp(c1->name, c2->name);
9914}
9915
9916static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009917setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009919{
Fred Drakebec628d1999-12-15 18:31:10 +00009920 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009921 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009922
9923 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9924 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009925 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009927
Barry Warsaw3155db32000-04-13 15:20:40 +00009928 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 PyObject *o = PyLong_FromLong(table[i].value);
9930 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9931 Py_XDECREF(o);
9932 Py_DECREF(d);
9933 return -1;
9934 }
9935 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009936 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009937 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009938}
9939
Fred Drakebec628d1999-12-15 18:31:10 +00009940/* Return -1 on failure, 0 on success. */
9941static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009942setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009943{
9944#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009945 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009946 sizeof(posix_constants_pathconf)
9947 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009948 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009949 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009950#endif
9951#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009952 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009953 sizeof(posix_constants_confstr)
9954 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009955 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009956 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009957#endif
9958#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009959 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009960 sizeof(posix_constants_sysconf)
9961 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009962 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009963 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009964#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009965 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009966}
Fred Draked86ed291999-12-15 15:34:33 +00009967
9968
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009969PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009970"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009971Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009972in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009973
9974static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009975posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009976{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009977 abort();
9978 /*NOTREACHED*/
9979 Py_FatalError("abort() called from Python code didn't abort!");
9980 return NULL;
9981}
Fred Drakebec628d1999-12-15 18:31:10 +00009982
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009983#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009984PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009985"startfile(filepath [, operation]) - Start a file with its associated\n\
9986application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009987\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009988When \"operation\" is not specified or \"open\", this acts like\n\
9989double-clicking the file in Explorer, or giving the file name as an\n\
9990argument to the DOS \"start\" command: the file is opened with whatever\n\
9991application (if any) its extension is associated.\n\
9992When another \"operation\" is given, it specifies what should be done with\n\
9993the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009994\n\
9995startfile returns as soon as the associated application is launched.\n\
9996There is no option to wait for the application to close, and no way\n\
9997to retrieve the application's exit status.\n\
9998\n\
9999The filepath is relative to the current directory. If you want to use\n\
10000an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010001the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010002
10003static PyObject *
10004win32_startfile(PyObject *self, PyObject *args)
10005{
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 PyObject *ofilepath;
10007 char *filepath;
10008 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010009 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010011
Victor Stinnereb5657a2011-09-30 01:44:27 +020010012 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 if (!PyArg_ParseTuple(args, "U|s:startfile",
10014 &unipath, &operation)) {
10015 PyErr_Clear();
10016 goto normal;
10017 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010018
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010020 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010022 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 PyErr_Clear();
10024 operation = NULL;
10025 goto normal;
10026 }
10027 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010028
Victor Stinnereb5657a2011-09-30 01:44:27 +020010029 wpath = PyUnicode_AsUnicode(unipath);
10030 if (wpath == NULL)
10031 goto normal;
10032 if (uoperation) {
10033 woperation = PyUnicode_AsUnicode(uoperation);
10034 if (woperation == NULL)
10035 goto normal;
10036 }
10037 else
10038 woperation = NULL;
10039
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010041 rc = ShellExecuteW((HWND)0, woperation, wpath,
10042 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 Py_END_ALLOW_THREADS
10044
Victor Stinnereb5657a2011-09-30 01:44:27 +020010045 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010047 win32_error_object("startfile", unipath);
10048 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 }
10050 Py_INCREF(Py_None);
10051 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010052
10053normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10055 PyUnicode_FSConverter, &ofilepath,
10056 &operation))
10057 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010058 if (win32_warn_bytes_api()) {
10059 Py_DECREF(ofilepath);
10060 return NULL;
10061 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 filepath = PyBytes_AsString(ofilepath);
10063 Py_BEGIN_ALLOW_THREADS
10064 rc = ShellExecute((HWND)0, operation, filepath,
10065 NULL, NULL, SW_SHOWNORMAL);
10066 Py_END_ALLOW_THREADS
10067 if (rc <= (HINSTANCE)32) {
10068 PyObject *errval = win32_error("startfile", filepath);
10069 Py_DECREF(ofilepath);
10070 return errval;
10071 }
10072 Py_DECREF(ofilepath);
10073 Py_INCREF(Py_None);
10074 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010075}
10076#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010077
Martin v. Löwis438b5342002-12-27 10:16:42 +000010078#ifdef HAVE_GETLOADAVG
10079PyDoc_STRVAR(posix_getloadavg__doc__,
10080"getloadavg() -> (float, float, float)\n\n\
10081Return the number of processes in the system run queue averaged over\n\
10082the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10083was unobtainable");
10084
10085static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010086posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010087{
10088 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010089 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010090 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10091 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010092 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010093 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010094}
10095#endif
10096
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010097PyDoc_STRVAR(device_encoding__doc__,
10098"device_encoding(fd) -> str\n\n\
10099Return a string describing the encoding of the device\n\
10100if the output is a terminal; else return None.");
10101
10102static PyObject *
10103device_encoding(PyObject *self, PyObject *args)
10104{
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010106
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10108 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010109
10110 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010111}
10112
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010113#ifdef HAVE_SETRESUID
10114PyDoc_STRVAR(posix_setresuid__doc__,
10115"setresuid(ruid, euid, suid)\n\n\
10116Set the current process's real, effective, and saved user ids.");
10117
10118static PyObject*
10119posix_setresuid (PyObject *self, PyObject *args)
10120{
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010122 uid_t ruid, euid, suid;
10123 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10124 _Py_Uid_Converter, &ruid,
10125 _Py_Uid_Converter, &euid,
10126 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 return NULL;
10128 if (setresuid(ruid, euid, suid) < 0)
10129 return posix_error();
10130 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010131}
10132#endif
10133
10134#ifdef HAVE_SETRESGID
10135PyDoc_STRVAR(posix_setresgid__doc__,
10136"setresgid(rgid, egid, sgid)\n\n\
10137Set the current process's real, effective, and saved group ids.");
10138
10139static PyObject*
10140posix_setresgid (PyObject *self, PyObject *args)
10141{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010142 gid_t rgid, egid, sgid;
10143 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10144 _Py_Gid_Converter, &rgid,
10145 _Py_Gid_Converter, &egid,
10146 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 return NULL;
10148 if (setresgid(rgid, egid, sgid) < 0)
10149 return posix_error();
10150 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010151}
10152#endif
10153
10154#ifdef HAVE_GETRESUID
10155PyDoc_STRVAR(posix_getresuid__doc__,
10156"getresuid() -> (ruid, euid, suid)\n\n\
10157Get tuple of the current process's real, effective, and saved user ids.");
10158
10159static PyObject*
10160posix_getresuid (PyObject *self, PyObject *noargs)
10161{
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 if (getresuid(&ruid, &euid, &suid) < 0)
10164 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010165 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10166 _PyLong_FromUid(euid),
10167 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010168}
10169#endif
10170
10171#ifdef HAVE_GETRESGID
10172PyDoc_STRVAR(posix_getresgid__doc__,
10173"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010174Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010175
10176static PyObject*
10177posix_getresgid (PyObject *self, PyObject *noargs)
10178{
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 if (getresgid(&rgid, &egid, &sgid) < 0)
10181 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010182 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10183 _PyLong_FromGid(egid),
10184 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010185}
10186#endif
10187
Benjamin Peterson9428d532011-09-14 11:45:52 -040010188#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010189
Benjamin Peterson799bd802011-08-31 22:15:17 -040010190PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010191"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10192Return the value of extended attribute attribute on path.\n\
10193\n\
10194path may be either a string or an open file descriptor.\n\
10195If follow_symlinks is False, and the last element of the path is a symbolic\n\
10196 link, getxattr will examine the symbolic link itself instead of the file\n\
10197 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010198
10199static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010200posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010201{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010202 path_t path;
10203 path_t attribute;
10204 int follow_symlinks = 1;
10205 PyObject *buffer = NULL;
10206 int i;
10207 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010208
Larry Hastings9cf065c2012-06-22 16:30:09 -070010209 memset(&path, 0, sizeof(path));
10210 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010211 path.function_name = "getxattr";
10212 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010213 path.allow_fd = 1;
10214 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10215 path_converter, &path,
10216 path_converter, &attribute,
10217 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010218 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010219
Larry Hastings9cf065c2012-06-22 16:30:09 -070010220 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10221 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010222
Larry Hastings9cf065c2012-06-22 16:30:09 -070010223 for (i = 0; ; i++) {
10224 void *ptr;
10225 ssize_t result;
10226 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10227 Py_ssize_t buffer_size = buffer_sizes[i];
10228 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010229 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010230 goto exit;
10231 }
10232 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10233 if (!buffer)
10234 goto exit;
10235 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010236
Larry Hastings9cf065c2012-06-22 16:30:09 -070010237 Py_BEGIN_ALLOW_THREADS;
10238 if (path.fd >= 0)
10239 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10240 else if (follow_symlinks)
10241 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10242 else
10243 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10244 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010245
Larry Hastings9cf065c2012-06-22 16:30:09 -070010246 if (result < 0) {
10247 Py_DECREF(buffer);
10248 buffer = NULL;
10249 if (errno == ERANGE)
10250 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010251 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010252 goto exit;
10253 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010254
Larry Hastings9cf065c2012-06-22 16:30:09 -070010255 if (result != buffer_size) {
10256 /* Can only shrink. */
10257 _PyBytes_Resize(&buffer, result);
10258 }
10259 break;
10260 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010261
Larry Hastings9cf065c2012-06-22 16:30:09 -070010262exit:
10263 path_cleanup(&path);
10264 path_cleanup(&attribute);
10265 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010266}
10267
10268PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010269"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10270Set extended attribute attribute on path to value.\n\
10271path may be either a string or an open file descriptor.\n\
10272If follow_symlinks is False, and the last element of the path is a symbolic\n\
10273 link, setxattr will modify the symbolic link itself instead of the file\n\
10274 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010275
10276static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010277posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010278{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010279 path_t path;
10280 path_t attribute;
10281 Py_buffer value;
10282 int flags = 0;
10283 int follow_symlinks = 1;
10284 int result;
10285 PyObject *return_value = NULL;
10286 static char *keywords[] = {"path", "attribute", "value",
10287 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010288
Larry Hastings9cf065c2012-06-22 16:30:09 -070010289 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010290 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010291 path.allow_fd = 1;
10292 memset(&attribute, 0, sizeof(attribute));
10293 memset(&value, 0, sizeof(value));
10294 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10295 keywords,
10296 path_converter, &path,
10297 path_converter, &attribute,
10298 &value, &flags,
10299 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010300 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010301
10302 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10303 goto exit;
10304
Benjamin Peterson799bd802011-08-31 22:15:17 -040010305 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010306 if (path.fd > -1)
10307 result = fsetxattr(path.fd, attribute.narrow,
10308 value.buf, value.len, flags);
10309 else if (follow_symlinks)
10310 result = setxattr(path.narrow, attribute.narrow,
10311 value.buf, value.len, flags);
10312 else
10313 result = lsetxattr(path.narrow, attribute.narrow,
10314 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010315 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010316
Larry Hastings9cf065c2012-06-22 16:30:09 -070010317 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010318 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010319 goto exit;
10320 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010321
Larry Hastings9cf065c2012-06-22 16:30:09 -070010322 return_value = Py_None;
10323 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010324
Larry Hastings9cf065c2012-06-22 16:30:09 -070010325exit:
10326 path_cleanup(&path);
10327 path_cleanup(&attribute);
10328 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010329
Larry Hastings9cf065c2012-06-22 16:30:09 -070010330 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010331}
10332
10333PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010334"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10335Remove extended attribute attribute on path.\n\
10336path may be either a string or an open file descriptor.\n\
10337If follow_symlinks is False, and the last element of the path is a symbolic\n\
10338 link, removexattr will modify the symbolic link itself instead of the file\n\
10339 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010340
10341static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010342posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010343{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010344 path_t path;
10345 path_t attribute;
10346 int follow_symlinks = 1;
10347 int result;
10348 PyObject *return_value = NULL;
10349 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010350
Larry Hastings9cf065c2012-06-22 16:30:09 -070010351 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010352 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010353 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010354 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010355 path.allow_fd = 1;
10356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10357 keywords,
10358 path_converter, &path,
10359 path_converter, &attribute,
10360 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010361 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010362
10363 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10364 goto exit;
10365
Benjamin Peterson799bd802011-08-31 22:15:17 -040010366 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010367 if (path.fd > -1)
10368 result = fremovexattr(path.fd, attribute.narrow);
10369 else if (follow_symlinks)
10370 result = removexattr(path.narrow, attribute.narrow);
10371 else
10372 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010373 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010374
Larry Hastings9cf065c2012-06-22 16:30:09 -070010375 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010376 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010378 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010379
Larry Hastings9cf065c2012-06-22 16:30:09 -070010380 return_value = Py_None;
10381 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010382
Larry Hastings9cf065c2012-06-22 16:30:09 -070010383exit:
10384 path_cleanup(&path);
10385 path_cleanup(&attribute);
10386
10387 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010388}
10389
10390PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010391"listxattr(path='.', *, follow_symlinks=True)\n\n\
10392Return a list of extended attributes on path.\n\
10393\n\
10394path may be either None, a string, or an open file descriptor.\n\
10395if path is None, listxattr will examine the current directory.\n\
10396If follow_symlinks is False, and the last element of the path is a symbolic\n\
10397 link, listxattr will examine the symbolic link itself instead of the file\n\
10398 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010399
10400static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010401posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010402{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010403 path_t path;
10404 int follow_symlinks = 1;
10405 Py_ssize_t i;
10406 PyObject *result = NULL;
10407 char *buffer = NULL;
10408 char *name;
10409 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010410
Larry Hastings9cf065c2012-06-22 16:30:09 -070010411 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010412 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010413 path.allow_fd = 1;
10414 path.fd = -1;
10415 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10416 path_converter, &path,
10417 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010418 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010419
Larry Hastings9cf065c2012-06-22 16:30:09 -070010420 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10421 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010422
Larry Hastings9cf065c2012-06-22 16:30:09 -070010423 name = path.narrow ? path.narrow : ".";
10424 for (i = 0; ; i++) {
10425 char *start, *trace, *end;
10426 ssize_t length;
10427 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10428 Py_ssize_t buffer_size = buffer_sizes[i];
10429 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010430 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010431 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010432 break;
10433 }
10434 buffer = PyMem_MALLOC(buffer_size);
10435 if (!buffer) {
10436 PyErr_NoMemory();
10437 break;
10438 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010439
Larry Hastings9cf065c2012-06-22 16:30:09 -070010440 Py_BEGIN_ALLOW_THREADS;
10441 if (path.fd > -1)
10442 length = flistxattr(path.fd, buffer, buffer_size);
10443 else if (follow_symlinks)
10444 length = listxattr(name, buffer, buffer_size);
10445 else
10446 length = llistxattr(name, buffer, buffer_size);
10447 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010448
Larry Hastings9cf065c2012-06-22 16:30:09 -070010449 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010450 if (errno == ERANGE) {
10451 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010452 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010454 }
Victor Stinner292c8352012-10-30 02:17:38 +010010455 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010456 break;
10457 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010458
Larry Hastings9cf065c2012-06-22 16:30:09 -070010459 result = PyList_New(0);
10460 if (!result) {
10461 goto exit;
10462 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463
Larry Hastings9cf065c2012-06-22 16:30:09 -070010464 end = buffer + length;
10465 for (trace = start = buffer; trace != end; trace++) {
10466 if (!*trace) {
10467 int error;
10468 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10469 trace - start);
10470 if (!attribute) {
10471 Py_DECREF(result);
10472 result = NULL;
10473 goto exit;
10474 }
10475 error = PyList_Append(result, attribute);
10476 Py_DECREF(attribute);
10477 if (error) {
10478 Py_DECREF(result);
10479 result = NULL;
10480 goto exit;
10481 }
10482 start = trace + 1;
10483 }
10484 }
10485 break;
10486 }
10487exit:
10488 path_cleanup(&path);
10489 if (buffer)
10490 PyMem_FREE(buffer);
10491 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010492}
10493
Benjamin Peterson9428d532011-09-14 11:45:52 -040010494#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010495
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010496
Georg Brandl2fb477c2012-02-21 00:33:36 +010010497PyDoc_STRVAR(posix_urandom__doc__,
10498"urandom(n) -> str\n\n\
10499Return n random bytes suitable for cryptographic use.");
10500
10501static PyObject *
10502posix_urandom(PyObject *self, PyObject *args)
10503{
10504 Py_ssize_t size;
10505 PyObject *result;
10506 int ret;
10507
10508 /* Read arguments */
10509 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10510 return NULL;
10511 if (size < 0)
10512 return PyErr_Format(PyExc_ValueError,
10513 "negative argument not allowed");
10514 result = PyBytes_FromStringAndSize(NULL, size);
10515 if (result == NULL)
10516 return NULL;
10517
10518 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10519 PyBytes_GET_SIZE(result));
10520 if (ret == -1) {
10521 Py_DECREF(result);
10522 return NULL;
10523 }
10524 return result;
10525}
10526
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010527/* Terminal size querying */
10528
10529static PyTypeObject TerminalSizeType;
10530
10531PyDoc_STRVAR(TerminalSize_docstring,
10532 "A tuple of (columns, lines) for holding terminal window size");
10533
10534static PyStructSequence_Field TerminalSize_fields[] = {
10535 {"columns", "width of the terminal window in characters"},
10536 {"lines", "height of the terminal window in characters"},
10537 {NULL, NULL}
10538};
10539
10540static PyStructSequence_Desc TerminalSize_desc = {
10541 "os.terminal_size",
10542 TerminalSize_docstring,
10543 TerminalSize_fields,
10544 2,
10545};
10546
10547#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10548PyDoc_STRVAR(termsize__doc__,
10549 "Return the size of the terminal window as (columns, lines).\n" \
10550 "\n" \
10551 "The optional argument fd (default standard output) specifies\n" \
10552 "which file descriptor should be queried.\n" \
10553 "\n" \
10554 "If the file descriptor is not connected to a terminal, an OSError\n" \
10555 "is thrown.\n" \
10556 "\n" \
10557 "This function will only be defined if an implementation is\n" \
10558 "available for this system.\n" \
10559 "\n" \
10560 "shutil.get_terminal_size is the high-level function which should \n" \
10561 "normally be used, os.get_terminal_size is the low-level implementation.");
10562
10563static PyObject*
10564get_terminal_size(PyObject *self, PyObject *args)
10565{
10566 int columns, lines;
10567 PyObject *termsize;
10568
10569 int fd = fileno(stdout);
10570 /* Under some conditions stdout may not be connected and
10571 * fileno(stdout) may point to an invalid file descriptor. For example
10572 * GUI apps don't have valid standard streams by default.
10573 *
10574 * If this happens, and the optional fd argument is not present,
10575 * the ioctl below will fail returning EBADF. This is what we want.
10576 */
10577
10578 if (!PyArg_ParseTuple(args, "|i", &fd))
10579 return NULL;
10580
10581#ifdef TERMSIZE_USE_IOCTL
10582 {
10583 struct winsize w;
10584 if (ioctl(fd, TIOCGWINSZ, &w))
10585 return PyErr_SetFromErrno(PyExc_OSError);
10586 columns = w.ws_col;
10587 lines = w.ws_row;
10588 }
10589#endif /* TERMSIZE_USE_IOCTL */
10590
10591#ifdef TERMSIZE_USE_CONIO
10592 {
10593 DWORD nhandle;
10594 HANDLE handle;
10595 CONSOLE_SCREEN_BUFFER_INFO csbi;
10596 switch (fd) {
10597 case 0: nhandle = STD_INPUT_HANDLE;
10598 break;
10599 case 1: nhandle = STD_OUTPUT_HANDLE;
10600 break;
10601 case 2: nhandle = STD_ERROR_HANDLE;
10602 break;
10603 default:
10604 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10605 }
10606 handle = GetStdHandle(nhandle);
10607 if (handle == NULL)
10608 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10609 if (handle == INVALID_HANDLE_VALUE)
10610 return PyErr_SetFromWindowsErr(0);
10611
10612 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10613 return PyErr_SetFromWindowsErr(0);
10614
10615 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10616 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10617 }
10618#endif /* TERMSIZE_USE_CONIO */
10619
10620 termsize = PyStructSequence_New(&TerminalSizeType);
10621 if (termsize == NULL)
10622 return NULL;
10623 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10624 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10625 if (PyErr_Occurred()) {
10626 Py_DECREF(termsize);
10627 return NULL;
10628 }
10629 return termsize;
10630}
10631#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10632
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010633PyDoc_STRVAR(posix_cpu_count__doc__,
10634"cpu_count() -> integer\n\n\
10635Return the number of CPUs in the system, or None if this value cannot be\n\
10636established.");
10637
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010638static PyObject *
10639posix_cpu_count(PyObject *self)
10640{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010641 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010642#ifdef MS_WINDOWS
10643 SYSTEM_INFO sysinfo;
10644 GetSystemInfo(&sysinfo);
10645 ncpu = sysinfo.dwNumberOfProcessors;
10646#elif defined(__hpux)
10647 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10648#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10649 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010650#elif defined(__DragonFly__) || \
10651 defined(__OpenBSD__) || \
10652 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010653 defined(__NetBSD__) || \
10654 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010655 int mib[2];
10656 size_t len = sizeof(ncpu);
10657 mib[0] = CTL_HW;
10658 mib[1] = HW_NCPU;
10659 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10660 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010661#endif
10662 if (ncpu >= 1)
10663 return PyLong_FromLong(ncpu);
10664 else
10665 Py_RETURN_NONE;
10666}
10667
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010668
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010669static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 {"access", (PyCFunction)posix_access,
10671 METH_VARARGS | METH_KEYWORDS,
10672 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010673#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010675#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010676 {"chdir", (PyCFunction)posix_chdir,
10677 METH_VARARGS | METH_KEYWORDS,
10678 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010679#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010680 {"chflags", (PyCFunction)posix_chflags,
10681 METH_VARARGS | METH_KEYWORDS,
10682 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010683#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 {"chmod", (PyCFunction)posix_chmod,
10685 METH_VARARGS | METH_KEYWORDS,
10686 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010687#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010689#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010690#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010691 {"chown", (PyCFunction)posix_chown,
10692 METH_VARARGS | METH_KEYWORDS,
10693 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010694#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010695#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010697#endif /* HAVE_LCHMOD */
10698#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010700#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010701#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010703#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010704#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010706#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010707#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010709#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010710#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010712#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010713#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10715 METH_NOARGS, posix_getcwd__doc__},
10716 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10717 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010718#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10720 {"link", (PyCFunction)posix_link,
10721 METH_VARARGS | METH_KEYWORDS,
10722 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010723#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010724 {"listdir", (PyCFunction)posix_listdir,
10725 METH_VARARGS | METH_KEYWORDS,
10726 posix_listdir__doc__},
10727 {"lstat", (PyCFunction)posix_lstat,
10728 METH_VARARGS | METH_KEYWORDS,
10729 posix_lstat__doc__},
10730 {"mkdir", (PyCFunction)posix_mkdir,
10731 METH_VARARGS | METH_KEYWORDS,
10732 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010733#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010735#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010736#ifdef HAVE_GETPRIORITY
10737 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10738#endif /* HAVE_GETPRIORITY */
10739#ifdef HAVE_SETPRIORITY
10740 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10741#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010742#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 {"readlink", (PyCFunction)posix_readlink,
10744 METH_VARARGS | METH_KEYWORDS,
10745 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010746#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010747#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010748 {"readlink", (PyCFunction)win_readlink,
10749 METH_VARARGS | METH_KEYWORDS,
10750 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010751#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 {"rename", (PyCFunction)posix_rename,
10753 METH_VARARGS | METH_KEYWORDS,
10754 posix_rename__doc__},
10755 {"replace", (PyCFunction)posix_replace,
10756 METH_VARARGS | METH_KEYWORDS,
10757 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010758 {"rmdir", (PyCFunction)posix_rmdir,
10759 METH_VARARGS | METH_KEYWORDS,
10760 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 {"stat", (PyCFunction)posix_stat,
10762 METH_VARARGS | METH_KEYWORDS,
10763 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765#if defined(HAVE_SYMLINK)
10766 {"symlink", (PyCFunction)posix_symlink,
10767 METH_VARARGS | METH_KEYWORDS,
10768 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010769#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010770#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010772#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010774#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010776#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 {"unlink", (PyCFunction)posix_unlink,
10778 METH_VARARGS | METH_KEYWORDS,
10779 posix_unlink__doc__},
10780 {"remove", (PyCFunction)posix_unlink,
10781 METH_VARARGS | METH_KEYWORDS,
10782 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010783 {"utime", (PyCFunction)posix_utime,
10784 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010785#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010787#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010789#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 {"execve", (PyCFunction)posix_execve,
10792 METH_VARARGS | METH_KEYWORDS,
10793 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010794#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010795#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10797 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010798#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010799#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010801#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010802#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010804#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010805#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010806#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010807 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10808 {"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 +020010809#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010810#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010811 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010812#endif
10813#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010814 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010815#endif
10816#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010817 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010818#endif
10819#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010820 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010821#endif
10822#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010823 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010824#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010825 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010826#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010827 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10828 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10829#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010830#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010831#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010833#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010834#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010836#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010837#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010839#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010840#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010842#endif /* HAVE_GETEUID */
10843#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010845#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010846#ifdef HAVE_GETGROUPLIST
10847 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10848#endif
Fred Drakec9680921999-12-13 16:37:25 +000010849#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010853#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010855#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010856#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010858#endif /* HAVE_GETPPID */
10859#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010861#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010862#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010864#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010865#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010867#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010868#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010870#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010871#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010873#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010874#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10876 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010877#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010878#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010880#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010881#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010883#endif /* HAVE_SETEUID */
10884#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010886#endif /* HAVE_SETEGID */
10887#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010889#endif /* HAVE_SETREUID */
10890#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010892#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010893#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010895#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010896#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010898#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010899#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010901#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010902#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010904#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010905#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010907#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010908#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010910#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010911#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010912 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010913#endif /* HAVE_WAIT3 */
10914#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010915 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010916#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010917#if defined(HAVE_WAITID) && !defined(__APPLE__)
10918 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10919#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010920#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010922#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010923#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010925#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010926#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010928#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010929#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010931#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010932#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010934#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010935#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010937#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010938 {"open", (PyCFunction)posix_open,\
10939 METH_VARARGS | METH_KEYWORDS,
10940 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10942 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10943 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10944 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10945 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010946#ifdef HAVE_LOCKF
10947 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10948#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10950 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010951#ifdef HAVE_READV
10952 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10953#endif
10954#ifdef HAVE_PREAD
10955 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10956#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010958#ifdef HAVE_WRITEV
10959 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10960#endif
10961#ifdef HAVE_PWRITE
10962 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10963#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010964#ifdef HAVE_SENDFILE
10965 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10966 posix_sendfile__doc__},
10967#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010968 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010970#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010972#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010973#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010974 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010975#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010976#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 {"mkfifo", (PyCFunction)posix_mkfifo,
10978 METH_VARARGS | METH_KEYWORDS,
10979 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010980#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010981#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982 {"mknod", (PyCFunction)posix_mknod,
10983 METH_VARARGS | METH_KEYWORDS,
10984 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010985#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010986#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10988 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10989 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010990#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010991#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010993#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010994#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010995 {"truncate", (PyCFunction)posix_truncate,
10996 METH_VARARGS | METH_KEYWORDS,
10997 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010998#endif
10999#ifdef HAVE_POSIX_FALLOCATE
11000 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11001#endif
11002#ifdef HAVE_POSIX_FADVISE
11003 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11004#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011005#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011007#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011008#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011012#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011014#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011015#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011017#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011018#ifdef HAVE_SYNC
11019 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11020#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011021#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011023#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011024#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011025#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011027#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011028#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011030#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011031#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011033#endif /* WIFSTOPPED */
11034#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011036#endif /* WIFSIGNALED */
11037#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011039#endif /* WIFEXITED */
11040#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011042#endif /* WEXITSTATUS */
11043#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011045#endif /* WTERMSIG */
11046#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011048#endif /* WSTOPSIG */
11049#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011050#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011052#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011053#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011054 {"statvfs", (PyCFunction)posix_statvfs,
11055 METH_VARARGS | METH_KEYWORDS,
11056 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011057#endif
Fred Drakec9680921999-12-13 16:37:25 +000011058#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011068 {"pathconf", (PyCFunction)posix_pathconf,
11069 METH_VARARGS | METH_KEYWORDS,
11070 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011071#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011073#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011075 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011076 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011077 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011078 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011079#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011080#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011082#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011083 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011084#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011086#endif
11087#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011089#endif
11090#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011092#endif
11093#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011095#endif
11096
Benjamin Peterson9428d532011-09-14 11:45:52 -040011097#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011098 {"setxattr", (PyCFunction)posix_setxattr,
11099 METH_VARARGS | METH_KEYWORDS,
11100 posix_setxattr__doc__},
11101 {"getxattr", (PyCFunction)posix_getxattr,
11102 METH_VARARGS | METH_KEYWORDS,
11103 posix_getxattr__doc__},
11104 {"removexattr", (PyCFunction)posix_removexattr,
11105 METH_VARARGS | METH_KEYWORDS,
11106 posix_removexattr__doc__},
11107 {"listxattr", (PyCFunction)posix_listxattr,
11108 METH_VARARGS | METH_KEYWORDS,
11109 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011110#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011111#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11112 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11113#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011114 {"cpu_count", (PyCFunction)posix_cpu_count,
11115 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011117};
11118
11119
Brian Curtin52173d42010-12-02 18:29:18 +000011120#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011121static int
Brian Curtin52173d42010-12-02 18:29:18 +000011122enable_symlink()
11123{
11124 HANDLE tok;
11125 TOKEN_PRIVILEGES tok_priv;
11126 LUID luid;
11127 int meth_idx = 0;
11128
11129 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011130 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011131
11132 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011133 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011134
11135 tok_priv.PrivilegeCount = 1;
11136 tok_priv.Privileges[0].Luid = luid;
11137 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11138
11139 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11140 sizeof(TOKEN_PRIVILEGES),
11141 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011142 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011143
Brian Curtin3b4499c2010-12-28 14:31:47 +000011144 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11145 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011146}
11147#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11148
Barry Warsaw4a342091996-12-19 23:50:02 +000011149static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011150all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011151{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011152#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011153 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011154#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011155#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011156 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011157#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011158#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011159 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011160#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011161#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011162 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011163#endif
Fred Drakec9680921999-12-13 16:37:25 +000011164#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011165 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011166#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011167#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011168 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011169#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011170#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011171 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011172#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011173#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011174 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011175#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011176#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011177 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011178#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011179#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011180 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011181#endif
11182#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011183 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011184#endif
11185#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011186 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011187#endif
11188#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011189 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011190#endif
11191#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011192 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011193#endif
11194#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011195 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011196#endif
11197#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011198 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011199#endif
11200#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011201 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011202#endif
11203#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011204 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011205#endif
11206#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011207 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011208#endif
11209#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011210 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011211#endif
11212#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011213 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011214#endif
11215#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011216 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011217#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011218#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011219 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011220#endif
11221#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011222 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011223#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011224#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011225 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011226#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011227#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011228 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011229#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011230#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011231 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011232#endif
11233#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011234 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011235#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011236#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011237 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011238#endif
11239#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011240 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011241#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011242#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011243 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011244#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011245#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011246 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011247#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011248#ifdef O_TMPFILE
11249 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11250#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011251#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011252 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011253#endif
11254#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011255 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011256#endif
11257#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011258 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011259#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011260#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011261 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011262#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011263#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011264 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011265#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011266
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011267
Jesus Cea94363612012-06-22 18:32:07 +020011268#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011269 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011270#endif
11271#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011272 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011273#endif
11274
Tim Peters5aa91602002-01-30 05:46:57 +000011275/* MS Windows */
11276#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011278 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011279#endif
11280#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 /* Optimize for short life (keep in memory). */
11282 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011283 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011284#endif
11285#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011287 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011288#endif
11289#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011291 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011292#endif
11293#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011295 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011296#endif
11297
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011298/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011299#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 /* Send a SIGIO signal whenever input or output
11301 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011302 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011303#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011304#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011306 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011307#endif
11308#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011310 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011311#endif
11312#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011314 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011315#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011316#ifdef O_NOLINKS
11317 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011318 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011319#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011320#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011322 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011323#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011324
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011326#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011327 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011328#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011329#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011330 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011331#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011332#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011333 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011334#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011335#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011336 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011337#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011338#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011339 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011340#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011341#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011342 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011343#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011344#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011345 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011346#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011347#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011348 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011349#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011350#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011351 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011352#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011353#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011354 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011355#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011356#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011357 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011358#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011359#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011360 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011361#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011362#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011363 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011364#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011365#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011366 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011367#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011368#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011369 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011370#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011371#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011372 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011373#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011374#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011375 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011376#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011377
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011378 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011379#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011380 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011381#endif /* ST_RDONLY */
11382#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011383 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011384#endif /* ST_NOSUID */
11385
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011386 /* FreeBSD sendfile() constants */
11387#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011388 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011389#endif
11390#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011391 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011392#endif
11393#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011394 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011395#endif
11396
Ross Lagerwall7807c352011-03-17 20:20:30 +020011397 /* constants for posix_fadvise */
11398#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011399 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011400#endif
11401#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011402 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011403#endif
11404#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011405 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011406#endif
11407#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011408 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011409#endif
11410#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011411 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011412#endif
11413#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011414 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011415#endif
11416
11417 /* constants for waitid */
11418#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011419 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11420 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11421 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011422#endif
11423#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011424 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011425#endif
11426#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011427 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011428#endif
11429#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011430 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011431#endif
11432#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011433 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011434#endif
11435#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011436 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011437#endif
11438#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011439 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011440#endif
11441#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011442 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011443#endif
11444
11445 /* constants for lockf */
11446#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011447 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011448#endif
11449#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011450 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011451#endif
11452#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011453 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011454#endif
11455#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011456 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011457#endif
11458
Guido van Rossum246bc171999-02-01 23:54:31 +000011459#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011460 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11461 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11462 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11463 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11464 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011465#endif
11466
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011467#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011468 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11469 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11470 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011471#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011472 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011473#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011474#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011475 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011476#endif
11477#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011478 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011479#endif
11480#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011481 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011482#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011483#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011484 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011485#endif
11486#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011487 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011488#endif
11489#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011490 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011491#endif
11492#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011493 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011494#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011495#endif
11496
Benjamin Peterson9428d532011-09-14 11:45:52 -040011497#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011498 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11499 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11500 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011501#endif
11502
Victor Stinner8b905bd2011-10-25 13:34:04 +020011503#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011504 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011505#endif
11506#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011507 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011508#endif
11509#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011510 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011511#endif
11512#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011513 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011514#endif
11515#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011516 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011517#endif
11518#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011519 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011520#endif
11521#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011522 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011523#endif
11524
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011526}
11527
11528
Tim Peters5aa91602002-01-30 05:46:57 +000011529#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011530#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011531#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011532
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011533#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011534#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011535#define MODNAME "posix"
11536#endif
11537
Martin v. Löwis1a214512008-06-11 05:26:20 +000011538static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 PyModuleDef_HEAD_INIT,
11540 MODNAME,
11541 posix__doc__,
11542 -1,
11543 posix_methods,
11544 NULL,
11545 NULL,
11546 NULL,
11547 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011548};
11549
11550
Larry Hastings9cf065c2012-06-22 16:30:09 -070011551static char *have_functions[] = {
11552
11553#ifdef HAVE_FACCESSAT
11554 "HAVE_FACCESSAT",
11555#endif
11556
11557#ifdef HAVE_FCHDIR
11558 "HAVE_FCHDIR",
11559#endif
11560
11561#ifdef HAVE_FCHMOD
11562 "HAVE_FCHMOD",
11563#endif
11564
11565#ifdef HAVE_FCHMODAT
11566 "HAVE_FCHMODAT",
11567#endif
11568
11569#ifdef HAVE_FCHOWN
11570 "HAVE_FCHOWN",
11571#endif
11572
Larry Hastings00964ed2013-08-12 13:49:30 -040011573#ifdef HAVE_FCHOWNAT
11574 "HAVE_FCHOWNAT",
11575#endif
11576
Larry Hastings9cf065c2012-06-22 16:30:09 -070011577#ifdef HAVE_FEXECVE
11578 "HAVE_FEXECVE",
11579#endif
11580
11581#ifdef HAVE_FDOPENDIR
11582 "HAVE_FDOPENDIR",
11583#endif
11584
Georg Brandl306336b2012-06-24 12:55:33 +020011585#ifdef HAVE_FPATHCONF
11586 "HAVE_FPATHCONF",
11587#endif
11588
Larry Hastings9cf065c2012-06-22 16:30:09 -070011589#ifdef HAVE_FSTATAT
11590 "HAVE_FSTATAT",
11591#endif
11592
11593#ifdef HAVE_FSTATVFS
11594 "HAVE_FSTATVFS",
11595#endif
11596
Georg Brandl306336b2012-06-24 12:55:33 +020011597#ifdef HAVE_FTRUNCATE
11598 "HAVE_FTRUNCATE",
11599#endif
11600
Larry Hastings9cf065c2012-06-22 16:30:09 -070011601#ifdef HAVE_FUTIMENS
11602 "HAVE_FUTIMENS",
11603#endif
11604
11605#ifdef HAVE_FUTIMES
11606 "HAVE_FUTIMES",
11607#endif
11608
11609#ifdef HAVE_FUTIMESAT
11610 "HAVE_FUTIMESAT",
11611#endif
11612
11613#ifdef HAVE_LINKAT
11614 "HAVE_LINKAT",
11615#endif
11616
11617#ifdef HAVE_LCHFLAGS
11618 "HAVE_LCHFLAGS",
11619#endif
11620
11621#ifdef HAVE_LCHMOD
11622 "HAVE_LCHMOD",
11623#endif
11624
11625#ifdef HAVE_LCHOWN
11626 "HAVE_LCHOWN",
11627#endif
11628
11629#ifdef HAVE_LSTAT
11630 "HAVE_LSTAT",
11631#endif
11632
11633#ifdef HAVE_LUTIMES
11634 "HAVE_LUTIMES",
11635#endif
11636
11637#ifdef HAVE_MKDIRAT
11638 "HAVE_MKDIRAT",
11639#endif
11640
11641#ifdef HAVE_MKFIFOAT
11642 "HAVE_MKFIFOAT",
11643#endif
11644
11645#ifdef HAVE_MKNODAT
11646 "HAVE_MKNODAT",
11647#endif
11648
11649#ifdef HAVE_OPENAT
11650 "HAVE_OPENAT",
11651#endif
11652
11653#ifdef HAVE_READLINKAT
11654 "HAVE_READLINKAT",
11655#endif
11656
11657#ifdef HAVE_RENAMEAT
11658 "HAVE_RENAMEAT",
11659#endif
11660
11661#ifdef HAVE_SYMLINKAT
11662 "HAVE_SYMLINKAT",
11663#endif
11664
11665#ifdef HAVE_UNLINKAT
11666 "HAVE_UNLINKAT",
11667#endif
11668
11669#ifdef HAVE_UTIMENSAT
11670 "HAVE_UTIMENSAT",
11671#endif
11672
11673#ifdef MS_WINDOWS
11674 "MS_WINDOWS",
11675#endif
11676
11677 NULL
11678};
11679
11680
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011681PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011682INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011683{
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011685 PyObject *list;
11686 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011687
Brian Curtin52173d42010-12-02 18:29:18 +000011688#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011689 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011690#endif
11691
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 m = PyModule_Create(&posixmodule);
11693 if (m == NULL)
11694 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011695
Victor Stinner8c62be82010-05-06 00:08:46 +000011696 /* Initialize environ dictionary */
11697 v = convertenviron();
11698 Py_XINCREF(v);
11699 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11700 return NULL;
11701 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011702
Victor Stinner8c62be82010-05-06 00:08:46 +000011703 if (all_ins(m))
11704 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011705
Victor Stinner8c62be82010-05-06 00:08:46 +000011706 if (setup_confname_tables(m))
11707 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011708
Victor Stinner8c62be82010-05-06 00:08:46 +000011709 Py_INCREF(PyExc_OSError);
11710 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011711
Guido van Rossumb3d39562000-01-31 18:41:26 +000011712#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 if (posix_putenv_garbage == NULL)
11714 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011715#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011716
Victor Stinner8c62be82010-05-06 00:08:46 +000011717 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011718#if defined(HAVE_WAITID) && !defined(__APPLE__)
11719 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011720 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
11721 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011722#endif
11723
Victor Stinner8c62be82010-05-06 00:08:46 +000011724 stat_result_desc.name = MODNAME ".stat_result";
11725 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11726 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11727 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020011728 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
11729 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011730 structseq_new = StatResultType.tp_new;
11731 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011732
Victor Stinner8c62be82010-05-06 00:08:46 +000011733 statvfs_result_desc.name = MODNAME ".statvfs_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011734 if (PyStructSequence_InitType2(&StatVFSResultType,
11735 &statvfs_result_desc) < 0)
11736 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011737#ifdef NEED_TICKS_PER_SECOND
11738# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011739 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011740# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011741 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011742# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011744# endif
11745#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011746
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011747#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011748 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011749 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
11750 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011751 SchedParamType.tp_new = sched_param_new;
11752#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011753
11754 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020011755 if (PyStructSequence_InitType2(&TerminalSizeType,
11756 &TerminalSize_desc) < 0)
11757 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011759#if defined(HAVE_WAITID) && !defined(__APPLE__)
11760 Py_INCREF((PyObject*) &WaitidResultType);
11761 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11762#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011763 Py_INCREF((PyObject*) &StatResultType);
11764 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11765 Py_INCREF((PyObject*) &StatVFSResultType);
11766 PyModule_AddObject(m, "statvfs_result",
11767 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011768
11769#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011770 Py_INCREF(&SchedParamType);
11771 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011772#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011773
Larry Hastings605a62d2012-06-24 04:33:36 -070011774 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011775 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
11776 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070011777 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11778
11779 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011780 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
11781 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070011782 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11783
Thomas Wouters477c8d52006-05-27 19:21:47 +000011784#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011785 /*
11786 * Step 2 of weak-linking support on Mac OS X.
11787 *
11788 * The code below removes functions that are not available on the
11789 * currently active platform.
11790 *
11791 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011792 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011793 * OSX 10.4.
11794 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011795#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011796 if (fstatvfs == NULL) {
11797 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11798 return NULL;
11799 }
11800 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011801#endif /* HAVE_FSTATVFS */
11802
11803#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011804 if (statvfs == NULL) {
11805 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11806 return NULL;
11807 }
11808 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011809#endif /* HAVE_STATVFS */
11810
11811# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011812 if (lchown == NULL) {
11813 if (PyObject_DelAttrString(m, "lchown") == -1) {
11814 return NULL;
11815 }
11816 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011817#endif /* HAVE_LCHOWN */
11818
11819
11820#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011821
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011822 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011823 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11824
Larry Hastings6fe20b32012-04-19 15:07:49 -070011825 billion = PyLong_FromLong(1000000000);
11826 if (!billion)
11827 return NULL;
11828
Larry Hastings9cf065c2012-06-22 16:30:09 -070011829 /* suppress "function not used" warnings */
11830 {
11831 int ignored;
11832 fd_specified("", -1);
11833 follow_symlinks_specified("", 1);
11834 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11835 dir_fd_converter(Py_None, &ignored);
11836 dir_fd_unavailable(Py_None, &ignored);
11837 }
11838
11839 /*
11840 * provide list of locally available functions
11841 * so os.py can populate support_* lists
11842 */
11843 list = PyList_New(0);
11844 if (!list)
11845 return NULL;
11846 for (trace = have_functions; *trace; trace++) {
11847 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11848 if (!unicode)
11849 return NULL;
11850 if (PyList_Append(list, unicode))
11851 return NULL;
11852 Py_DECREF(unicode);
11853 }
11854 PyModule_AddObject(m, "_have_functions", list);
11855
11856 initialized = 1;
11857
Victor Stinner8c62be82010-05-06 00:08:46 +000011858 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000011859}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011860
11861#ifdef __cplusplus
11862}
11863#endif