blob: 36f0c4c91c16cb902c68a0a54c07d8b70c3e0e3b [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
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 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
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
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
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
417#define DEFAULT_DIR_FD AT_FDCWD
418#else
419#define DEFAULT_DIR_FD (-100)
420#endif
421
422static int
423_fd_converter(PyObject *o, int *p, int default_value) {
424 long long_value;
425 if (o == Py_None) {
426 *p = default_value;
427 return 1;
428 }
429 if (PyFloat_Check(o)) {
430 PyErr_SetString(PyExc_TypeError,
431 "integer argument expected, got float" );
432 return 0;
433 }
434 long_value = PyLong_AsLong(o);
435 if (long_value == -1 && PyErr_Occurred())
436 return 0;
437 if (long_value > INT_MAX) {
438 PyErr_SetString(PyExc_OverflowError,
439 "signed integer is greater than maximum");
440 return 0;
441 }
442 if (long_value < INT_MIN) {
443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is less than minimum");
445 return 0;
446 }
447 *p = (int)long_value;
448 return 1;
449}
450
451static int
452dir_fd_converter(PyObject *o, void *p) {
453 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
454}
455
456
457
458/*
459 * A PyArg_ParseTuple "converter" function
460 * that handles filesystem paths in the manner
461 * preferred by the os module.
462 *
463 * path_converter accepts (Unicode) strings and their
464 * subclasses, and bytes and their subclasses. What
465 * it does with the argument depends on the platform:
466 *
467 * * On Windows, if we get a (Unicode) string we
468 * extract the wchar_t * and return it; if we get
469 * bytes we extract the char * and return that.
470 *
471 * * On all other platforms, strings are encoded
472 * to bytes using PyUnicode_FSConverter, then we
473 * extract the char * from the bytes object and
474 * return that.
475 *
476 * path_converter also optionally accepts signed
477 * integers (representing open file descriptors) instead
478 * of path strings.
479 *
480 * Input fields:
481 * path.nullable
482 * If nonzero, the path is permitted to be None.
483 * path.allow_fd
484 * If nonzero, the path is permitted to be a file handle
485 * (a signed int) instead of a string.
486 * path.function_name
487 * If non-NULL, path_converter will use that as the name
488 * of the function in error messages.
489 * (If path.argument_name is NULL it omits the function name.)
490 * path.argument_name
491 * If non-NULL, path_converter will use that as the name
492 * of the parameter in error messages.
493 * (If path.argument_name is NULL it uses "path".)
494 *
495 * Output fields:
496 * path.wide
497 * Points to the path if it was expressed as Unicode
498 * and was not encoded. (Only used on Windows.)
499 * path.narrow
500 * Points to the path if it was expressed as bytes,
501 * or it was Unicode and was encoded to bytes.
502 * path.fd
503 * Contains a file descriptor if path.accept_fd was true
504 * and the caller provided a signed integer instead of any
505 * sort of string.
506 *
507 * WARNING: if your "path" parameter is optional, and is
508 * unspecified, path_converter will never get called.
509 * So if you set allow_fd, you *MUST* initialize path.fd = -1
510 * yourself!
511 * path.length
512 * The length of the path in characters, if specified as
513 * a string.
514 * path.object
515 * The original object passed in.
516 * path.cleanup
517 * For internal use only. May point to a temporary object.
518 * (Pay no attention to the man behind the curtain.)
519 *
520 * At most one of path.wide or path.narrow will be non-NULL.
521 * If path was None and path.nullable was set,
522 * or if path was an integer and path.allow_fd was set,
523 * both path.wide and path.narrow will be NULL
524 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200525 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700526 * path_converter takes care to not write to the path_t
527 * unless it's successful. However it must reset the
528 * "cleanup" field each time it's called.
529 *
530 * Use as follows:
531 * path_t path;
532 * memset(&path, 0, sizeof(path));
533 * PyArg_ParseTuple(args, "O&", path_converter, &path);
534 * // ... use values from path ...
535 * path_cleanup(&path);
536 *
537 * (Note that if PyArg_Parse fails you don't need to call
538 * path_cleanup(). However it is safe to do so.)
539 */
540typedef struct {
541 char *function_name;
542 char *argument_name;
543 int nullable;
544 int allow_fd;
545 wchar_t *wide;
546 char *narrow;
547 int fd;
548 Py_ssize_t length;
549 PyObject *object;
550 PyObject *cleanup;
551} path_t;
552
553static void
554path_cleanup(path_t *path) {
555 if (path->cleanup) {
556 Py_DECREF(path->cleanup);
557 path->cleanup = NULL;
558 }
559}
560
561static int
562path_converter(PyObject *o, void *p) {
563 path_t *path = (path_t *)p;
564 PyObject *unicode, *bytes;
565 Py_ssize_t length;
566 char *narrow;
567
568#define FORMAT_EXCEPTION(exc, fmt) \
569 PyErr_Format(exc, "%s%s" fmt, \
570 path->function_name ? path->function_name : "", \
571 path->function_name ? ": " : "", \
572 path->argument_name ? path->argument_name : "path")
573
574 /* Py_CLEANUP_SUPPORTED support */
575 if (o == NULL) {
576 path_cleanup(path);
577 return 1;
578 }
579
580 /* ensure it's always safe to call path_cleanup() */
581 path->cleanup = NULL;
582
583 if (o == Py_None) {
584 if (!path->nullable) {
585 FORMAT_EXCEPTION(PyExc_TypeError,
586 "can't specify None for %s argument");
587 return 0;
588 }
589 path->wide = NULL;
590 path->narrow = NULL;
591 path->length = 0;
592 path->object = o;
593 path->fd = -1;
594 return 1;
595 }
596
597 unicode = PyUnicode_FromObject(o);
598 if (unicode) {
599#ifdef MS_WINDOWS
600 wchar_t *wide;
601 length = PyUnicode_GET_SIZE(unicode);
602 if (length > 32767) {
603 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
604 Py_DECREF(unicode);
605 return 0;
606 }
607
608 wide = PyUnicode_AsUnicode(unicode);
609 if (!wide) {
610 Py_DECREF(unicode);
611 return 0;
612 }
613
614 path->wide = wide;
615 path->narrow = NULL;
616 path->length = length;
617 path->object = o;
618 path->fd = -1;
619 path->cleanup = unicode;
620 return Py_CLEANUP_SUPPORTED;
621#else
622 int converted = PyUnicode_FSConverter(unicode, &bytes);
623 Py_DECREF(unicode);
624 if (!converted)
625 bytes = NULL;
626#endif
627 }
628 else {
629 PyErr_Clear();
630 bytes = PyBytes_FromObject(o);
631 if (!bytes) {
632 PyErr_Clear();
633 if (path->allow_fd) {
634 int fd;
635 /*
636 * note: _fd_converter always permits None.
637 * but we've already done our None check.
638 * so o cannot be None at this point.
639 */
640 int result = _fd_converter(o, &fd, -1);
641 if (result) {
642 path->wide = NULL;
643 path->narrow = NULL;
644 path->length = 0;
645 path->object = o;
646 path->fd = fd;
647 return result;
648 }
649 }
650 }
651 }
652
653 if (!bytes) {
654 if (!PyErr_Occurred())
655 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
656 return 0;
657 }
658
659#ifdef MS_WINDOWS
660 if (win32_warn_bytes_api()) {
661 Py_DECREF(bytes);
662 return 0;
663 }
664#endif
665
666 length = PyBytes_GET_SIZE(bytes);
667#ifdef MS_WINDOWS
668 if (length > MAX_PATH) {
669 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 narrow = PyBytes_AS_STRING(bytes);
676 if (length != strlen(narrow)) {
677 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
678 Py_DECREF(bytes);
679 return 0;
680 }
681
682 path->wide = NULL;
683 path->narrow = narrow;
684 path->length = length;
685 path->object = o;
686 path->fd = -1;
687 path->cleanup = bytes;
688 return Py_CLEANUP_SUPPORTED;
689}
690
691static void
692argument_unavailable_error(char *function_name, char *argument_name) {
693 PyErr_Format(PyExc_NotImplementedError,
694 "%s%s%s unavailable on this platform",
695 (function_name != NULL) ? function_name : "",
696 (function_name != NULL) ? ": ": "",
697 argument_name);
698}
699
700static int
701dir_fd_unavailable(PyObject *o, void *p) {
702 int *dir_fd = (int *)p;
703 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
704 if (!return_value)
705 return 0;
706 if (*dir_fd == DEFAULT_DIR_FD)
707 return 1;
708 argument_unavailable_error(NULL, "dir_fd");
709 return 0;
710}
711
712static int
713fd_specified(char *function_name, int fd) {
714 if (fd == -1)
715 return 0;
716
717 argument_unavailable_error(function_name, "fd");
718 return 1;
719}
720
721static int
722follow_symlinks_specified(char *function_name, int follow_symlinks) {
723 if (follow_symlinks)
724 return 0;
725
726 argument_unavailable_error(function_name, "follow_symlinks");
727 return 1;
728}
729
730static int
731path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
732 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
733 PyErr_Format(PyExc_ValueError,
734 "%s: can't specify dir_fd without matching path",
735 function_name);
736 return 1;
737 }
738 return 0;
739}
740
741static int
742dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify both dir_fd and fd",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753fd_and_follow_symlinks_invalid(char *function_name, int fd,
754 int follow_symlinks) {
755 if ((fd > 0) && (!follow_symlinks)) {
756 PyErr_Format(PyExc_ValueError,
757 "%s: cannot use fd and follow_symlinks together",
758 function_name);
759 return 1;
760 }
761 return 0;
762}
763
764static int
765dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
766 int follow_symlinks) {
767 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
768 PyErr_Format(PyExc_ValueError,
769 "%s: cannot use dir_fd and follow_symlinks together",
770 function_name);
771 return 1;
772 }
773 return 0;
774}
775
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200776/* A helper used by a number of POSIX-only functions */
777#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000778static int
779_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000780{
781#if !defined(HAVE_LARGEFILE_SUPPORT)
782 *((off_t*)addr) = PyLong_AsLong(arg);
783#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000784 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000785#endif
786 if (PyErr_Occurred())
787 return 0;
788 return 1;
789}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200790#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792#if defined _MSC_VER && _MSC_VER >= 1400
793/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
794 * valid and throw an assertion if it isn't.
795 * Normally, an invalid fd is likely to be a C program error and therefore
796 * an assertion can be useful, but it does contradict the POSIX standard
797 * which for write(2) states:
798 * "Otherwise, -1 shall be returned and errno set to indicate the error."
799 * "[EBADF] The fildes argument is not a valid file descriptor open for
800 * writing."
801 * Furthermore, python allows the user to enter any old integer
802 * as a fd and should merely raise a python exception on error.
803 * The Microsoft CRT doesn't provide an official way to check for the
804 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * internal structures involved.
807 * The structures below must be updated for each version of visual studio
808 * according to the file internal.h in the CRT source, until MS comes
809 * up with a less hacky way to do this.
810 * (all of this is to avoid globally modifying the CRT behaviour using
811 * _set_invalid_parameter_handler() and _CrtSetReportMode())
812 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000813/* The actual size of the structure is determined at runtime.
814 * Only the first items must be present.
815 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000816typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000817 intptr_t osfhnd;
818 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000819} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000820
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000821extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000822#define IOINFO_L2E 5
823#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
824#define IOINFO_ARRAYS 64
825#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
826#define FOPEN 0x01
827#define _NO_CONSOLE_FILENO (intptr_t)-2
828
829/* This function emulates what the windows CRT does to validate file handles */
830int
831_PyVerify_fd(int fd)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 const int i1 = fd >> IOINFO_L2E;
834 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000835
Antoine Pitrou22e41552010-08-15 18:07:50 +0000836 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000837
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 /* Determine the actual size of the ioinfo structure,
839 * as used by the CRT loaded in memory
840 */
841 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
842 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
843 }
844 if (sizeof_ioinfo == 0) {
845 /* This should not happen... */
846 goto fail;
847 }
848
849 /* See that it isn't a special CLEAR fileno */
850 if (fd != _NO_CONSOLE_FILENO) {
851 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
852 * we check pointer validity and other info
853 */
854 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
855 /* finally, check that the file is open */
856 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
857 if (info->osfile & FOPEN) {
858 return 1;
859 }
860 }
861 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000862 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 errno = EBADF;
864 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000865}
866
867/* the special case of checking dup2. The target fd must be in a sensible range */
868static int
869_PyVerify_fd_dup2(int fd1, int fd2)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 if (!_PyVerify_fd(fd1))
872 return 0;
873 if (fd2 == _NO_CONSOLE_FILENO)
874 return 0;
875 if ((unsigned)fd2 < _NHANDLE_)
876 return 1;
877 else
878 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000879}
880#else
881/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
882#define _PyVerify_fd_dup2(A, B) (1)
883#endif
884
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000885#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000886/* The following structure was copied from
887 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
888 include doesn't seem to be present in the Windows SDK (at least as included
889 with Visual Studio Express). */
890typedef struct _REPARSE_DATA_BUFFER {
891 ULONG ReparseTag;
892 USHORT ReparseDataLength;
893 USHORT Reserved;
894 union {
895 struct {
896 USHORT SubstituteNameOffset;
897 USHORT SubstituteNameLength;
898 USHORT PrintNameOffset;
899 USHORT PrintNameLength;
900 ULONG Flags;
901 WCHAR PathBuffer[1];
902 } SymbolicLinkReparseBuffer;
903
904 struct {
905 USHORT SubstituteNameOffset;
906 USHORT SubstituteNameLength;
907 USHORT PrintNameOffset;
908 USHORT PrintNameLength;
909 WCHAR PathBuffer[1];
910 } MountPointReparseBuffer;
911
912 struct {
913 UCHAR DataBuffer[1];
914 } GenericReparseBuffer;
915 };
916} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
917
918#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
919 GenericReparseBuffer)
920#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
921
922static int
Brian Curtind25aef52011-06-13 15:16:04 -0500923win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000924{
925 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
926 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
927 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000928
929 if (0 == DeviceIoControl(
930 reparse_point_handle,
931 FSCTL_GET_REPARSE_POINT,
932 NULL, 0, /* in buffer */
933 target_buffer, sizeof(target_buffer),
934 &n_bytes_returned,
935 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500936 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000937
938 if (reparse_tag)
939 *reparse_tag = rdb->ReparseTag;
940
Brian Curtind25aef52011-06-13 15:16:04 -0500941 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000942}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100943
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000944#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000945
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000947#ifdef WITH_NEXT_FRAMEWORK
948/* On Darwin/MacOSX a shared library or framework has no access to
949** environ directly, we must obtain it with _NSGetEnviron().
950*/
951#include <crt_externs.h>
952static char **environ;
953#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000955#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000958convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000963#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000964 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000965#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000966#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 APIRET rc;
968 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
969#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000970
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 d = PyDict_New();
972 if (d == NULL)
973 return NULL;
974#ifdef WITH_NEXT_FRAMEWORK
975 if (environ == NULL)
976 environ = *_NSGetEnviron();
977#endif
978#ifdef MS_WINDOWS
979 /* _wenviron must be initialized in this way if the program is started
980 through main() instead of wmain(). */
981 _wgetenv(L"");
982 if (_wenviron == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = _wenviron; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 wchar_t *p = wcschr(*e, L'=');
989 if (p == NULL)
990 continue;
991 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000995 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
1008 }
1009#else
1010 if (environ == NULL)
1011 return d;
1012 /* This part ignores errors */
1013 for (e = environ; *e != NULL; e++) {
1014 PyObject *k;
1015 PyObject *v;
1016 char *p = strchr(*e, '=');
1017 if (p == NULL)
1018 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001019 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 if (k == NULL) {
1021 PyErr_Clear();
1022 continue;
1023 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001024 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 if (v == NULL) {
1026 PyErr_Clear();
1027 Py_DECREF(k);
1028 continue;
1029 }
1030 if (PyDict_GetItem(d, k) == NULL) {
1031 if (PyDict_SetItem(d, k, v) != 0)
1032 PyErr_Clear();
1033 }
1034 Py_DECREF(k);
1035 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001036 }
1037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001038#if defined(PYOS_OS2)
1039 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1040 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1041 PyObject *v = PyBytes_FromString(buffer);
1042 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1043 Py_DECREF(v);
1044 }
1045 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1046 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1047 PyObject *v = PyBytes_FromString(buffer);
1048 PyDict_SetItemString(d, "ENDLIBPATH", v);
1049 Py_DECREF(v);
1050 }
1051#endif
1052 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055/* Set a POSIX-specific error from errno, and return NULL */
1056
Barry Warsawd58d7641998-07-23 16:14:40 +00001057static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001058posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061}
Barry Warsawd58d7641998-07-23 16:14:40 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001066}
1067
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001068
Mark Hammondef8b6542001-05-13 08:04:26 +00001069static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001070posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001071{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001072 PyObject *name_str, *rc;
1073 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1074 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001076 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1077 name_str);
1078 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001080}
1081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001082#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001083static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001084win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 /* XXX We should pass the function name along in the future.
1087 (winreg.c also wants to pass the function name.)
1088 This would however require an additional param to the
1089 Windows error object, which is non-trivial.
1090 */
1091 errno = GetLastError();
1092 if (filename)
1093 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1094 else
1095 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001097
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001098static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001099win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 /* XXX - see win32_error for comments on 'function' */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107}
1108
Victor Stinnereb5657a2011-09-30 01:44:27 +02001109static PyObject *
1110win32_error_object(char* function, PyObject* filename)
1111{
1112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1116 PyExc_WindowsError,
1117 errno,
1118 filename);
1119 else
1120 return PyErr_SetFromWindowsErr(errno);
1121}
1122
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001123#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125/*
1126 * Some functions return Win32 errors, others only ever use posix_error
1127 * (this is for backwards compatibility with exceptions)
1128 */
1129static PyObject *
1130path_posix_error(char *function_name, path_t *path)
1131{
1132 if (path->narrow)
1133 return posix_error_with_filename(path->narrow);
1134 return posix_error();
1135}
1136
1137static PyObject *
1138path_error(char *function_name, path_t *path)
1139{
1140#ifdef MS_WINDOWS
1141 if (path->narrow)
1142 return win32_error(function_name, path->narrow);
1143 if (path->wide)
1144 return win32_error_unicode(function_name, path->wide);
1145 return win32_error(function_name, NULL);
1146#else
1147 return path_posix_error(function_name, path);
1148#endif
1149}
1150
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151#if defined(PYOS_OS2)
1152/**********************************************************************
1153 * Helper Function to Trim and Format OS/2 Messages
1154 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001155static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001156os2_formatmsg(char *msgbuf, int msglen, char *reason)
1157{
1158 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1159
1160 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1161 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1162
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001163 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001164 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1165 }
1166
1167 /* Add Optional Reason Text */
1168 if (reason) {
1169 strcat(msgbuf, " : ");
1170 strcat(msgbuf, reason);
1171 }
1172}
1173
1174/**********************************************************************
1175 * Decode an OS/2 Operating System Error Code
1176 *
1177 * A convenience function to lookup an OS/2 error code and return a
1178 * text message we can use to raise a Python exception.
1179 *
1180 * Notes:
1181 * The messages for errors returned from the OS/2 kernel reside in
1182 * the file OSO001.MSG in the \OS2 directory hierarchy.
1183 *
1184 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001185static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001186os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1187{
1188 APIRET rc;
1189 ULONG msglen;
1190
1191 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1192 Py_BEGIN_ALLOW_THREADS
1193 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1194 errorcode, "oso001.msg", &msglen);
1195 Py_END_ALLOW_THREADS
1196
1197 if (rc == NO_ERROR)
1198 os2_formatmsg(msgbuf, msglen, reason);
1199 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001200 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001202
1203 return msgbuf;
1204}
1205
1206/* Set an OS/2-specific error and return NULL. OS/2 kernel
1207 errors are not in a global variable e.g. 'errno' nor are
1208 they congruent with posix error numbers. */
1209
Victor Stinner8c62be82010-05-06 00:08:46 +00001210static PyObject *
1211os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001212{
1213 char text[1024];
1214 PyObject *v;
1215
1216 os2_strerror(text, sizeof(text), code, "");
1217
1218 v = Py_BuildValue("(is)", code, text);
1219 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001220 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221 Py_DECREF(v);
1222 }
1223 return NULL; /* Signal to Python that an Exception is Pending */
1224}
1225
1226#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227
1228/* POSIX generic methods */
1229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001231posix_fildes(PyObject *fdobj, int (*func)(int))
1232{
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 int fd;
1234 int res;
1235 fd = PyObject_AsFileDescriptor(fdobj);
1236 if (fd < 0)
1237 return NULL;
1238 if (!_PyVerify_fd(fd))
1239 return posix_error();
1240 Py_BEGIN_ALLOW_THREADS
1241 res = (*func)(fd);
1242 Py_END_ALLOW_THREADS
1243 if (res < 0)
1244 return posix_error();
1245 Py_INCREF(Py_None);
1246 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247}
Guido van Rossum21142a01999-01-08 21:05:37 +00001248
1249static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 PyObject *opath1 = NULL;
1253 char *path1;
1254 int res;
1255 if (!PyArg_ParseTuple(args, format,
1256 PyUnicode_FSConverter, &opath1))
1257 return NULL;
1258 path1 = PyBytes_AsString(opath1);
1259 Py_BEGIN_ALLOW_THREADS
1260 res = (*func)(path1);
1261 Py_END_ALLOW_THREADS
1262 if (res < 0)
1263 return posix_error_with_allocated_filename(opath1);
1264 Py_DECREF(opath1);
1265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001270#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001272win32_1str(PyObject* args, char* func,
1273 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1274 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001277 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001279
Victor Stinnereb5657a2011-09-30 01:44:27 +02001280 if (PyArg_ParseTuple(args, wformat, &uni))
1281 {
1282 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1283 if (wstr == NULL)
1284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 Py_END_ALLOW_THREADS
1288 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 Py_INCREF(Py_None);
1291 return Py_None;
1292 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 PyErr_Clear();
1294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (!PyArg_ParseTuple(args, format, &ansi))
1296 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001297 if (win32_warn_bytes_api())
1298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_BEGIN_ALLOW_THREADS
1300 result = funcA(ansi);
1301 Py_END_ALLOW_THREADS
1302 if (!result)
1303 return win32_error(func, ansi);
1304 Py_INCREF(Py_None);
1305 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306
1307}
1308
1309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char new_path[MAX_PATH+1];
1318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
1323 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
1327 than MAX_PATH. */
1328 assert(result <= MAX_PATH+1);
1329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
1348 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1349 if (!result)
1350 return FALSE;
1351 if (result > MAX_PATH+1) {
1352 new_path = malloc(result * sizeof(wchar_t));
1353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
1359 free(new_path);
1360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
1370 free(new_path);
1371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001383
1384struct win32_stat{
1385 int st_dev;
1386 __int64 st_ino;
1387 unsigned short st_mode;
1388 int st_nlink;
1389 int st_uid;
1390 int st_gid;
1391 int st_rdev;
1392 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001393 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001395 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001396 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001397 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001398 int st_ctime_nsec;
1399};
1400
1401static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1402
1403static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1407 /* Cannot simply cast and dereference in_ptr,
1408 since it might not be aligned properly */
1409 __int64 in;
1410 memcpy(&in, in_ptr, sizeof(in));
1411 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001412 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001413}
1414
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness */
1419 __int64 out;
1420 out = time_in + secs_between_epochs;
1421 out = out * 10000000 + nsec_in / 100;
1422 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423}
1424
Martin v. Löwis14694662006-02-03 12:54:16 +00001425/* Below, we *know* that ugo+r is 0444 */
1426#if _S_IREAD != 0400
1427#error Unsupported C library
1428#endif
1429static int
1430attributes_to_mode(DWORD attr)
1431{
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 int m = 0;
1433 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1434 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1435 else
1436 m |= _S_IFREG;
1437 if (attr & FILE_ATTRIBUTE_READONLY)
1438 m |= 0444;
1439 else
1440 m |= 0666;
1441 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442}
1443
1444static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 memset(result, 0, sizeof(*result));
1448 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1449 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1450 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1451 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1452 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001453 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001454 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1456 /* first clear the S_IFMT bits */
1457 result->st_mode ^= (result->st_mode & 0170000);
1458 /* now set the bits that make this a symlink */
1459 result->st_mode |= 0120000;
1460 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463}
1464
Guido van Rossumd8faa362007-04-27 19:54:29 +00001465static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATAA FileData;
1470 hFindFile = FindFirstFileA(pszFile, &FileData);
1471 if (hFindFile == INVALID_HANDLE_VALUE)
1472 return FALSE;
1473 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001474 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001475 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001476 info->dwFileAttributes = FileData.dwFileAttributes;
1477 info->ftCreationTime = FileData.ftCreationTime;
1478 info->ftLastAccessTime = FileData.ftLastAccessTime;
1479 info->ftLastWriteTime = FileData.ftLastWriteTime;
1480 info->nFileSizeHigh = FileData.nFileSizeHigh;
1481 info->nFileSizeLow = FileData.nFileSizeLow;
1482/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001483 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1484 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486}
1487
1488static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 HANDLE hFindFile;
1492 WIN32_FIND_DATAW FileData;
1493 hFindFile = FindFirstFileW(pszFile, &FileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE)
1495 return FALSE;
1496 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001498 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 info->dwFileAttributes = FileData.dwFileAttributes;
1500 info->ftCreationTime = FileData.ftCreationTime;
1501 info->ftLastAccessTime = FileData.ftLastAccessTime;
1502 info->ftLastWriteTime = FileData.ftLastWriteTime;
1503 info->nFileSizeHigh = FileData.nFileSizeHigh;
1504 info->nFileSizeLow = FileData.nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509}
1510
Brian Curtind25aef52011-06-13 15:16:04 -05001511/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1512static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001513static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1514 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515static int
Brian Curtind25aef52011-06-13 15:16:04 -05001516check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517{
Brian Curtind25aef52011-06-13 15:16:04 -05001518 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001519 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1520 DWORD);
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* only recheck */
1523 if (!has_GetFinalPathNameByHandle)
1524 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001525 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001526 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1527 "GetFinalPathNameByHandleA");
1528 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1529 "GetFinalPathNameByHandleW");
1530 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1531 Py_GetFinalPathNameByHandleW;
1532 }
1533 return has_GetFinalPathNameByHandle;
1534}
1535
1536static BOOL
1537get_target_path(HANDLE hdl, wchar_t **target_path)
1538{
1539 int buf_size, result_length;
1540 wchar_t *buf;
1541
1542 /* We have a good handle to the target, use it to determine
1543 the target path name (then we'll call lstat on it). */
1544 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1545 VOLUME_NAME_DOS);
1546 if(!buf_size)
1547 return FALSE;
1548
1549 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001550 if (!buf) {
1551 SetLastError(ERROR_OUTOFMEMORY);
1552 return FALSE;
1553 }
1554
Brian Curtind25aef52011-06-13 15:16:04 -05001555 result_length = Py_GetFinalPathNameByHandleW(hdl,
1556 buf, buf_size, VOLUME_NAME_DOS);
1557
1558 if(!result_length) {
1559 free(buf);
1560 return FALSE;
1561 }
1562
1563 if(!CloseHandle(hdl)) {
1564 free(buf);
1565 return FALSE;
1566 }
1567
1568 buf[result_length] = 0;
1569
1570 *target_path = buf;
1571 return TRUE;
1572}
1573
1574static int
1575win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1576 BOOL traverse);
1577static int
1578win32_xstat_impl(const char *path, struct win32_stat *result,
1579 BOOL traverse)
1580{
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const char *dot;
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1590 traverse reparse point. */
1591 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 }
1593
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 hFile = CreateFileA(
1595 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 0, /* share mode */
1598 NULL, /* security attributes */
1599 OPEN_EXISTING,
1600 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001601 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1602 Because of this, calls like GetFinalPathNameByHandle will return
1603 the symlink path agin and not the actual final path. */
1604 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1605 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 NULL);
1607
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 /* Either the target doesn't exist, or we don't have access to
1610 get a handle to it. If the former, we need to return an error.
1611 If the latter, we can use attributes_from_dir. */
1612 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileA(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 free(target_path);
1656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = strrchr(path, '.');
1665 if (dot) {
1666 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1667 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Brian Curtind25aef52011-06-13 15:16:04 -05001674win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1675 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
1677 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001678 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 const wchar_t *dot;
1683
Brian Curtind25aef52011-06-13 15:16:04 -05001684 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1686 traverse reparse point. */
1687 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 }
1689
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 hFile = CreateFileW(
1691 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 0, /* share mode */
1694 NULL, /* security attributes */
1695 OPEN_EXISTING,
1696 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1698 Because of this, calls like GetFinalPathNameByHandle will return
1699 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001700 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 NULL);
1703
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 /* Either the target doesn't exist, or we don't have access to
1706 get a handle to it. If the former, we need to return an error.
1707 If the latter, we can use attributes_from_dir. */
1708 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
1739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
1750 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 free(target_path);
1752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779static int
1780win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1781{
1782 /* Protocol violation: we explicitly clear errno, instead of
1783 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001784 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 errno = 0;
1786 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787}
Brian Curtind25aef52011-06-13 15:16:04 -05001788/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001789
1790 In Posix, stat automatically traverses symlinks and returns the stat
1791 structure for the target. In Windows, the equivalent GetFileAttributes by
1792 default does not traverse symlinks and instead returns attributes for
1793 the symlink.
1794
1795 Therefore, win32_lstat will get the attributes traditionally, and
1796 win32_stat will first explicitly resolve the symlink target and then will
1797 call win32_lstat on that result.
1798
Ezio Melotti4969f702011-03-15 05:59:46 +02001799 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001801static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001802win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001803{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001804 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001805}
1806
Victor Stinner8c62be82010-05-06 00:08:46 +00001807static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001808win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001809{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001811}
1812
1813static int
1814win32_stat(const char* path, struct win32_stat *result)
1815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001817}
1818
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_stat_w(const wchar_t* path, struct win32_stat *result)
1821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001823}
1824
1825static int
1826win32_fstat(int file_number, struct win32_stat *result)
1827{
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 BY_HANDLE_FILE_INFORMATION info;
1829 HANDLE h;
1830 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001831
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001833
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
1836 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001837
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 if (h == INVALID_HANDLE_VALUE) {
1839 /* This is really a C library error (invalid file handle).
1840 We set the Win32 error to the closes one matching. */
1841 SetLastError(ERROR_INVALID_HANDLE);
1842 return -1;
1843 }
1844 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 type = GetFileType(h);
1847 if (type == FILE_TYPE_UNKNOWN) {
1848 DWORD error = GetLastError();
1849 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 }
1852 /* else: valid but unknown file */
1853 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (type != FILE_TYPE_DISK) {
1856 if (type == FILE_TYPE_CHAR)
1857 result->st_mode = _S_IFCHR;
1858 else if (type == FILE_TYPE_PIPE)
1859 result->st_mode = _S_IFIFO;
1860 return 0;
1861 }
1862
1863 if (!GetFileInformationByHandle(h, &info)) {
1864 return -1;
1865 }
1866
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1870 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
1873#endif /* MS_WINDOWS */
1874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001876"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001878 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1880\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001881Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1882or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001885
1886static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 {"st_mode", "protection bits"},
1888 {"st_ino", "inode"},
1889 {"st_dev", "device"},
1890 {"st_nlink", "number of hard links"},
1891 {"st_uid", "user ID of owner"},
1892 {"st_gid", "group ID of owner"},
1893 {"st_size", "total size, in bytes"},
1894 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1895 {NULL, "integer time of last access"},
1896 {NULL, "integer time of last modification"},
1897 {NULL, "integer time of last change"},
1898 {"st_atime", "time of last access"},
1899 {"st_mtime", "time of last modification"},
1900 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 {"st_atime_ns", "time of last access in nanoseconds"},
1902 {"st_mtime_ns", "time of last modification in nanoseconds"},
1903 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001904#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001907#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001910#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001913#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001915#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001916#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001918#endif
1919#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923};
1924
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001925#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001926#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001929#endif
1930
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1933#else
1934#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1935#endif
1936
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1939#else
1940#define ST_RDEV_IDX ST_BLOCKS_IDX
1941#endif
1942
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001943#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1944#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1945#else
1946#define ST_FLAGS_IDX ST_RDEV_IDX
1947#endif
1948
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001949#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001950#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001951#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001952#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001953#endif
1954
1955#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1956#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1957#else
1958#define ST_BIRTHTIME_IDX ST_GEN_IDX
1959#endif
1960
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001961static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 "stat_result", /* name */
1963 stat_result__doc__, /* doc */
1964 stat_result_fields,
1965 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001966};
1967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1970This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001972or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001973\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975
1976static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"f_bsize", },
1978 {"f_frsize", },
1979 {"f_blocks", },
1980 {"f_bfree", },
1981 {"f_bavail", },
1982 {"f_files", },
1983 {"f_ffree", },
1984 {"f_favail", },
1985 {"f_flag", },
1986 {"f_namemax",},
1987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
1990static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 "statvfs_result", /* name */
1992 statvfs_result__doc__, /* doc */
1993 statvfs_result_fields,
1994 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995};
1996
Ross Lagerwall7807c352011-03-17 20:20:30 +02001997#if defined(HAVE_WAITID) && !defined(__APPLE__)
1998PyDoc_STRVAR(waitid_result__doc__,
1999"waitid_result: Result from waitid.\n\n\
2000This object may be accessed either as a tuple of\n\
2001 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2002or via the attributes si_pid, si_uid, and so on.\n\
2003\n\
2004See os.waitid for more information.");
2005
2006static PyStructSequence_Field waitid_result_fields[] = {
2007 {"si_pid", },
2008 {"si_uid", },
2009 {"si_signo", },
2010 {"si_status", },
2011 {"si_code", },
2012 {0}
2013};
2014
2015static PyStructSequence_Desc waitid_result_desc = {
2016 "waitid_result", /* name */
2017 waitid_result__doc__, /* doc */
2018 waitid_result_fields,
2019 5
2020};
2021static PyTypeObject WaitidResultType;
2022#endif
2023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002024static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025static PyTypeObject StatResultType;
2026static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002027#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002028static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002029#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002030static newfunc structseq_new;
2031
2032static PyObject *
2033statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyStructSequence *result;
2036 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002037
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 result = (PyStructSequence*)structseq_new(type, args, kwds);
2039 if (!result)
2040 return NULL;
2041 /* If we have been initialized from a tuple,
2042 st_?time might be set to None. Initialize it
2043 from the int slots. */
2044 for (i = 7; i <= 9; i++) {
2045 if (result->ob_item[i+3] == Py_None) {
2046 Py_DECREF(Py_None);
2047 Py_INCREF(result->ob_item[i]);
2048 result->ob_item[i+3] = result->ob_item[i];
2049 }
2050 }
2051 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052}
2053
2054
2055
2056/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002057static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002058
2059PyDoc_STRVAR(stat_float_times__doc__,
2060"stat_float_times([newval]) -> oldval\n\n\
2061Determine whether os.[lf]stat represents time stamps as float objects.\n\
2062If newval is True, future calls to stat() return floats, if it is False,\n\
2063future calls return ints. \n\
2064If newval is omitted, return the current setting.\n");
2065
2066static PyObject*
2067stat_float_times(PyObject* self, PyObject *args)
2068{
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 int newval = -1;
2070 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2071 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002072 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2073 "stat_float_times() is deprecated",
2074 1))
2075 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 if (newval == -1)
2077 /* Return old value */
2078 return PyBool_FromLong(_stat_float_times);
2079 _stat_float_times = newval;
2080 Py_INCREF(Py_None);
2081 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002082}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083
Larry Hastings6fe20b32012-04-19 15:07:49 -07002084static PyObject *billion = NULL;
2085
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002086static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002087fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002088{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002089 PyObject *s = _PyLong_FromTime_t(sec);
2090 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2091 PyObject *s_in_ns = NULL;
2092 PyObject *ns_total = NULL;
2093 PyObject *float_s = NULL;
2094
2095 if (!(s && ns_fractional))
2096 goto exit;
2097
2098 s_in_ns = PyNumber_Multiply(s, billion);
2099 if (!s_in_ns)
2100 goto exit;
2101
2102 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2103 if (!ns_total)
2104 goto exit;
2105
Victor Stinner4195b5c2012-02-08 23:03:19 +01002106 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002107 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2108 if (!float_s)
2109 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002111 else {
2112 float_s = s;
2113 Py_INCREF(float_s);
2114 }
2115
2116 PyStructSequence_SET_ITEM(v, index, s);
2117 PyStructSequence_SET_ITEM(v, index+3, float_s);
2118 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2119 s = NULL;
2120 float_s = NULL;
2121 ns_total = NULL;
2122exit:
2123 Py_XDECREF(s);
2124 Py_XDECREF(ns_fractional);
2125 Py_XDECREF(s_in_ns);
2126 Py_XDECREF(ns_total);
2127 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002128}
2129
Tim Peters5aa91602002-01-30 05:46:57 +00002130/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002131 (used by posix_stat() and posix_fstat()) */
2132static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002133_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 unsigned long ansec, mnsec, cnsec;
2136 PyObject *v = PyStructSequence_New(&StatResultType);
2137 if (v == NULL)
2138 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002139
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002141#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002142 PyStructSequence_SET_ITEM(v, 1,
2143 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002144#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002146#endif
2147#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 PyStructSequence_SET_ITEM(v, 2,
2149 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002156#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, 6,
2158 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002161#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002162
Martin v. Löwis14694662006-02-03 12:54:16 +00002163#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 ansec = st->st_atim.tv_nsec;
2165 mnsec = st->st_mtim.tv_nsec;
2166 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002167#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 ansec = st->st_atimespec.tv_nsec;
2169 mnsec = st->st_mtimespec.tv_nsec;
2170 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002171#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 ansec = st->st_atime_nsec;
2173 mnsec = st->st_mtime_nsec;
2174 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002177#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002178 fill_time(v, 7, st->st_atime, ansec);
2179 fill_time(v, 8, st->st_mtime, mnsec);
2180 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002181
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002182#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2184 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002185#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002186#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2188 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002190#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2192 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002193#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002194#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2196 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002197#endif
2198#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002200 PyObject *val;
2201 unsigned long bsec,bnsec;
2202 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002203#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002204 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002205#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002207#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002208 if (_stat_float_times) {
2209 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2210 } else {
2211 val = PyLong_FromLong((long)bsec);
2212 }
2213 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2214 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002216#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002217#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2219 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002220#endif
Fred Drake699f3522000-06-29 21:12:41 +00002221
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 if (PyErr_Occurred()) {
2223 Py_DECREF(v);
2224 return NULL;
2225 }
Fred Drake699f3522000-06-29 21:12:41 +00002226
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002228}
2229
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002230/* POSIX methods */
2231
Guido van Rossum94f6f721999-01-06 18:42:14 +00002232
2233static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002234posix_do_stat(char *function_name, path_t *path,
2235 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002236{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002237 STRUCT_STAT st;
2238 int result;
2239
2240#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2241 if (follow_symlinks_specified(function_name, follow_symlinks))
2242 return NULL;
2243#endif
2244
2245 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2246 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2247 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2248 return NULL;
2249
2250 Py_BEGIN_ALLOW_THREADS
2251 if (path->fd != -1)
2252 result = FSTAT(path->fd, &st);
2253 else
2254#ifdef MS_WINDOWS
2255 if (path->wide) {
2256 if (follow_symlinks)
2257 result = win32_stat_w(path->wide, &st);
2258 else
2259 result = win32_lstat_w(path->wide, &st);
2260 }
2261 else
2262#endif
2263#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2264 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2265 result = LSTAT(path->narrow, &st);
2266 else
2267#endif
2268#ifdef HAVE_FSTATAT
2269 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2270 result = fstatat(dir_fd, path->narrow, &st,
2271 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2272 else
2273#endif
2274 result = STAT(path->narrow, &st);
2275 Py_END_ALLOW_THREADS
2276
2277 if (result != 0)
2278 return path_error("stat", path);
2279
2280 return _pystat_fromstructstat(&st);
2281}
2282
2283PyDoc_STRVAR(posix_stat__doc__,
2284"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2285Perform a stat system call on the given path.\n\
2286\n\
2287path may be specified as either a string or as an open file descriptor.\n\
2288\n\
2289If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2290 and path should be relative; path will then be relative to that directory.\n\
2291 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2292 it will raise a NotImplementedError.\n\
2293If follow_symlinks is False, and the last element of the path is a symbolic\n\
2294 link, stat will examine the symbolic link itself instead of the file the\n\
2295 link points to.\n\
2296It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2297 an open file descriptor.");
2298
2299static PyObject *
2300posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2301{
2302 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2303 path_t path;
2304 int dir_fd = DEFAULT_DIR_FD;
2305 int follow_symlinks = 1;
2306 PyObject *return_value;
2307
2308 memset(&path, 0, sizeof(path));
2309 path.allow_fd = 1;
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2311 path_converter, &path,
2312#ifdef HAVE_FSTATAT
2313 dir_fd_converter, &dir_fd,
2314#else
2315 dir_fd_unavailable, &dir_fd,
2316#endif
2317 &follow_symlinks))
2318 return NULL;
2319 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2320 path_cleanup(&path);
2321 return return_value;
2322}
2323
2324PyDoc_STRVAR(posix_lstat__doc__,
2325"lstat(path, *, dir_fd=None) -> stat result\n\n\
2326Like stat(), but do not follow symbolic links.\n\
2327Equivalent to stat(path, follow_symlinks=False).");
2328
2329static PyObject *
2330posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2331{
2332 static char *keywords[] = {"path", "dir_fd", NULL};
2333 path_t path;
2334 int dir_fd = DEFAULT_DIR_FD;
2335 int follow_symlinks = 0;
2336 PyObject *return_value;
2337
2338 memset(&path, 0, sizeof(path));
2339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2340 path_converter, &path,
2341#ifdef HAVE_FSTATAT
2342 dir_fd_converter, &dir_fd
2343#else
2344 dir_fd_unavailable, &dir_fd
2345#endif
2346 ))
2347 return NULL;
2348 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2349 path_cleanup(&path);
2350 return return_value;
2351}
2352
2353PyDoc_STRVAR(posix_access__doc__,
2354"access(path, mode, *, dir_fd=None, effective_ids=False,\
2355 follow_symlinks=True)\n\n\
2356Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2357False otherwise.\n\
2358\n\
2359If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2360 and path should be relative; path will then be relative to that directory.\n\
2361If effective_ids is True, access will use the effective uid/gid instead of\n\
2362 the real uid/gid.\n\
2363If follow_symlinks is False, and the last element of the path is a symbolic\n\
2364 link, access will examine the symbolic link itself instead of the file the\n\
2365 link points to.\n\
2366dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2367 on your platform. If they are unavailable, using them will raise a\n\
2368 NotImplementedError.\n\
2369\n\
2370Note that most operations will use the effective uid/gid, therefore this\n\
2371 routine can be used in a suid/sgid environment to test if the invoking user\n\
2372 has the specified access to the path.\n\
2373The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2374 of R_OK, W_OK, and X_OK.");
2375
2376static PyObject *
2377posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2378{
2379 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2380 "follow_symlinks", NULL};
2381 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002382 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002383 int dir_fd = DEFAULT_DIR_FD;
2384 int effective_ids = 0;
2385 int follow_symlinks = 1;
2386 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002387
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002388#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002392#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002393
2394 memset(&path, 0, sizeof(path));
2395 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2396 path_converter, &path, &mode,
2397#ifdef HAVE_FACCESSAT
2398 dir_fd_converter, &dir_fd,
2399#else
2400 dir_fd_unavailable, &dir_fd,
2401#endif
2402 &effective_ids, &follow_symlinks))
2403 return NULL;
2404
2405#ifndef HAVE_FACCESSAT
2406 if (follow_symlinks_specified("access", follow_symlinks))
2407 goto exit;
2408
2409 if (effective_ids) {
2410 argument_unavailable_error("access", "effective_ids");
2411 goto exit;
2412 }
2413#endif
2414
2415#ifdef MS_WINDOWS
2416 Py_BEGIN_ALLOW_THREADS
2417 if (path.wide != NULL)
2418 attr = GetFileAttributesW(path.wide);
2419 else
2420 attr = GetFileAttributesA(path.narrow);
2421 Py_END_ALLOW_THREADS
2422
2423 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002424 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002425 * * we didn't get a -1, and
2426 * * write access wasn't requested,
2427 * * or the file isn't read-only,
2428 * * or it's a directory.
2429 * (Directories cannot be read-only on Windows.)
2430 */
2431 return_value = PyBool_FromLong(
2432 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002433 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002434 !(attr & FILE_ATTRIBUTE_READONLY) ||
2435 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2436#else
2437
2438 Py_BEGIN_ALLOW_THREADS
2439#ifdef HAVE_FACCESSAT
2440 if ((dir_fd != DEFAULT_DIR_FD) ||
2441 effective_ids ||
2442 !follow_symlinks) {
2443 int flags = 0;
2444 if (!follow_symlinks)
2445 flags |= AT_SYMLINK_NOFOLLOW;
2446 if (effective_ids)
2447 flags |= AT_EACCESS;
2448 result = faccessat(dir_fd, path.narrow, mode, flags);
2449 }
2450 else
2451#endif
2452 result = access(path.narrow, mode);
2453 Py_END_ALLOW_THREADS
2454 return_value = PyBool_FromLong(!result);
2455#endif
2456
2457#ifndef HAVE_FACCESSAT
2458exit:
2459#endif
2460 path_cleanup(&path);
2461 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002462}
2463
Guido van Rossumd371ff11999-01-25 16:12:23 +00002464#ifndef F_OK
2465#define F_OK 0
2466#endif
2467#ifndef R_OK
2468#define R_OK 4
2469#endif
2470#ifndef W_OK
2471#define W_OK 2
2472#endif
2473#ifndef X_OK
2474#define X_OK 1
2475#endif
2476
2477#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484{
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 int id;
2486 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2489 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002491#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002492 /* file descriptor 0 only, the default input device (stdin) */
2493 if (id == 0) {
2494 ret = ttyname();
2495 }
2496 else {
2497 ret = NULL;
2498 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (ret == NULL)
2503 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002504 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002508#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002510"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512
2513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002514posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515{
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 char *ret;
2517 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518
Greg Wardb48bc172000-03-01 21:51:56 +00002519#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (ret == NULL)
2525 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002526 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527}
2528#endif
2529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532Change the current working directory to the specified path.\n\
2533\n\
2534path may always be specified as a string.\n\
2535On some platforms, path may also be specified as an open file descriptor.\n\
2536 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 path_t path;
2542 int result;
2543 PyObject *return_value = NULL;
2544 static char *keywords[] = {"path", NULL};
2545
2546 memset(&path, 0, sizeof(path));
2547#ifdef HAVE_FCHDIR
2548 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2551 path_converter, &path
2552 ))
2553 return NULL;
2554
2555 Py_BEGIN_ALLOW_THREADS
2556#ifdef MS_WINDOWS
2557 if (path.wide)
2558 result = win32_wchdir(path.wide);
2559 else
2560 result = win32_chdir(path.narrow);
2561 result = !result; /* on unix, success = 0, on windows, success = !0 */
2562#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2563 result = _chdir2(path.narrow);
2564#else
2565#ifdef HAVE_FCHDIR
2566 if (path.fd != -1)
2567 result = fchdir(path.fd);
2568 else
2569#endif
2570 result = chdir(path.narrow);
2571#endif
2572 Py_END_ALLOW_THREADS
2573
2574 if (result) {
2575 return_value = path_error("chdir", &path);
2576 goto exit;
2577 }
2578
2579 return_value = Py_None;
2580 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002581
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582exit:
2583 path_cleanup(&path);
2584 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002585}
2586
Fred Drake4d1e64b2002-04-15 19:40:07 +00002587#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589"fchdir(fd)\n\n\
2590Change to the directory of the given file descriptor. fd must be\n\
2591opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002592
2593static PyObject *
2594posix_fchdir(PyObject *self, PyObject *fdobj)
2595{
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002597}
2598#endif /* HAVE_FCHDIR */
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002601PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2603Change the access permissions of a file.\n\
2604\n\
2605path may always be specified as a string.\n\
2606On some platforms, path may also be specified as an open file descriptor.\n\
2607 If this functionality is unavailable, using it raises an exception.\n\
2608If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2609 and path should be relative; path will then be relative to that directory.\n\
2610If follow_symlinks is False, and the last element of the path is a symbolic\n\
2611 link, chmod will modify the symbolic link itself instead of the file the\n\
2612 link points to.\n\
2613It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2614 an open file descriptor.\n\
2615dir_fd and follow_symlinks may not be implemented on your platform.\n\
2616 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002617
Barry Warsaw53699e91996-12-10 23:23:01 +00002618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 path_t path;
2622 int mode;
2623 int dir_fd = DEFAULT_DIR_FD;
2624 int follow_symlinks = 1;
2625 int result;
2626 PyObject *return_value = NULL;
2627 static char *keywords[] = {"path", "mode", "dir_fd",
2628 "follow_symlinks", NULL};
2629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002630#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002633
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634#ifdef HAVE_FCHMODAT
2635 int fchmodat_nofollow_unsupported = 0;
2636#endif
2637
2638 memset(&path, 0, sizeof(path));
2639#ifdef HAVE_FCHMOD
2640 path.allow_fd = 1;
2641#endif
2642 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2643 path_converter, &path,
2644 &mode,
2645#ifdef HAVE_FCHMODAT
2646 dir_fd_converter, &dir_fd,
2647#else
2648 dir_fd_unavailable, &dir_fd,
2649#endif
2650 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002651 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652
2653#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2654 if (follow_symlinks_specified("chmod", follow_symlinks))
2655 goto exit;
2656#endif
2657
2658#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002659 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 if (path.wide)
2661 attr = GetFileAttributesW(path.wide);
2662 else
2663 attr = GetFileAttributesA(path.narrow);
2664 if (attr == 0xFFFFFFFF)
2665 result = 0;
2666 else {
2667 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 attr &= ~FILE_ATTRIBUTE_READONLY;
2669 else
2670 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 if (path.wide)
2672 result = SetFileAttributesW(path.wide, attr);
2673 else
2674 result = SetFileAttributesA(path.narrow, attr);
2675 }
2676 Py_END_ALLOW_THREADS
2677
2678 if (!result) {
2679 return_value = win32_error_object("chmod", path.object);
2680 goto exit;
2681 }
2682#else /* MS_WINDOWS */
2683 Py_BEGIN_ALLOW_THREADS
2684#ifdef HAVE_FCHMOD
2685 if (path.fd != -1)
2686 result = fchmod(path.fd, mode);
2687 else
2688#endif
2689#ifdef HAVE_LCHMOD
2690 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2691 result = lchmod(path.narrow, mode);
2692 else
2693#endif
2694#ifdef HAVE_FCHMODAT
2695 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2696 /*
2697 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2698 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002699 * and then says it isn't implemented yet.
2700 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 *
2702 * Once it is supported, os.chmod will automatically
2703 * support dir_fd and follow_symlinks=False. (Hopefully.)
2704 * Until then, we need to be careful what exception we raise.
2705 */
2706 result = fchmodat(dir_fd, path.narrow, mode,
2707 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2708 /*
2709 * But wait! We can't throw the exception without allowing threads,
2710 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2711 */
2712 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002713 result &&
2714 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2715 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 }
2717 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002718#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719 result = chmod(path.narrow, mode);
2720 Py_END_ALLOW_THREADS
2721
2722 if (result) {
2723#ifdef HAVE_FCHMODAT
2724 if (fchmodat_nofollow_unsupported) {
2725 if (dir_fd != DEFAULT_DIR_FD)
2726 dir_fd_and_follow_symlinks_invalid("chmod",
2727 dir_fd, follow_symlinks);
2728 else
2729 follow_symlinks_specified("chmod", follow_symlinks);
2730 }
2731 else
2732#endif
2733 return_value = path_error("chmod", &path);
2734 goto exit;
2735 }
2736#endif
2737
2738 Py_INCREF(Py_None);
2739 return_value = Py_None;
2740exit:
2741 path_cleanup(&path);
2742 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002743}
2744
Larry Hastings9cf065c2012-06-22 16:30:09 -07002745
Christian Heimes4e30a842007-11-30 22:12:06 +00002746#ifdef HAVE_FCHMOD
2747PyDoc_STRVAR(posix_fchmod__doc__,
2748"fchmod(fd, mode)\n\n\
2749Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002751
2752static PyObject *
2753posix_fchmod(PyObject *self, PyObject *args)
2754{
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 int fd, mode, res;
2756 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2757 return NULL;
2758 Py_BEGIN_ALLOW_THREADS
2759 res = fchmod(fd, mode);
2760 Py_END_ALLOW_THREADS
2761 if (res < 0)
2762 return posix_error();
2763 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002764}
2765#endif /* HAVE_FCHMOD */
2766
2767#ifdef HAVE_LCHMOD
2768PyDoc_STRVAR(posix_lchmod__doc__,
2769"lchmod(path, mode)\n\n\
2770Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771affects the link itself rather than the target.\n\
2772Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002773
2774static PyObject *
2775posix_lchmod(PyObject *self, PyObject *args)
2776{
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 PyObject *opath;
2778 char *path;
2779 int i;
2780 int res;
2781 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2782 &opath, &i))
2783 return NULL;
2784 path = PyBytes_AsString(opath);
2785 Py_BEGIN_ALLOW_THREADS
2786 res = lchmod(path, i);
2787 Py_END_ALLOW_THREADS
2788 if (res < 0)
2789 return posix_error_with_allocated_filename(opath);
2790 Py_DECREF(opath);
2791 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002792}
2793#endif /* HAVE_LCHMOD */
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Thomas Wouterscf297e42007-02-23 15:07:44 +00002796#ifdef HAVE_CHFLAGS
2797PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798"chflags(path, flags, *, follow_symlinks=True)\n\n\
2799Set file flags.\n\
2800\n\
2801If follow_symlinks is False, and the last element of the path is a symbolic\n\
2802 link, chflags will change flags on the symbolic link itself instead of the\n\
2803 file the link points to.\n\
2804follow_symlinks may not be implemented on your platform. If it is\n\
2805unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002806
2807static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002809{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002811 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 int follow_symlinks = 1;
2813 int result;
2814 PyObject *return_value;
2815 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2816
2817 memset(&path, 0, sizeof(path));
2818 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2819 path_converter, &path,
2820 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822
2823#ifndef HAVE_LCHFLAGS
2824 if (follow_symlinks_specified("chflags", follow_symlinks))
2825 goto exit;
2826#endif
2827
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829#ifdef HAVE_LCHFLAGS
2830 if (!follow_symlinks)
2831 result = lchflags(path.narrow, flags);
2832 else
2833#endif
2834 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002835 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836
2837 if (result) {
2838 return_value = path_posix_error("chflags", &path);
2839 goto exit;
2840 }
2841
2842 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844
2845exit:
2846 path_cleanup(&path);
2847 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002848}
2849#endif /* HAVE_CHFLAGS */
2850
2851#ifdef HAVE_LCHFLAGS
2852PyDoc_STRVAR(posix_lchflags__doc__,
2853"lchflags(path, flags)\n\n\
2854Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855This function will not follow symbolic links.\n\
2856Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002857
2858static PyObject *
2859posix_lchflags(PyObject *self, PyObject *args)
2860{
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 PyObject *opath;
2862 char *path;
2863 unsigned long flags;
2864 int res;
2865 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2866 PyUnicode_FSConverter, &opath, &flags))
2867 return NULL;
2868 path = PyBytes_AsString(opath);
2869 Py_BEGIN_ALLOW_THREADS
2870 res = lchflags(path, flags);
2871 Py_END_ALLOW_THREADS
2872 if (res < 0)
2873 return posix_error_with_allocated_filename(opath);
2874 Py_DECREF(opath);
2875 Py_INCREF(Py_None);
2876 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002877}
2878#endif /* HAVE_LCHFLAGS */
2879
Martin v. Löwis244edc82001-10-04 22:44:26 +00002880#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002881PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002882"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002884
2885static PyObject *
2886posix_chroot(PyObject *self, PyObject *args)
2887{
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002889}
2890#endif
2891
Guido van Rossum21142a01999-01-08 21:05:37 +00002892#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002896
2897static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002898posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002899{
Stefan Krah0e803b32010-11-26 16:16:47 +00002900 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002901}
2902#endif /* HAVE_FSYNC */
2903
Ross Lagerwall7807c352011-03-17 20:20:30 +02002904#ifdef HAVE_SYNC
2905PyDoc_STRVAR(posix_sync__doc__,
2906"sync()\n\n\
2907Force write of everything to disk.");
2908
2909static PyObject *
2910posix_sync(PyObject *self, PyObject *noargs)
2911{
2912 Py_BEGIN_ALLOW_THREADS
2913 sync();
2914 Py_END_ALLOW_THREADS
2915 Py_RETURN_NONE;
2916}
2917#endif
2918
Guido van Rossum21142a01999-01-08 21:05:37 +00002919#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002920
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002921#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002922extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2923#endif
2924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002927force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002929
2930static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002931posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002932{
Stefan Krah0e803b32010-11-26 16:16:47 +00002933 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002934}
2935#endif /* HAVE_FDATASYNC */
2936
2937
Fredrik Lundh10723342000-07-10 16:38:09 +00002938#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2941Change the owner and group id of path to the numeric uid and gid.\n\
2942\n\
2943path may always be specified as a string.\n\
2944On some platforms, path may also be specified as an open file descriptor.\n\
2945 If this functionality is unavailable, using it raises an exception.\n\
2946If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2947 and path should be relative; path will then be relative to that directory.\n\
2948If follow_symlinks is False, and the last element of the path is a symbolic\n\
2949 link, chown will modify the symbolic link itself instead of the file the\n\
2950 link points to.\n\
2951It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2952 an open file descriptor.\n\
2953dir_fd and follow_symlinks may not be implemented on your platform.\n\
2954 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002958{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 path_t path;
2960 long uid_l, gid_l;
2961 uid_t uid;
2962 gid_t gid;
2963 int dir_fd = DEFAULT_DIR_FD;
2964 int follow_symlinks = 1;
2965 int result;
2966 PyObject *return_value = NULL;
2967 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2968 "follow_symlinks", NULL};
2969
2970 memset(&path, 0, sizeof(path));
2971#ifdef HAVE_FCHOWN
2972 path.allow_fd = 1;
2973#endif
2974 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2975 path_converter, &path,
2976 &uid_l, &gid_l,
2977#ifdef HAVE_FCHOWNAT
2978 dir_fd_converter, &dir_fd,
2979#else
2980 dir_fd_unavailable, &dir_fd,
2981#endif
2982 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
2985#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2986 if (follow_symlinks_specified("chown", follow_symlinks))
2987 goto exit;
2988#endif
2989 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2990 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2991 goto exit;
2992
2993#ifdef __APPLE__
2994 /*
2995 * This is for Mac OS X 10.3, which doesn't have lchown.
2996 * (But we still have an lchown symbol because of weak-linking.)
2997 * It doesn't have fchownat either. So there's no possibility
2998 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002999 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000 if ((!follow_symlinks) && (lchown == NULL)) {
3001 follow_symlinks_specified("chown", follow_symlinks);
3002 goto exit;
3003 }
3004#endif
3005
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007 uid = (uid_t)uid_l;
3008 gid = (uid_t)gid_l;
3009#ifdef HAVE_FCHOWN
3010 if (path.fd != -1)
3011 result = fchown(path.fd, uid, gid);
3012 else
3013#endif
3014#ifdef HAVE_LCHOWN
3015 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3016 result = lchown(path.narrow, uid, gid);
3017 else
3018#endif
3019#ifdef HAVE_FCHOWNAT
3020 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3021 result = fchownat(dir_fd, path.narrow, uid, gid,
3022 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3023 else
3024#endif
3025 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027
3028 if (result) {
3029 return_value = path_posix_error("chown", &path);
3030 goto exit;
3031 }
3032
3033 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035
3036exit:
3037 path_cleanup(&path);
3038 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003039}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003040#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003041
Christian Heimes4e30a842007-11-30 22:12:06 +00003042#ifdef HAVE_FCHOWN
3043PyDoc_STRVAR(posix_fchown__doc__,
3044"fchown(fd, uid, gid)\n\n\
3045Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003047
3048static PyObject *
3049posix_fchown(PyObject *self, PyObject *args)
3050{
Victor Stinner8c62be82010-05-06 00:08:46 +00003051 int fd;
3052 long uid, gid;
3053 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003054 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 return NULL;
3056 Py_BEGIN_ALLOW_THREADS
3057 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3058 Py_END_ALLOW_THREADS
3059 if (res < 0)
3060 return posix_error();
3061 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003062}
3063#endif /* HAVE_FCHOWN */
3064
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003065#ifdef HAVE_LCHOWN
3066PyDoc_STRVAR(posix_lchown__doc__,
3067"lchown(path, uid, gid)\n\n\
3068Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069This function will not follow symbolic links.\n\
3070Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003071
3072static PyObject *
3073posix_lchown(PyObject *self, PyObject *args)
3074{
Victor Stinner8c62be82010-05-06 00:08:46 +00003075 PyObject *opath;
3076 char *path;
3077 long uid, gid;
3078 int res;
3079 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3080 PyUnicode_FSConverter, &opath,
3081 &uid, &gid))
3082 return NULL;
3083 path = PyBytes_AsString(opath);
3084 Py_BEGIN_ALLOW_THREADS
3085 res = lchown(path, (uid_t) uid, (gid_t) gid);
3086 Py_END_ALLOW_THREADS
3087 if (res < 0)
3088 return posix_error_with_allocated_filename(opath);
3089 Py_DECREF(opath);
3090 Py_INCREF(Py_None);
3091 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003092}
3093#endif /* HAVE_LCHOWN */
3094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095
Guido van Rossum36bc6801995-06-14 22:54:23 +00003096#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003097static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003098posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003099{
Victor Stinner8c62be82010-05-06 00:08:46 +00003100 char buf[1026];
3101 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 if (!use_bytes) {
3105 wchar_t wbuf[1026];
3106 wchar_t *wbuf2 = wbuf;
3107 PyObject *resobj;
3108 DWORD len;
3109 Py_BEGIN_ALLOW_THREADS
3110 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3111 /* If the buffer is large enough, len does not include the
3112 terminating \0. If the buffer is too small, len includes
3113 the space needed for the terminator. */
3114 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3115 wbuf2 = malloc(len * sizeof(wchar_t));
3116 if (wbuf2)
3117 len = GetCurrentDirectoryW(len, wbuf2);
3118 }
3119 Py_END_ALLOW_THREADS
3120 if (!wbuf2) {
3121 PyErr_NoMemory();
3122 return NULL;
3123 }
3124 if (!len) {
3125 if (wbuf2 != wbuf) free(wbuf2);
3126 return win32_error("getcwdu", NULL);
3127 }
3128 resobj = PyUnicode_FromWideChar(wbuf2, len);
3129 if (wbuf2 != wbuf) free(wbuf2);
3130 return resobj;
3131 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003132
3133 if (win32_warn_bytes_api())
3134 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135#endif
3136
Victor Stinner8c62be82010-05-06 00:08:46 +00003137 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003138#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003140#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003142#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 Py_END_ALLOW_THREADS
3144 if (res == NULL)
3145 return posix_error();
3146 if (use_bytes)
3147 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003148 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003149}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003150
3151PyDoc_STRVAR(posix_getcwd__doc__,
3152"getcwd() -> path\n\n\
3153Return a unicode string representing the current working directory.");
3154
3155static PyObject *
3156posix_getcwd_unicode(PyObject *self)
3157{
3158 return posix_getcwd(0);
3159}
3160
3161PyDoc_STRVAR(posix_getcwdb__doc__,
3162"getcwdb() -> path\n\n\
3163Return a bytes string representing the current working directory.");
3164
3165static PyObject *
3166posix_getcwd_bytes(PyObject *self)
3167{
3168 return posix_getcwd(1);
3169}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003170#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003171
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3173#define HAVE_LINK 1
3174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3179Create a hard link to a file.\n\
3180\n\
3181If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3182 descriptor open to a directory, and the respective path string (src or dst)\n\
3183 should be relative; the path will then be relative to that directory.\n\
3184If follow_symlinks is False, and the last element of src is a symbolic\n\
3185 link, link will create a link to the symbolic link itself instead of the\n\
3186 file the link points to.\n\
3187src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3188 platform. If they are unavailable, using them will raise a\n\
3189 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Barry Warsaw53699e91996-12-10 23:23:01 +00003191static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003193{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 path_t src, dst;
3195 int src_dir_fd = DEFAULT_DIR_FD;
3196 int dst_dir_fd = DEFAULT_DIR_FD;
3197 int follow_symlinks = 1;
3198 PyObject *return_value = NULL;
3199 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3200 "follow_symlinks", NULL};
3201#ifdef MS_WINDOWS
3202 BOOL result;
3203#else
3204 int result;
3205#endif
3206
3207 memset(&src, 0, sizeof(src));
3208 memset(&dst, 0, sizeof(dst));
3209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3210 path_converter, &src,
3211 path_converter, &dst,
3212 dir_fd_converter, &src_dir_fd,
3213 dir_fd_converter, &dst_dir_fd,
3214 &follow_symlinks))
3215 return NULL;
3216
3217#ifndef HAVE_LINKAT
3218 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3219 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3220 goto exit;
3221 }
3222#endif
3223
3224 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3225 PyErr_SetString(PyExc_NotImplementedError,
3226 "link: src and dst must be the same type");
3227 goto exit;
3228 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003229
Brian Curtin1b9df392010-11-24 20:24:31 +00003230#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231 Py_BEGIN_ALLOW_THREADS
3232 if (src.wide)
3233 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3234 else
3235 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3236 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003237
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 if (!result) {
3239 return_value = win32_error_object("link", dst.object);
3240 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003241 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242#else
3243 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003244#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3246 (dst_dir_fd != DEFAULT_DIR_FD) ||
3247 (!follow_symlinks))
3248 result = linkat(src_dir_fd, src.narrow,
3249 dst_dir_fd, dst.narrow,
3250 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3251 else
3252#endif
3253 result = link(src.narrow, dst.narrow);
3254 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003255
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 if (result) {
3257 return_value = path_error("link", &dst);
3258 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003259 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260#endif
3261
3262 return_value = Py_None;
3263 Py_INCREF(Py_None);
3264
3265exit:
3266 path_cleanup(&src);
3267 path_cleanup(&dst);
3268 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003269}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270#endif
3271
Brian Curtin1b9df392010-11-24 20:24:31 +00003272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003274PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275"listdir(path='.') -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276Return a list containing the names of the entries in the directory.\n\
3277\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279entries '.' and '..' even if they are present in the directory.\n\
3280\n\
3281path can always be specified as a string.\n\
3282On some platforms, path may also be specified as an open file descriptor.\n\
3283 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Barry Warsaw53699e91996-12-10 23:23:01 +00003285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288 path_t path;
3289 PyObject *list = NULL;
3290 static char *keywords[] = {"path", NULL};
3291 int fd = -1;
3292
3293#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3294 PyObject *v;
3295 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3296 BOOL result;
3297 WIN32_FIND_DATA FileData;
3298 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3299 char *bufptr = namebuf;
3300 /* only claim to have space for MAX_PATH */
3301 Py_ssize_t len = sizeof(namebuf)-5;
3302 PyObject *po = NULL;
3303 wchar_t *wnamebuf = NULL;
3304#elif defined(PYOS_OS2)
3305#ifndef MAX_PATH
3306#define MAX_PATH CCHMAXPATH
3307#endif
3308 char *pt;
3309 PyObject *v;
3310 char namebuf[MAX_PATH+5];
3311 HDIR hdir = 1;
3312 ULONG srchcnt = 1;
3313 FILEFINDBUF3 ep;
3314 APIRET rc;
3315#else
3316 PyObject *v;
3317 DIR *dirp = NULL;
3318 struct dirent *ep;
Georg Brandlf7875592012-06-24 13:58:31 +02003319 int arg_is_unicode = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003320#endif
3321
3322 memset(&path, 0, sizeof(path));
3323 path.nullable = 1;
3324#ifdef HAVE_FDOPENDIR
3325 path.allow_fd = 1;
3326 path.fd = -1;
3327#endif
3328 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3329 path_converter, &path
3330 ))
3331 return NULL;
3332
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 /* XXX Should redo this putting the (now four) versions of opendir
3334 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003335#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003339
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003341 po_wchars = L".";
3342 len = 1;
3343 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 po_wchars = path.wide;
3345 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3349 if (!wnamebuf) {
3350 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003353 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003355 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (wch != L'/' && wch != L'\\' && wch != L':')
3357 wnamebuf[len++] = L'\\';
3358 wcscpy(wnamebuf + len, L"*.*");
3359 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 if ((list = PyList_New(0)) == NULL) {
3361 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003363 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003365 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 if (hFindFile == INVALID_HANDLE_VALUE) {
3367 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 if (error == ERROR_FILE_NOT_FOUND)
3369 goto exit;
3370 Py_DECREF(list);
3371 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 }
3375 do {
3376 /* Skip over . and .. */
3377 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3378 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 v = PyUnicode_FromWideChar(wFileData.cFileName,
3380 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 Py_DECREF(list);
3383 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 break;
3385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003387 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 Py_DECREF(list);
3389 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 break;
3391 }
3392 Py_DECREF(v);
3393 }
3394 Py_BEGIN_ALLOW_THREADS
3395 result = FindNextFileW(hFindFile, &wFileData);
3396 Py_END_ALLOW_THREADS
3397 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3398 it got to the end of the directory. */
3399 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 Py_DECREF(list);
3401 list = win32_error_unicode("FindNextFileW", wnamebuf);
3402 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 }
3404 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003405
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 strcpy(namebuf, path.narrow);
3409 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 if (len > 0) {
3411 char ch = namebuf[len-1];
3412 if (ch != SEP && ch != ALTSEP && ch != ':')
3413 namebuf[len++] = '/';
3414 strcpy(namebuf + len, "*.*");
3415 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003419
Antoine Pitroub73caab2010-08-09 23:39:31 +00003420 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 if (hFindFile == INVALID_HANDLE_VALUE) {
3424 int error = GetLastError();
3425 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 goto exit;
3427 Py_DECREF(list);
3428 list = win32_error("FindFirstFile", namebuf);
3429 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 }
3431 do {
3432 /* Skip over . and .. */
3433 if (strcmp(FileData.cFileName, ".") != 0 &&
3434 strcmp(FileData.cFileName, "..") != 0) {
3435 v = PyBytes_FromString(FileData.cFileName);
3436 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 Py_DECREF(list);
3438 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 break;
3440 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_DECREF(list);
3444 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 break;
3446 }
3447 Py_DECREF(v);
3448 }
3449 Py_BEGIN_ALLOW_THREADS
3450 result = FindNextFile(hFindFile, &FileData);
3451 Py_END_ALLOW_THREADS
3452 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3453 it got to the end of the directory. */
3454 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_DECREF(list);
3456 list = win32_error("FindNextFile", namebuf);
3457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
3459 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461exit:
3462 if (hFindFile != INVALID_HANDLE_VALUE) {
3463 if (FindClose(hFindFile) == FALSE) {
3464 if (list != NULL) {
3465 Py_DECREF(list);
3466 list = win32_error_object("FindClose", path.object);
3467 }
3468 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 if (wnamebuf)
3471 free(wnamebuf);
3472 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003473
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003475
Tim Peters0bb44a42000-09-15 07:44:49 +00003476#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003478 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003480 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003482 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483 if (*pt == ALTSEP)
3484 *pt = SEP;
3485 if (namebuf[len-1] != SEP)
3486 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487 strcpy(namebuf + len, "*.*");
3488
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 if ((list = PyList_New(0)) == NULL) {
3490 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003491 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003493 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3494 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003495 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003496 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3497 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3498 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499
3500 if (rc != NO_ERROR) {
3501 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = posix_error_with_filename(path.narrow);
3504 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505 }
3506
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003507 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508 do {
3509 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003510 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003511 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512
3513 strcpy(namebuf, ep.achName);
3514
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003515 /* Leave Case of Name Alone -- In Native Form */
3516 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517
Christian Heimes72b710a2008-05-26 13:28:38 +00003518 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522 break;
3523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003528 break;
3529 }
3530 Py_DECREF(v);
3531 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3532 }
3533
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534exit:
3535 path_cleanup(&path);
3536
3537 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003541 /* v is never read, so it does not need to be initialized yet. */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 if (path.narrow && !PyArg_ParseTuple(args, "U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 arg_is_unicode = 0;
3544 PyErr_Clear();
3545 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546#ifdef HAVE_FDOPENDIR
3547 if (path.fd != -1) {
3548 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003549 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003551 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552
3553 if (fd == -1) {
3554 list = posix_error();
3555 goto exit;
3556 }
3557
3558 Py_BEGIN_ALLOW_THREADS
3559 dirp = fdopendir(fd);
3560 Py_END_ALLOW_THREADS
3561 }
3562 else
3563#endif
3564 {
3565 char *name = path.narrow ? path.narrow : ".";
3566 Py_BEGIN_ALLOW_THREADS
3567 dirp = opendir(name);
3568 Py_END_ALLOW_THREADS
3569 }
3570
3571 if (dirp == NULL) {
3572 list = path_error("listdir", &path);
3573 goto exit;
3574 }
3575 if ((list = PyList_New(0)) == NULL) {
3576 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
3578 for (;;) {
3579 errno = 0;
3580 Py_BEGIN_ALLOW_THREADS
3581 ep = readdir(dirp);
3582 Py_END_ALLOW_THREADS
3583 if (ep == NULL) {
3584 if (errno == 0) {
3585 break;
3586 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_DECREF(list);
3588 list = path_error("listdir", &path);
3589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
3591 }
3592 if (ep->d_name[0] == '.' &&
3593 (NAMLEN(ep) == 1 ||
3594 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3595 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00003596 if (arg_is_unicode)
3597 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3598 else
3599 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 break;
3603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 break;
3608 }
3609 Py_DECREF(v);
3610 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612exit:
3613 if (dirp != NULL) {
3614 Py_BEGIN_ALLOW_THREADS
3615 if (fd > -1)
3616 rewinddir(dirp);
3617 closedir(dirp);
3618 Py_END_ALLOW_THREADS
3619 }
3620
3621 path_cleanup(&path);
3622
3623 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003624
Tim Peters0bb44a42000-09-15 07:44:49 +00003625#endif /* which OS */
3626} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003627
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003628#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003629/* A helper function for abspath on win32 */
3630static PyObject *
3631posix__getfullpathname(PyObject *self, PyObject *args)
3632{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003633 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 char outbuf[MAX_PATH*2];
3635 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636 PyObject *po;
3637
3638 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3639 {
3640 wchar_t *wpath;
3641 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3642 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 DWORD result;
3644 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003645
3646 wpath = PyUnicode_AsUnicode(po);
3647 if (wpath == NULL)
3648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003650 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003652 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003653 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 if (!woutbufp)
3655 return PyErr_NoMemory();
3656 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3657 }
3658 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003659 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003661 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 if (woutbufp != woutbuf)
3663 free(woutbufp);
3664 return v;
3665 }
3666 /* Drop the argument parsing error as narrow strings
3667 are also valid. */
3668 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003669
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003670 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3671 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003673 if (win32_warn_bytes_api())
3674 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003675 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 outbuf, &temp)) {
3677 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 return NULL;
3679 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3681 return PyUnicode_Decode(outbuf, strlen(outbuf),
3682 Py_FileSystemDefaultEncoding, NULL);
3683 }
3684 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003685} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
Brian Curtind25aef52011-06-13 15:16:04 -05003687
Brian Curtinf5e76d02010-11-24 13:14:05 +00003688
Brian Curtind40e6f72010-07-08 21:39:08 +00003689/* A helper function for samepath on windows */
3690static PyObject *
3691posix__getfinalpathname(PyObject *self, PyObject *args)
3692{
3693 HANDLE hFile;
3694 int buf_size;
3695 wchar_t *target_path;
3696 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003697 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003698 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003699
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003701 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003702 path = PyUnicode_AsUnicode(po);
3703 if (path == NULL)
3704 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003705
3706 if(!check_GetFinalPathNameByHandle()) {
3707 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3708 NotImplementedError. */
3709 return PyErr_Format(PyExc_NotImplementedError,
3710 "GetFinalPathNameByHandle not available on this platform");
3711 }
3712
3713 hFile = CreateFileW(
3714 path,
3715 0, /* desired access */
3716 0, /* share mode */
3717 NULL, /* security attributes */
3718 OPEN_EXISTING,
3719 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3720 FILE_FLAG_BACKUP_SEMANTICS,
3721 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003722
Victor Stinnereb5657a2011-09-30 01:44:27 +02003723 if(hFile == INVALID_HANDLE_VALUE)
3724 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003725
3726 /* We have a good handle to the target, use it to determine the
3727 target path name. */
3728 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3729
3730 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003732
3733 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3734 if(!target_path)
3735 return PyErr_NoMemory();
3736
3737 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3738 buf_size, VOLUME_NAME_DOS);
3739 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
3742 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003746 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003747 free(target_path);
3748 return result;
3749
3750} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003751
3752static PyObject *
3753posix__getfileinformation(PyObject *self, PyObject *args)
3754{
3755 HANDLE hFile;
3756 BY_HANDLE_FILE_INFORMATION info;
3757 int fd;
3758
3759 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3760 return NULL;
3761
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003762 if (!_PyVerify_fd(fd))
3763 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003764
3765 hFile = (HANDLE)_get_osfhandle(fd);
3766 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003767 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003768
3769 if (!GetFileInformationByHandle(hFile, &info))
3770 return win32_error("_getfileinformation", NULL);
3771
3772 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3773 info.nFileIndexHigh,
3774 info.nFileIndexLow);
3775}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003776
Brian Curtin95d028f2011-06-09 09:10:38 -05003777PyDoc_STRVAR(posix__isdir__doc__,
3778"Return true if the pathname refers to an existing directory.");
3779
Brian Curtin9c669cc2011-06-08 18:17:18 -05003780static PyObject *
3781posix__isdir(PyObject *self, PyObject *args)
3782{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003783 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003784 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003785 DWORD attributes;
3786
3787 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003788 wchar_t *wpath = PyUnicode_AsUnicode(po);
3789 if (wpath == NULL)
3790 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003791
3792 attributes = GetFileAttributesW(wpath);
3793 if (attributes == INVALID_FILE_ATTRIBUTES)
3794 Py_RETURN_FALSE;
3795 goto check;
3796 }
3797 /* Drop the argument parsing error as narrow strings
3798 are also valid. */
3799 PyErr_Clear();
3800
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003801 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003802 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003803 if (win32_warn_bytes_api())
3804 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003805 attributes = GetFileAttributesA(path);
3806 if (attributes == INVALID_FILE_ATTRIBUTES)
3807 Py_RETURN_FALSE;
3808
3809check:
3810 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3811 Py_RETURN_TRUE;
3812 else
3813 Py_RETURN_FALSE;
3814}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003815#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003817PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003818"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3819Create a directory.\n\
3820\n\
3821If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3822 and path should be relative; path will then be relative to that directory.\n\
3823dir_fd may not be implemented on your platform.\n\
3824 If it is unavailable, using it will raise a NotImplementedError.\n\
3825\n\
3826The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003827
Barry Warsaw53699e91996-12-10 23:23:01 +00003828static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003830{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003833 int dir_fd = DEFAULT_DIR_FD;
3834 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3835 PyObject *return_value = NULL;
3836 int result;
3837
3838 memset(&path, 0, sizeof(path));
3839 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3840 path_converter, &path, &mode,
3841#ifdef HAVE_MKDIRAT
3842 dir_fd_converter, &dir_fd
3843#else
3844 dir_fd_unavailable, &dir_fd
3845#endif
3846 ))
3847 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003848
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003849#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851 if (path.wide)
3852 result = CreateDirectoryW(path.wide, NULL);
3853 else
3854 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003856
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 if (!result) {
3858 return_value = win32_error_object("mkdir", path.object);
3859 goto exit;
3860 }
3861#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863#if HAVE_MKDIRAT
3864 if (dir_fd != DEFAULT_DIR_FD)
3865 result = mkdirat(dir_fd, path.narrow, mode);
3866 else
3867#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003868#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003870#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003874 if (result < 0) {
3875 return_value = path_error("mkdir", &path);
3876 goto exit;
3877 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 return_value = Py_None;
3880 Py_INCREF(Py_None);
3881exit:
3882 path_cleanup(&path);
3883 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003884}
3885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003887/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3888#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003889#include <sys/resource.h>
3890#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003892
3893#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003894PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003895"nice(inc) -> new_priority\n\n\
3896Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Barry Warsaw53699e91996-12-10 23:23:01 +00003898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003899posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003900{
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003902
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3904 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003905
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 /* There are two flavours of 'nice': one that returns the new
3907 priority (as required by almost all standards out there) and the
3908 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3909 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003910
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 If we are of the nice family that returns the new priority, we
3912 need to clear errno before the call, and check if errno is filled
3913 before calling posix_error() on a returnvalue of -1, because the
3914 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003915
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 errno = 0;
3917 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003918#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 if (value == 0)
3920 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (value == -1 && errno != 0)
3923 /* either nice() or getpriority() returned an error */
3924 return posix_error();
3925 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003927#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003928
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003929
3930#ifdef HAVE_GETPRIORITY
3931PyDoc_STRVAR(posix_getpriority__doc__,
3932"getpriority(which, who) -> current_priority\n\n\
3933Get program scheduling priority.");
3934
3935static PyObject *
3936posix_getpriority(PyObject *self, PyObject *args)
3937{
3938 int which, who, retval;
3939
3940 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3941 return NULL;
3942 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944 if (errno != 0)
3945 return posix_error();
3946 return PyLong_FromLong((long)retval);
3947}
3948#endif /* HAVE_GETPRIORITY */
3949
3950
3951#ifdef HAVE_SETPRIORITY
3952PyDoc_STRVAR(posix_setpriority__doc__,
3953"setpriority(which, who, prio) -> None\n\n\
3954Set program scheduling priority.");
3955
3956static PyObject *
3957posix_setpriority(PyObject *self, PyObject *args)
3958{
3959 int which, who, prio, retval;
3960
3961 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3962 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003964 if (retval == -1)
3965 return posix_error();
3966 Py_RETURN_NONE;
3967}
3968#endif /* HAVE_SETPRIORITY */
3969
3970
Barry Warsaw53699e91996-12-10 23:23:01 +00003971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 char *function_name = is_replace ? "replace" : "rename";
3975 path_t src;
3976 path_t dst;
3977 int src_dir_fd = DEFAULT_DIR_FD;
3978 int dst_dir_fd = DEFAULT_DIR_FD;
3979 int dir_fd_specified;
3980 PyObject *return_value = NULL;
3981 char format[24];
3982 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3983
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003985 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003986 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003987#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003988 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990
3991 memset(&src, 0, sizeof(src));
3992 memset(&dst, 0, sizeof(dst));
3993 strcpy(format, "O&O&|$O&O&:");
3994 strcat(format, function_name);
3995 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3996 path_converter, &src,
3997 path_converter, &dst,
3998 dir_fd_converter, &src_dir_fd,
3999 dir_fd_converter, &dst_dir_fd))
4000 return NULL;
4001
4002 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4003 (dst_dir_fd != DEFAULT_DIR_FD);
4004#ifndef HAVE_RENAMEAT
4005 if (dir_fd_specified) {
4006 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4007 goto exit;
4008 }
4009#endif
4010
4011 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4012 PyErr_Format(PyExc_ValueError,
4013 "%s: src and dst must be the same type", function_name);
4014 goto exit;
4015 }
4016
4017#ifdef MS_WINDOWS
4018 Py_BEGIN_ALLOW_THREADS
4019 if (src.wide)
4020 result = MoveFileExW(src.wide, dst.wide, flags);
4021 else
4022 result = MoveFileExA(src.narrow, dst.narrow, flags);
4023 Py_END_ALLOW_THREADS
4024
4025 if (!result) {
4026 return_value = win32_error_object(function_name, dst.object);
4027 goto exit;
4028 }
4029
4030#else
4031 Py_BEGIN_ALLOW_THREADS
4032#ifdef HAVE_RENAMEAT
4033 if (dir_fd_specified)
4034 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4035 else
4036#endif
4037 result = rename(src.narrow, dst.narrow);
4038 Py_END_ALLOW_THREADS
4039
4040 if (result) {
4041 return_value = path_error(function_name, &dst);
4042 goto exit;
4043 }
4044#endif
4045
4046 Py_INCREF(Py_None);
4047 return_value = Py_None;
4048exit:
4049 path_cleanup(&src);
4050 path_cleanup(&dst);
4051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004052}
4053
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004054PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4056Rename a file or directory.\n\
4057\n\
4058If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4059 descriptor open to a directory, and the respective path string (src or dst)\n\
4060 should be relative; the path will then be relative to that directory.\n\
4061src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4062 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004063
4064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004068}
4069
4070PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4072Rename a file or directory, overwriting the destination.\n\
4073\n\
4074If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4075 descriptor open to a directory, and the respective path string (src or dst)\n\
4076 should be relative; the path will then be relative to that directory.\n\
4077src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4078 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004079
4080static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004082{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004084}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087"rmdir(path, *, dir_fd=None)\n\n\
4088Remove a directory.\n\
4089\n\
4090If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4091 and path should be relative; path will then be relative to that directory.\n\
4092dir_fd may not be implemented on your platform.\n\
4093 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Barry Warsaw53699e91996-12-10 23:23:01 +00004095static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004096posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004097{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004098 path_t path;
4099 int dir_fd = DEFAULT_DIR_FD;
4100 static char *keywords[] = {"path", "dir_fd", NULL};
4101 int result;
4102 PyObject *return_value = NULL;
4103
4104 memset(&path, 0, sizeof(path));
4105 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4106 path_converter, &path,
4107#ifdef HAVE_UNLINKAT
4108 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004109#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004111#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004112 ))
4113 return NULL;
4114
4115 Py_BEGIN_ALLOW_THREADS
4116#ifdef MS_WINDOWS
4117 if (path.wide)
4118 result = RemoveDirectoryW(path.wide);
4119 else
4120 result = RemoveDirectoryA(path.narrow);
4121 result = !result; /* Windows, success=1, UNIX, success=0 */
4122#else
4123#ifdef HAVE_UNLINKAT
4124 if (dir_fd != DEFAULT_DIR_FD)
4125 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4126 else
4127#endif
4128 result = rmdir(path.narrow);
4129#endif
4130 Py_END_ALLOW_THREADS
4131
4132 if (result) {
4133 return_value = path_error("rmdir", &path);
4134 goto exit;
4135 }
4136
4137 return_value = Py_None;
4138 Py_INCREF(Py_None);
4139
4140exit:
4141 path_cleanup(&path);
4142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143}
4144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004146#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004147PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004148"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004149Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Barry Warsaw53699e91996-12-10 23:23:01 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004153{
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 wchar_t *command;
4157 if (!PyArg_ParseTuple(args, "u:system", &command))
4158 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004159
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 Py_BEGIN_ALLOW_THREADS
4161 sts = _wsystem(command);
4162 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004163#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 PyObject *command_obj;
4165 char *command;
4166 if (!PyArg_ParseTuple(args, "O&:system",
4167 PyUnicode_FSConverter, &command_obj))
4168 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 command = PyBytes_AsString(command_obj);
4171 Py_BEGIN_ALLOW_THREADS
4172 sts = system(command);
4173 Py_END_ALLOW_THREADS
4174 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004175#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004178#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004182"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Barry Warsaw53699e91996-12-10 23:23:01 +00004185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004186posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004187{
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 int i;
4189 if (!PyArg_ParseTuple(args, "i:umask", &i))
4190 return NULL;
4191 i = (int)umask(i);
4192 if (i < 0)
4193 return posix_error();
4194 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004195}
4196
Brian Curtind40e6f72010-07-08 21:39:08 +00004197#ifdef MS_WINDOWS
4198
4199/* override the default DeleteFileW behavior so that directory
4200symlinks can be removed with this function, the same as with
4201Unix symlinks */
4202BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4203{
4204 WIN32_FILE_ATTRIBUTE_DATA info;
4205 WIN32_FIND_DATAW find_data;
4206 HANDLE find_data_handle;
4207 int is_directory = 0;
4208 int is_link = 0;
4209
4210 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4211 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004212
Brian Curtind40e6f72010-07-08 21:39:08 +00004213 /* Get WIN32_FIND_DATA structure for the path to determine if
4214 it is a symlink */
4215 if(is_directory &&
4216 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4217 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4218
4219 if(find_data_handle != INVALID_HANDLE_VALUE) {
4220 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4221 FindClose(find_data_handle);
4222 }
4223 }
4224 }
4225
4226 if (is_directory && is_link)
4227 return RemoveDirectoryW(lpFileName);
4228
4229 return DeleteFileW(lpFileName);
4230}
4231#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004232
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004235Remove a file (same as remove()).\n\
4236\n\
4237If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4238 and path should be relative; path will then be relative to that directory.\n\
4239dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004240 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004243"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244Remove a file (same as unlink()).\n\
4245\n\
4246If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4247 and path should be relative; path will then be relative to that directory.\n\
4248dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Barry Warsaw53699e91996-12-10 23:23:01 +00004251static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004252posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004253{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 path_t path;
4255 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257 int result;
4258 PyObject *return_value = NULL;
4259
4260 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262 path_converter, &path,
4263#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004265#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004266 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004267#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269 return NULL;
4270
4271 Py_BEGIN_ALLOW_THREADS
4272#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 if (path.wide)
4274 result = Py_DeleteFileW(path.wide);
4275 else
4276 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277 result = !result; /* Windows, success=1, UNIX, success=0 */
4278#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004279#ifdef HAVE_UNLINKAT
4280 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004281 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004282 else
4283#endif /* HAVE_UNLINKAT */
4284 result = unlink(path.narrow);
4285#endif
4286 Py_END_ALLOW_THREADS
4287
4288 if (result) {
4289 return_value = path_error("unlink", &path);
4290 goto exit;
4291 }
4292
4293 return_value = Py_None;
4294 Py_INCREF(Py_None);
4295
4296exit:
4297 path_cleanup(&path);
4298 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004299}
4300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004302PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004303"uname() -> uname_result\n\n\
4304Return an object identifying the current operating system.\n\
4305The object behaves like a named tuple with the following fields:\n\
4306 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Larry Hastings605a62d2012-06-24 04:33:36 -07004308static PyStructSequence_Field uname_result_fields[] = {
4309 {"sysname", "operating system name"},
4310 {"nodename", "name of machine on network (implementation-defined)"},
4311 {"release", "operating system release"},
4312 {"version", "operating system version"},
4313 {"machine", "hardware identifier"},
4314 {NULL}
4315};
4316
4317PyDoc_STRVAR(uname_result__doc__,
4318"uname_result: Result from os.uname().\n\n\
4319This object may be accessed either as a tuple of\n\
4320 (sysname, nodename, release, version, machine),\n\
4321or via the attributes sysname, nodename, release, version, and machine.\n\
4322\n\
4323See os.uname for more information.");
4324
4325static PyStructSequence_Desc uname_result_desc = {
4326 "uname_result", /* name */
4327 uname_result__doc__, /* doc */
4328 uname_result_fields,
4329 5
4330};
4331
4332static PyTypeObject UnameResultType;
4333
4334
4335#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004336static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004337posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004338{
Victor Stinner8c62be82010-05-06 00:08:46 +00004339 struct utsname u;
4340 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004341 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004342
Victor Stinner8c62be82010-05-06 00:08:46 +00004343 Py_BEGIN_ALLOW_THREADS
4344 res = uname(&u);
4345 Py_END_ALLOW_THREADS
4346 if (res < 0)
4347 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004348
4349 value = PyStructSequence_New(&UnameResultType);
4350 if (value == NULL)
4351 return NULL;
4352
4353#define SET(i, field) \
4354 { \
4355 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4356 if (!o) { \
4357 Py_DECREF(value); \
4358 return NULL; \
4359 } \
4360 PyStructSequence_SET_ITEM(value, i, o); \
4361 } \
4362
4363 SET(0, u.sysname);
4364 SET(1, u.nodename);
4365 SET(2, u.release);
4366 SET(3, u.version);
4367 SET(4, u.machine);
4368
4369#undef SET
4370
4371 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004372}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004373#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004374
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004375
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376PyDoc_STRVAR(posix_utime__doc__,
4377"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4378Set the access and modified time of path.\n\
4379\n\
4380path may always be specified as a string.\n\
4381On some platforms, path may also be specified as an open file descriptor.\n\
4382 If this functionality is unavailable, using it raises an exception.\n\
4383\n\
4384If times is not None, it must be a tuple (atime, mtime);\n\
4385 atime and mtime should be expressed as float seconds since the epoch.\n\
4386If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4387 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4388 since the epoch.\n\
4389If both times and ns are None, utime uses the current time.\n\
4390Specifying tuples for both times and ns is an error.\n\
4391\n\
4392If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4393 and path should be relative; path will then be relative to that directory.\n\
4394If follow_symlinks is False, and the last element of the path is a symbolic\n\
4395 link, utime will modify the symbolic link itself instead of the file the\n\
4396 link points to.\n\
4397It is an error to use dir_fd or follow_symlinks when specifying path\n\
4398 as an open file descriptor.\n\
4399dir_fd and follow_symlinks may not be available on your platform.\n\
4400 If they are unavailable, using them will raise a NotImplementedError.");
4401
4402typedef struct {
4403 int now;
4404 time_t atime_s;
4405 long atime_ns;
4406 time_t mtime_s;
4407 long mtime_ns;
4408} utime_t;
4409
4410/*
4411 * these macros assume that "utime" is a pointer to a utime_t
4412 * they also intentionally leak the declaration of a pointer named "time"
4413 */
4414#define UTIME_TO_TIMESPEC \
4415 struct timespec ts[2]; \
4416 struct timespec *time; \
4417 if (utime->now) \
4418 time = NULL; \
4419 else { \
4420 ts[0].tv_sec = utime->atime_s; \
4421 ts[0].tv_nsec = utime->atime_ns; \
4422 ts[1].tv_sec = utime->mtime_s; \
4423 ts[1].tv_nsec = utime->mtime_ns; \
4424 time = ts; \
4425 } \
4426
4427#define UTIME_TO_TIMEVAL \
4428 struct timeval tv[2]; \
4429 struct timeval *time; \
4430 if (utime->now) \
4431 time = NULL; \
4432 else { \
4433 tv[0].tv_sec = utime->atime_s; \
4434 tv[0].tv_usec = utime->atime_ns / 1000; \
4435 tv[1].tv_sec = utime->mtime_s; \
4436 tv[1].tv_usec = utime->mtime_ns / 1000; \
4437 time = tv; \
4438 } \
4439
4440#define UTIME_TO_UTIMBUF \
4441 struct utimbuf u[2]; \
4442 struct utimbuf *time; \
4443 if (utime->now) \
4444 time = NULL; \
4445 else { \
4446 u.actime = utime->atime_s; \
4447 u.modtime = utime->mtime_s; \
4448 time = u; \
4449 }
4450
4451#define UTIME_TO_TIME_T \
4452 time_t timet[2]; \
4453 struct timet time; \
4454 if (utime->now) \
4455 time = NULL; \
4456 else { \
4457 timet[0] = utime->atime_s; \
4458 timet[1] = utime->mtime_s; \
4459 time = &timet; \
4460 } \
4461
4462
4463#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4464
4465#if UTIME_HAVE_DIR_FD
4466
4467static int
4468utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4469{
4470#ifdef HAVE_UTIMENSAT
4471 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4472 UTIME_TO_TIMESPEC;
4473 return utimensat(dir_fd, path, time, flags);
4474#elif defined(HAVE_FUTIMESAT)
4475 UTIME_TO_TIMEVAL;
4476 /*
4477 * follow_symlinks will never be false here;
4478 * we only allow !follow_symlinks and dir_fd together
4479 * if we have utimensat()
4480 */
4481 assert(follow_symlinks);
4482 return futimesat(dir_fd, path, time);
4483#endif
4484}
4485
4486#endif
4487
4488#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4489
4490#if UTIME_HAVE_FD
4491
4492static int
4493utime_fd(utime_t *utime, int fd)
4494{
4495#ifdef HAVE_FUTIMENS
4496 UTIME_TO_TIMESPEC;
4497 return futimens(fd, time);
4498#else
4499 UTIME_TO_TIMEVAL;
4500 return futimes(fd, time);
4501#endif
4502}
4503
4504#endif
4505
4506
4507#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4508 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4509
4510#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4511
4512static int
4513utime_nofollow_symlinks(utime_t *utime, char *path)
4514{
4515#ifdef HAVE_UTIMENSAT
4516 UTIME_TO_TIMESPEC;
4517 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4518#else
4519 UTIME_TO_TIMEVAL;
4520 return lutimes(path, time);
4521#endif
4522}
4523
4524#endif
4525
4526#ifndef MS_WINDOWS
4527
4528static int
4529utime_default(utime_t *utime, char *path)
4530{
4531#ifdef HAVE_UTIMENSAT
4532 UTIME_TO_TIMESPEC;
4533 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4534#elif defined(HAVE_UTIMES)
4535 UTIME_TO_TIMEVAL;
4536 return utimes(path, time);
4537#elif defined(HAVE_UTIME_H)
4538 UTIME_TO_UTIMBUF;
4539 return utime(path, time);
4540#else
4541 UTIME_TO_TIME_T;
4542 return utime(path, time);
4543#endif
4544}
4545
4546#endif
4547
Larry Hastings76ad59b2012-05-03 00:30:07 -07004548static int
4549split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4550{
4551 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004552 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004553 divmod = PyNumber_Divmod(py_long, billion);
4554 if (!divmod)
4555 goto exit;
4556 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4557 if ((*s == -1) && PyErr_Occurred())
4558 goto exit;
4559 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004560 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004561 goto exit;
4562
4563 result = 1;
4564exit:
4565 Py_XDECREF(divmod);
4566 return result;
4567}
4568
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569static PyObject *
4570posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004573 PyObject *times = NULL;
4574 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 int dir_fd = DEFAULT_DIR_FD;
4576 int follow_symlinks = 1;
4577 char *keywords[] = {"path", "times", "ns", "dir_fd",
4578 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004579
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004581
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582#ifdef MS_WINDOWS
4583 HANDLE hFile;
4584 FILETIME atime, mtime;
4585#else
4586 int result;
4587#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 memset(&path, 0, sizeof(path));
4592#if UTIME_HAVE_FD
4593 path.allow_fd = 1;
4594#endif
4595 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4596 "O&|O$OO&p:utime", keywords,
4597 path_converter, &path,
4598 &times, &ns,
4599#if UTIME_HAVE_DIR_FD
4600 dir_fd_converter, &dir_fd,
4601#else
4602 dir_fd_unavailable, &dir_fd,
4603#endif
4604 &follow_symlinks
4605 ))
4606 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004607
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 if (times && (times != Py_None) && ns) {
4609 PyErr_SetString(PyExc_ValueError,
4610 "utime: you may specify either 'times'"
4611 " or 'ns' but not both");
4612 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004613 }
4614
4615 if (times && (times != Py_None)) {
4616 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617 PyErr_SetString(PyExc_TypeError,
4618 "utime: 'times' must be either"
4619 " a tuple of two ints or None");
4620 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004621 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004623 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004625 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 &utime.mtime_s, &utime.mtime_ns) == -1) {
4627 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004628 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004629 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004631 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 PyErr_SetString(PyExc_TypeError,
4633 "utime: 'ns' must be a tuple of two ints");
4634 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004635 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004637 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004639 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 &utime.mtime_s, &utime.mtime_ns)) {
4641 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004642 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643 }
4644 else {
4645 /* times and ns are both None/unspecified. use "now". */
4646 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647 }
4648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4650 if (follow_symlinks_specified("utime", follow_symlinks))
4651 goto exit;
4652#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004653
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4655 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4656 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4657 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659#if !defined(HAVE_UTIMENSAT)
4660 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
4661 PyErr_SetString(PyExc_RuntimeError,
4662 "utime: cannot use dir_fd and follow_symlinks "
4663 "together on this platform");
4664 goto exit;
4665 }
4666#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004668#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 Py_BEGIN_ALLOW_THREADS
4670 if (path.wide)
4671 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004672 NULL, OPEN_EXISTING,
4673 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 else
4675 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004676 NULL, OPEN_EXISTING,
4677 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678 Py_END_ALLOW_THREADS
4679 if (hFile == INVALID_HANDLE_VALUE) {
4680 win32_error_object("utime", path.object);
4681 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004682 }
4683
Larry Hastings9cf065c2012-06-22 16:30:09 -07004684 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004685 SYSTEMTIME now;
4686 GetSystemTime(&now);
4687 if (!SystemTimeToFileTime(&now, &mtime) ||
4688 !SystemTimeToFileTime(&now, &atime)) {
4689 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004691 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004692 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004693 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4695 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004696 }
4697 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4698 /* Avoid putting the file name into the error here,
4699 as that may confuse the user into believing that
4700 something is wrong with the file, when it also
4701 could be the time stamp that gives a problem. */
4702 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004705#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004707
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4709 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4710 result = utime_nofollow_symlinks(&utime, path.narrow);
4711 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004712#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713
4714#if UTIME_HAVE_DIR_FD
4715 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4716 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4717 else
4718#endif
4719
4720#if UTIME_HAVE_FD
4721 if (path.fd != -1)
4722 result = utime_fd(&utime, path.fd);
4723 else
4724#endif
4725
4726 result = utime_default(&utime, path.narrow);
4727
4728 Py_END_ALLOW_THREADS
4729
4730 if (result < 0) {
4731 /* see previous comment about not putting filename in error here */
4732 return_value = posix_error();
4733 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004736#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737
4738 Py_INCREF(Py_None);
4739 return_value = Py_None;
4740
4741exit:
4742 path_cleanup(&path);
4743#ifdef MS_WINDOWS
4744 if (hFile != INVALID_HANDLE_VALUE)
4745 CloseHandle(hFile);
4746#endif
4747 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004748}
4749
Guido van Rossum3b066191991-06-04 19:40:25 +00004750/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004752PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004753"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004754Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004755
Barry Warsaw53699e91996-12-10 23:23:01 +00004756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004757posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004758{
Victor Stinner8c62be82010-05-06 00:08:46 +00004759 int sts;
4760 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4761 return NULL;
4762 _exit(sts);
4763 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004764}
4765
Martin v. Löwis114619e2002-10-07 06:44:21 +00004766#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4767static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004768free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004769{
Victor Stinner8c62be82010-05-06 00:08:46 +00004770 Py_ssize_t i;
4771 for (i = 0; i < count; i++)
4772 PyMem_Free(array[i]);
4773 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004774}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004775
Antoine Pitrou69f71142009-05-24 21:25:49 +00004776static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004777int fsconvert_strdup(PyObject *o, char**out)
4778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 PyObject *bytes;
4780 Py_ssize_t size;
4781 if (!PyUnicode_FSConverter(o, &bytes))
4782 return 0;
4783 size = PyBytes_GET_SIZE(bytes);
4784 *out = PyMem_Malloc(size+1);
4785 if (!*out)
4786 return 0;
4787 memcpy(*out, PyBytes_AsString(bytes), size+1);
4788 Py_DECREF(bytes);
4789 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004790}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004791#endif
4792
Ross Lagerwall7807c352011-03-17 20:20:30 +02004793#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004794static char**
4795parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4796{
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 char **envlist;
4798 Py_ssize_t i, pos, envc;
4799 PyObject *keys=NULL, *vals=NULL;
4800 PyObject *key, *val, *key2, *val2;
4801 char *p, *k, *v;
4802 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004803
Victor Stinner8c62be82010-05-06 00:08:46 +00004804 i = PyMapping_Size(env);
4805 if (i < 0)
4806 return NULL;
4807 envlist = PyMem_NEW(char *, i + 1);
4808 if (envlist == NULL) {
4809 PyErr_NoMemory();
4810 return NULL;
4811 }
4812 envc = 0;
4813 keys = PyMapping_Keys(env);
4814 vals = PyMapping_Values(env);
4815 if (!keys || !vals)
4816 goto error;
4817 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4818 PyErr_Format(PyExc_TypeError,
4819 "env.keys() or env.values() is not a list");
4820 goto error;
4821 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004822
Victor Stinner8c62be82010-05-06 00:08:46 +00004823 for (pos = 0; pos < i; pos++) {
4824 key = PyList_GetItem(keys, pos);
4825 val = PyList_GetItem(vals, pos);
4826 if (!key || !val)
4827 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004828
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 if (PyUnicode_FSConverter(key, &key2) == 0)
4830 goto error;
4831 if (PyUnicode_FSConverter(val, &val2) == 0) {
4832 Py_DECREF(key2);
4833 goto error;
4834 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004835
4836#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004837 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4838 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004839#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 k = PyBytes_AsString(key2);
4841 v = PyBytes_AsString(val2);
4842 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004843
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 p = PyMem_NEW(char, len);
4845 if (p == NULL) {
4846 PyErr_NoMemory();
4847 Py_DECREF(key2);
4848 Py_DECREF(val2);
4849 goto error;
4850 }
4851 PyOS_snprintf(p, len, "%s=%s", k, v);
4852 envlist[envc++] = p;
4853 Py_DECREF(key2);
4854 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004855#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004857#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 }
4859 Py_DECREF(vals);
4860 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004861
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 envlist[envc] = 0;
4863 *envc_ptr = envc;
4864 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004865
4866error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 Py_XDECREF(keys);
4868 Py_XDECREF(vals);
4869 while (--envc >= 0)
4870 PyMem_DEL(envlist[envc]);
4871 PyMem_DEL(envlist);
4872 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004873}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004874
Ross Lagerwall7807c352011-03-17 20:20:30 +02004875static char**
4876parse_arglist(PyObject* argv, Py_ssize_t *argc)
4877{
4878 int i;
4879 char **argvlist = PyMem_NEW(char *, *argc+1);
4880 if (argvlist == NULL) {
4881 PyErr_NoMemory();
4882 return NULL;
4883 }
4884 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004885 PyObject* item = PySequence_ITEM(argv, i);
4886 if (item == NULL)
4887 goto fail;
4888 if (!fsconvert_strdup(item, &argvlist[i])) {
4889 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004890 goto fail;
4891 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004892 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004893 }
4894 argvlist[*argc] = NULL;
4895 return argvlist;
4896fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004897 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898 free_string_array(argvlist, *argc);
4899 return NULL;
4900}
4901#endif
4902
4903#ifdef HAVE_EXECV
4904PyDoc_STRVAR(posix_execv__doc__,
4905"execv(path, args)\n\n\
4906Execute an executable path with arguments, replacing current process.\n\
4907\n\
4908 path: path of executable file\n\
4909 args: tuple or list of strings");
4910
4911static PyObject *
4912posix_execv(PyObject *self, PyObject *args)
4913{
4914 PyObject *opath;
4915 char *path;
4916 PyObject *argv;
4917 char **argvlist;
4918 Py_ssize_t argc;
4919
4920 /* execv has two arguments: (path, argv), where
4921 argv is a list or tuple of strings. */
4922
4923 if (!PyArg_ParseTuple(args, "O&O:execv",
4924 PyUnicode_FSConverter,
4925 &opath, &argv))
4926 return NULL;
4927 path = PyBytes_AsString(opath);
4928 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4929 PyErr_SetString(PyExc_TypeError,
4930 "execv() arg 2 must be a tuple or list");
4931 Py_DECREF(opath);
4932 return NULL;
4933 }
4934 argc = PySequence_Size(argv);
4935 if (argc < 1) {
4936 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4937 Py_DECREF(opath);
4938 return NULL;
4939 }
4940
4941 argvlist = parse_arglist(argv, &argc);
4942 if (argvlist == NULL) {
4943 Py_DECREF(opath);
4944 return NULL;
4945 }
4946
4947 execv(path, argvlist);
4948
4949 /* If we get here it's definitely an error */
4950
4951 free_string_array(argvlist, argc);
4952 Py_DECREF(opath);
4953 return posix_error();
4954}
4955
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004957"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004958Execute a path with arguments and environment, replacing current process.\n\
4959\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 path: path of executable file\n\
4961 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004962 env: dictionary of strings mapping to strings\n\
4963\n\
4964On some platforms, you may specify an open file descriptor for path;\n\
4965 execve will execute the program the file descriptor is open to.\n\
4966 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Barry Warsaw53699e91996-12-10 23:23:01 +00004968static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004969posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004970{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004973 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004976 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 /* execve has three arguments: (path, argv, env), where
4979 argv is a list or tuple of strings and env is a dictionary
4980 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004981
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 memset(&path, 0, sizeof(path));
4983#ifdef HAVE_FEXECVE
4984 path.allow_fd = 1;
4985#endif
4986 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4987 path_converter, &path,
4988 &argv, &env
4989 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004991
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 "execve: argv must be a tuple or list");
4995 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 if (!PyMapping_Check(env)) {
4999 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000 "execve: environment must be a mapping object");
5001 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005003
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005007 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 envlist = parse_envlist(env, &envc);
5010 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011 goto fail;
5012
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013#ifdef HAVE_FEXECVE
5014 if (path.fd > -1)
5015 fexecve(path.fd, argvlist, envlist);
5016 else
5017#endif
5018 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019
5020 /* If we get here it's definitely an error */
5021
Larry Hastings9cf065c2012-06-22 16:30:09 -07005022 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023
5024 while (--envc >= 0)
5025 PyMem_DEL(envlist[envc]);
5026 PyMem_DEL(envlist);
5027 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005028 if (argvlist)
5029 free_string_array(argvlist, argc);
5030 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031 return NULL;
5032}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005033#endif /* HAVE_EXECV */
5034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Guido van Rossuma1065681999-01-25 23:20:23 +00005036#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005038"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005039Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005040\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 mode: mode of process creation\n\
5042 path: path of executable file\n\
5043 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005044
5045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005046posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005047{
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 PyObject *opath;
5049 char *path;
5050 PyObject *argv;
5051 char **argvlist;
5052 int mode, i;
5053 Py_ssize_t argc;
5054 Py_intptr_t spawnval;
5055 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005056
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 /* spawnv has three arguments: (mode, path, argv), where
5058 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005059
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5061 PyUnicode_FSConverter,
5062 &opath, &argv))
5063 return NULL;
5064 path = PyBytes_AsString(opath);
5065 if (PyList_Check(argv)) {
5066 argc = PyList_Size(argv);
5067 getitem = PyList_GetItem;
5068 }
5069 else if (PyTuple_Check(argv)) {
5070 argc = PyTuple_Size(argv);
5071 getitem = PyTuple_GetItem;
5072 }
5073 else {
5074 PyErr_SetString(PyExc_TypeError,
5075 "spawnv() arg 2 must be a tuple or list");
5076 Py_DECREF(opath);
5077 return NULL;
5078 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005079
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 argvlist = PyMem_NEW(char *, argc+1);
5081 if (argvlist == NULL) {
5082 Py_DECREF(opath);
5083 return PyErr_NoMemory();
5084 }
5085 for (i = 0; i < argc; i++) {
5086 if (!fsconvert_strdup((*getitem)(argv, i),
5087 &argvlist[i])) {
5088 free_string_array(argvlist, i);
5089 PyErr_SetString(
5090 PyExc_TypeError,
5091 "spawnv() arg 2 must contain only strings");
5092 Py_DECREF(opath);
5093 return NULL;
5094 }
5095 }
5096 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005097
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005098#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 Py_BEGIN_ALLOW_THREADS
5100 spawnval = spawnv(mode, path, argvlist);
5101 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005102#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 if (mode == _OLD_P_OVERLAY)
5104 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005105
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 Py_BEGIN_ALLOW_THREADS
5107 spawnval = _spawnv(mode, path, argvlist);
5108 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005109#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 free_string_array(argvlist, argc);
5112 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 if (spawnval == -1)
5115 return posix_error();
5116 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005117#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005121#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005122}
5123
5124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005126"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005127Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005128\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 mode: mode of process creation\n\
5130 path: path of executable file\n\
5131 args: tuple or list of arguments\n\
5132 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005133
5134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005136{
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 PyObject *opath;
5138 char *path;
5139 PyObject *argv, *env;
5140 char **argvlist;
5141 char **envlist;
5142 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005143 int mode;
5144 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 Py_intptr_t spawnval;
5146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5147 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 /* spawnve has four arguments: (mode, path, argv, env), where
5150 argv is a list or tuple of strings and env is a dictionary
5151 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5154 PyUnicode_FSConverter,
5155 &opath, &argv, &env))
5156 return NULL;
5157 path = PyBytes_AsString(opath);
5158 if (PyList_Check(argv)) {
5159 argc = PyList_Size(argv);
5160 getitem = PyList_GetItem;
5161 }
5162 else if (PyTuple_Check(argv)) {
5163 argc = PyTuple_Size(argv);
5164 getitem = PyTuple_GetItem;
5165 }
5166 else {
5167 PyErr_SetString(PyExc_TypeError,
5168 "spawnve() arg 2 must be a tuple or list");
5169 goto fail_0;
5170 }
5171 if (!PyMapping_Check(env)) {
5172 PyErr_SetString(PyExc_TypeError,
5173 "spawnve() arg 3 must be a mapping object");
5174 goto fail_0;
5175 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 argvlist = PyMem_NEW(char *, argc+1);
5178 if (argvlist == NULL) {
5179 PyErr_NoMemory();
5180 goto fail_0;
5181 }
5182 for (i = 0; i < argc; i++) {
5183 if (!fsconvert_strdup((*getitem)(argv, i),
5184 &argvlist[i]))
5185 {
5186 lastarg = i;
5187 goto fail_1;
5188 }
5189 }
5190 lastarg = argc;
5191 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005192
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 envlist = parse_envlist(env, &envc);
5194 if (envlist == NULL)
5195 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005196
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005197#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 Py_BEGIN_ALLOW_THREADS
5199 spawnval = spawnve(mode, path, argvlist, envlist);
5200 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005201#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 if (mode == _OLD_P_OVERLAY)
5203 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 Py_BEGIN_ALLOW_THREADS
5206 spawnval = _spawnve(mode, path, argvlist, envlist);
5207 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005208#endif
Tim Peters25059d32001-12-07 20:35:43 +00005209
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 if (spawnval == -1)
5211 (void) posix_error();
5212 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005213#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005215#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005217#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 while (--envc >= 0)
5220 PyMem_DEL(envlist[envc]);
5221 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005222 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005224 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 Py_DECREF(opath);
5226 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005227}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005228
5229/* OS/2 supports spawnvp & spawnvpe natively */
5230#if defined(PYOS_OS2)
5231PyDoc_STRVAR(posix_spawnvp__doc__,
5232"spawnvp(mode, file, args)\n\n\
5233Execute the program 'file' in a new process, using the environment\n\
5234search path to find the file.\n\
5235\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 mode: mode of process creation\n\
5237 file: executable file name\n\
5238 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005239
5240static PyObject *
5241posix_spawnvp(PyObject *self, PyObject *args)
5242{
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 PyObject *opath;
5244 char *path;
5245 PyObject *argv;
5246 char **argvlist;
5247 int mode, i, argc;
5248 Py_intptr_t spawnval;
5249 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 /* spawnvp has three arguments: (mode, path, argv), where
5252 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005253
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5255 PyUnicode_FSConverter,
5256 &opath, &argv))
5257 return NULL;
5258 path = PyBytes_AsString(opath);
5259 if (PyList_Check(argv)) {
5260 argc = PyList_Size(argv);
5261 getitem = PyList_GetItem;
5262 }
5263 else if (PyTuple_Check(argv)) {
5264 argc = PyTuple_Size(argv);
5265 getitem = PyTuple_GetItem;
5266 }
5267 else {
5268 PyErr_SetString(PyExc_TypeError,
5269 "spawnvp() arg 2 must be a tuple or list");
5270 Py_DECREF(opath);
5271 return NULL;
5272 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 argvlist = PyMem_NEW(char *, argc+1);
5275 if (argvlist == NULL) {
5276 Py_DECREF(opath);
5277 return PyErr_NoMemory();
5278 }
5279 for (i = 0; i < argc; i++) {
5280 if (!fsconvert_strdup((*getitem)(argv, i),
5281 &argvlist[i])) {
5282 free_string_array(argvlist, i);
5283 PyErr_SetString(
5284 PyExc_TypeError,
5285 "spawnvp() arg 2 must contain only strings");
5286 Py_DECREF(opath);
5287 return NULL;
5288 }
5289 }
5290 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005293#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005297#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005299
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 free_string_array(argvlist, argc);
5301 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005302
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 if (spawnval == -1)
5304 return posix_error();
5305 else
5306 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005307}
5308
5309
5310PyDoc_STRVAR(posix_spawnvpe__doc__,
5311"spawnvpe(mode, file, args, env)\n\n\
5312Execute the program 'file' in a new process, using the environment\n\
5313search path to find the file.\n\
5314\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 mode: mode of process creation\n\
5316 file: executable file name\n\
5317 args: tuple or list of arguments\n\
5318 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005319
5320static PyObject *
5321posix_spawnvpe(PyObject *self, PyObject *args)
5322{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005323 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 char *path;
5325 PyObject *argv, *env;
5326 char **argvlist;
5327 char **envlist;
5328 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005329 int mode;
5330 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 Py_intptr_t spawnval;
5332 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5333 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005334
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 /* spawnvpe has four arguments: (mode, path, argv, env), where
5336 argv is a list or tuple of strings and env is a dictionary
5337 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005338
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5340 PyUnicode_FSConverter,
5341 &opath, &argv, &env))
5342 return NULL;
5343 path = PyBytes_AsString(opath);
5344 if (PyList_Check(argv)) {
5345 argc = PyList_Size(argv);
5346 getitem = PyList_GetItem;
5347 }
5348 else if (PyTuple_Check(argv)) {
5349 argc = PyTuple_Size(argv);
5350 getitem = PyTuple_GetItem;
5351 }
5352 else {
5353 PyErr_SetString(PyExc_TypeError,
5354 "spawnvpe() arg 2 must be a tuple or list");
5355 goto fail_0;
5356 }
5357 if (!PyMapping_Check(env)) {
5358 PyErr_SetString(PyExc_TypeError,
5359 "spawnvpe() arg 3 must be a mapping object");
5360 goto fail_0;
5361 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005362
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 argvlist = PyMem_NEW(char *, argc+1);
5364 if (argvlist == NULL) {
5365 PyErr_NoMemory();
5366 goto fail_0;
5367 }
5368 for (i = 0; i < argc; i++) {
5369 if (!fsconvert_strdup((*getitem)(argv, i),
5370 &argvlist[i]))
5371 {
5372 lastarg = i;
5373 goto fail_1;
5374 }
5375 }
5376 lastarg = argc;
5377 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005378
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 envlist = parse_envlist(env, &envc);
5380 if (envlist == NULL)
5381 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005382
Victor Stinner8c62be82010-05-06 00:08:46 +00005383 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005384#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005386#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005389 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005390
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 if (spawnval == -1)
5392 (void) posix_error();
5393 else
5394 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005395
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 while (--envc >= 0)
5397 PyMem_DEL(envlist[envc]);
5398 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005399 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005401 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 Py_DECREF(opath);
5403 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005404}
5405#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005406#endif /* HAVE_SPAWNV */
5407
5408
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005409#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005411"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005412Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5413\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005415
5416static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005417posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005418{
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 pid_t pid;
5420 int result = 0;
5421 _PyImport_AcquireLock();
5422 pid = fork1();
5423 if (pid == 0) {
5424 /* child: this clobbers and resets the import lock. */
5425 PyOS_AfterFork();
5426 } else {
5427 /* parent: release the import lock. */
5428 result = _PyImport_ReleaseLock();
5429 }
5430 if (pid == -1)
5431 return posix_error();
5432 if (result < 0) {
5433 /* Don't clobber the OSError if the fork failed. */
5434 PyErr_SetString(PyExc_RuntimeError,
5435 "not holding the import lock");
5436 return NULL;
5437 }
5438 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005439}
5440#endif
5441
5442
Guido van Rossumad0ee831995-03-01 10:34:45 +00005443#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005445"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005446Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005448
Barry Warsaw53699e91996-12-10 23:23:01 +00005449static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005450posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005451{
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 pid_t pid;
5453 int result = 0;
5454 _PyImport_AcquireLock();
5455 pid = fork();
5456 if (pid == 0) {
5457 /* child: this clobbers and resets the import lock. */
5458 PyOS_AfterFork();
5459 } else {
5460 /* parent: release the import lock. */
5461 result = _PyImport_ReleaseLock();
5462 }
5463 if (pid == -1)
5464 return posix_error();
5465 if (result < 0) {
5466 /* Don't clobber the OSError if the fork failed. */
5467 PyErr_SetString(PyExc_RuntimeError,
5468 "not holding the import lock");
5469 return NULL;
5470 }
5471 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005472}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005473#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005474
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475#ifdef HAVE_SCHED_H
5476
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005477#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5478
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005479PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5480"sched_get_priority_max(policy)\n\n\
5481Get the maximum scheduling priority for *policy*.");
5482
5483static PyObject *
5484posix_sched_get_priority_max(PyObject *self, PyObject *args)
5485{
5486 int policy, max;
5487
5488 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5489 return NULL;
5490 max = sched_get_priority_max(policy);
5491 if (max < 0)
5492 return posix_error();
5493 return PyLong_FromLong(max);
5494}
5495
5496PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5497"sched_get_priority_min(policy)\n\n\
5498Get the minimum scheduling priority for *policy*.");
5499
5500static PyObject *
5501posix_sched_get_priority_min(PyObject *self, PyObject *args)
5502{
5503 int policy, min;
5504
5505 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5506 return NULL;
5507 min = sched_get_priority_min(policy);
5508 if (min < 0)
5509 return posix_error();
5510 return PyLong_FromLong(min);
5511}
5512
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005513#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5514
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005515#ifdef HAVE_SCHED_SETSCHEDULER
5516
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005517PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5518"sched_getscheduler(pid)\n\n\
5519Get the scheduling policy for the process with a PID of *pid*.\n\
5520Passing a PID of 0 returns the scheduling policy for the calling process.");
5521
5522static PyObject *
5523posix_sched_getscheduler(PyObject *self, PyObject *args)
5524{
5525 pid_t pid;
5526 int policy;
5527
5528 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5529 return NULL;
5530 policy = sched_getscheduler(pid);
5531 if (policy < 0)
5532 return posix_error();
5533 return PyLong_FromLong(policy);
5534}
5535
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005536#endif
5537
5538#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5539
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540static PyObject *
5541sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5542{
5543 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005544 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005545
5546 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5547 return NULL;
5548 res = PyStructSequence_New(type);
5549 if (!res)
5550 return NULL;
5551 Py_INCREF(priority);
5552 PyStructSequence_SET_ITEM(res, 0, priority);
5553 return res;
5554}
5555
5556PyDoc_STRVAR(sched_param__doc__,
5557"sched_param(sched_priority): A scheduling parameter.\n\n\
5558Current has only one field: sched_priority");
5559
5560static PyStructSequence_Field sched_param_fields[] = {
5561 {"sched_priority", "the scheduling priority"},
5562 {0}
5563};
5564
5565static PyStructSequence_Desc sched_param_desc = {
5566 "sched_param", /* name */
5567 sched_param__doc__, /* doc */
5568 sched_param_fields,
5569 1
5570};
5571
5572static int
5573convert_sched_param(PyObject *param, struct sched_param *res)
5574{
5575 long priority;
5576
5577 if (Py_TYPE(param) != &SchedParamType) {
5578 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5579 return 0;
5580 }
5581 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5582 if (priority == -1 && PyErr_Occurred())
5583 return 0;
5584 if (priority > INT_MAX || priority < INT_MIN) {
5585 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5586 return 0;
5587 }
5588 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5589 return 1;
5590}
5591
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005592#endif
5593
5594#ifdef HAVE_SCHED_SETSCHEDULER
5595
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5597"sched_setscheduler(pid, policy, param)\n\n\
5598Set the scheduling policy, *policy*, for *pid*.\n\
5599If *pid* is 0, the calling process is changed.\n\
5600*param* is an instance of sched_param.");
5601
5602static PyObject *
5603posix_sched_setscheduler(PyObject *self, PyObject *args)
5604{
5605 pid_t pid;
5606 int policy;
5607 struct sched_param param;
5608
5609 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5610 &pid, &policy, &convert_sched_param, &param))
5611 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005612
5613 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005614 ** sched_setscheduler() returns 0 in Linux, but the previous
5615 ** scheduling policy under Solaris/Illumos, and others.
5616 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005617 */
5618 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005619 return posix_error();
5620 Py_RETURN_NONE;
5621}
5622
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005623#endif
5624
5625#ifdef HAVE_SCHED_SETPARAM
5626
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005627PyDoc_STRVAR(posix_sched_getparam__doc__,
5628"sched_getparam(pid) -> sched_param\n\n\
5629Returns scheduling parameters for the process with *pid* as an instance of the\n\
5630sched_param class. A PID of 0 means the calling process.");
5631
5632static PyObject *
5633posix_sched_getparam(PyObject *self, PyObject *args)
5634{
5635 pid_t pid;
5636 struct sched_param param;
5637 PyObject *res, *priority;
5638
5639 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5640 return NULL;
5641 if (sched_getparam(pid, &param))
5642 return posix_error();
5643 res = PyStructSequence_New(&SchedParamType);
5644 if (!res)
5645 return NULL;
5646 priority = PyLong_FromLong(param.sched_priority);
5647 if (!priority) {
5648 Py_DECREF(res);
5649 return NULL;
5650 }
5651 PyStructSequence_SET_ITEM(res, 0, priority);
5652 return res;
5653}
5654
5655PyDoc_STRVAR(posix_sched_setparam__doc__,
5656"sched_setparam(pid, param)\n\n\
5657Set scheduling parameters for a process with PID *pid*.\n\
5658A PID of 0 means the calling process.");
5659
5660static PyObject *
5661posix_sched_setparam(PyObject *self, PyObject *args)
5662{
5663 pid_t pid;
5664 struct sched_param param;
5665
5666 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5667 &pid, &convert_sched_param, &param))
5668 return NULL;
5669 if (sched_setparam(pid, &param))
5670 return posix_error();
5671 Py_RETURN_NONE;
5672}
5673
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005674#endif
5675
5676#ifdef HAVE_SCHED_RR_GET_INTERVAL
5677
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005678PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5679"sched_rr_get_interval(pid) -> float\n\n\
5680Return the round-robin quantum for the process with PID *pid* in seconds.");
5681
5682static PyObject *
5683posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5684{
5685 pid_t pid;
5686 struct timespec interval;
5687
5688 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5689 return NULL;
5690 if (sched_rr_get_interval(pid, &interval))
5691 return posix_error();
5692 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5693}
5694
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005695#endif
5696
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005697PyDoc_STRVAR(posix_sched_yield__doc__,
5698"sched_yield()\n\n\
5699Voluntarily relinquish the CPU.");
5700
5701static PyObject *
5702posix_sched_yield(PyObject *self, PyObject *noargs)
5703{
5704 if (sched_yield())
5705 return posix_error();
5706 Py_RETURN_NONE;
5707}
5708
Benjamin Peterson2740af82011-08-02 17:41:34 -05005709#ifdef HAVE_SCHED_SETAFFINITY
5710
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005711typedef struct {
5712 PyObject_HEAD;
5713 Py_ssize_t size;
5714 int ncpus;
5715 cpu_set_t *set;
5716} Py_cpu_set;
5717
5718static PyTypeObject cpu_set_type;
5719
5720static void
5721cpu_set_dealloc(Py_cpu_set *set)
5722{
5723 assert(set->set);
5724 CPU_FREE(set->set);
5725 Py_TYPE(set)->tp_free(set);
5726}
5727
5728static Py_cpu_set *
5729make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5730{
5731 Py_cpu_set *set;
5732
5733 if (size < 0) {
5734 PyErr_SetString(PyExc_ValueError, "negative size");
5735 return NULL;
5736 }
5737 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5738 if (!set)
5739 return NULL;
5740 set->ncpus = size;
5741 set->size = CPU_ALLOC_SIZE(size);
5742 set->set = CPU_ALLOC(size);
5743 if (!set->set) {
5744 type->tp_free(set);
5745 PyErr_NoMemory();
5746 return NULL;
5747 }
5748 CPU_ZERO_S(set->size, set->set);
5749 return set;
5750}
5751
5752static PyObject *
5753cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5754{
5755 int size;
5756
5757 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5758 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5759 return NULL;
5760 return (PyObject *)make_new_cpu_set(type, size);
5761}
5762
5763static PyObject *
5764cpu_set_repr(Py_cpu_set *set)
5765{
5766 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005767}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005768
5769static Py_ssize_t
5770cpu_set_len(Py_cpu_set *set)
5771{
5772 return set->ncpus;
5773}
5774
5775static int
5776_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5777{
5778 int cpu;
5779 if (!PyArg_ParseTuple(args, requester, &cpu))
5780 return -1;
5781 if (cpu < 0) {
5782 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5783 return -1;
5784 }
5785 if (cpu >= set->ncpus) {
5786 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5787 return -1;
5788 }
5789 return cpu;
5790}
5791
5792PyDoc_STRVAR(cpu_set_set_doc,
5793"cpu_set.set(i)\n\n\
5794Add CPU *i* to the set.");
5795
5796static PyObject *
5797cpu_set_set(Py_cpu_set *set, PyObject *args)
5798{
5799 int cpu = _get_cpu(set, "i|set", args);
5800 if (cpu == -1)
5801 return NULL;
5802 CPU_SET_S(cpu, set->size, set->set);
5803 Py_RETURN_NONE;
5804}
5805
5806PyDoc_STRVAR(cpu_set_count_doc,
5807"cpu_set.count() -> int\n\n\
5808Return the number of CPUs active in the set.");
5809
5810static PyObject *
5811cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5812{
5813 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5814}
5815
5816PyDoc_STRVAR(cpu_set_clear_doc,
5817"cpu_set.clear(i)\n\n\
5818Remove CPU *i* from the set.");
5819
5820static PyObject *
5821cpu_set_clear(Py_cpu_set *set, PyObject *args)
5822{
5823 int cpu = _get_cpu(set, "i|clear", args);
5824 if (cpu == -1)
5825 return NULL;
5826 CPU_CLR_S(cpu, set->size, set->set);
5827 Py_RETURN_NONE;
5828}
5829
5830PyDoc_STRVAR(cpu_set_isset_doc,
5831"cpu_set.isset(i) -> bool\n\n\
5832Test if CPU *i* is in the set.");
5833
5834static PyObject *
5835cpu_set_isset(Py_cpu_set *set, PyObject *args)
5836{
5837 int cpu = _get_cpu(set, "i|isset", args);
5838 if (cpu == -1)
5839 return NULL;
5840 if (CPU_ISSET_S(cpu, set->size, set->set))
5841 Py_RETURN_TRUE;
5842 Py_RETURN_FALSE;
5843}
5844
5845PyDoc_STRVAR(cpu_set_zero_doc,
5846"cpu_set.zero()\n\n\
5847Clear the cpu_set.");
5848
5849static PyObject *
5850cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5851{
5852 CPU_ZERO_S(set->size, set->set);
5853 Py_RETURN_NONE;
5854}
5855
5856static PyObject *
5857cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5858{
5859 int eq;
5860
Brian Curtindfc80e32011-08-10 20:28:54 -05005861 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5862 Py_RETURN_NOTIMPLEMENTED;
5863
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005864 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5865 if ((op == Py_EQ) ? eq : !eq)
5866 Py_RETURN_TRUE;
5867 else
5868 Py_RETURN_FALSE;
5869}
5870
5871#define CPU_SET_BINOP(name, op) \
5872 static PyObject * \
5873 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5874 if (res) { \
5875 Py_INCREF(res); \
5876 } \
5877 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005878 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879 if (!res) \
5880 return NULL; \
5881 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005882 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005883 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005884 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005885 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005886 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005887 op(res->size, res->set, left->set, right->set); \
5888 return (PyObject *)res; \
5889 } \
5890 static PyObject * \
5891 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5892 return do_cpu_set_##name(left, right, NULL); \
5893 } \
5894 static PyObject * \
5895 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5896 return do_cpu_set_##name(left, right, left); \
5897 } \
5898
5899CPU_SET_BINOP(and, CPU_AND_S)
5900CPU_SET_BINOP(or, CPU_OR_S)
5901CPU_SET_BINOP(xor, CPU_XOR_S)
5902#undef CPU_SET_BINOP
5903
5904PyDoc_STRVAR(cpu_set_doc,
5905"cpu_set(size)\n\n\
5906Create an empty mask of CPUs.");
5907
5908static PyNumberMethods cpu_set_as_number = {
5909 0, /*nb_add*/
5910 0, /*nb_subtract*/
5911 0, /*nb_multiply*/
5912 0, /*nb_remainder*/
5913 0, /*nb_divmod*/
5914 0, /*nb_power*/
5915 0, /*nb_negative*/
5916 0, /*nb_positive*/
5917 0, /*nb_absolute*/
5918 0, /*nb_bool*/
5919 0, /*nb_invert*/
5920 0, /*nb_lshift*/
5921 0, /*nb_rshift*/
5922 (binaryfunc)cpu_set_and, /*nb_and*/
5923 (binaryfunc)cpu_set_xor, /*nb_xor*/
5924 (binaryfunc)cpu_set_or, /*nb_or*/
5925 0, /*nb_int*/
5926 0, /*nb_reserved*/
5927 0, /*nb_float*/
5928 0, /*nb_inplace_add*/
5929 0, /*nb_inplace_subtract*/
5930 0, /*nb_inplace_multiply*/
5931 0, /*nb_inplace_remainder*/
5932 0, /*nb_inplace_power*/
5933 0, /*nb_inplace_lshift*/
5934 0, /*nb_inplace_rshift*/
5935 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5936 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5937 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5938};
5939
5940static PySequenceMethods cpu_set_as_sequence = {
5941 (lenfunc)cpu_set_len, /* sq_length */
5942};
5943
5944static PyMethodDef cpu_set_methods[] = {
5945 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5946 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5947 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5948 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5949 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5950 {NULL, NULL} /* sentinel */
5951};
5952
5953static PyTypeObject cpu_set_type = {
5954 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5955 "posix.cpu_set", /* tp_name */
5956 sizeof(Py_cpu_set), /* tp_basicsize */
5957 0, /* tp_itemsize */
5958 /* methods */
5959 (destructor)cpu_set_dealloc, /* tp_dealloc */
5960 0, /* tp_print */
5961 0, /* tp_getattr */
5962 0, /* tp_setattr */
5963 0, /* tp_reserved */
5964 (reprfunc)cpu_set_repr, /* tp_repr */
5965 &cpu_set_as_number, /* tp_as_number */
5966 &cpu_set_as_sequence, /* tp_as_sequence */
5967 0, /* tp_as_mapping */
5968 PyObject_HashNotImplemented, /* tp_hash */
5969 0, /* tp_call */
5970 0, /* tp_str */
5971 PyObject_GenericGetAttr, /* tp_getattro */
5972 0, /* tp_setattro */
5973 0, /* tp_as_buffer */
5974 Py_TPFLAGS_DEFAULT, /* tp_flags */
5975 cpu_set_doc, /* tp_doc */
5976 0, /* tp_traverse */
5977 0, /* tp_clear */
5978 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5979 0, /* tp_weaklistoffset */
5980 0, /* tp_iter */
5981 0, /* tp_iternext */
5982 cpu_set_methods, /* tp_methods */
5983 0, /* tp_members */
5984 0, /* tp_getset */
5985 0, /* tp_base */
5986 0, /* tp_dict */
5987 0, /* tp_descr_get */
5988 0, /* tp_descr_set */
5989 0, /* tp_dictoffset */
5990 0, /* tp_init */
5991 PyType_GenericAlloc, /* tp_alloc */
5992 cpu_set_new, /* tp_new */
5993 PyObject_Del, /* tp_free */
5994};
5995
5996PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5997"sched_setaffinity(pid, cpu_set)\n\n\
5998Set the affinity of the process with PID *pid* to *cpu_set*.");
5999
6000static PyObject *
6001posix_sched_setaffinity(PyObject *self, PyObject *args)
6002{
6003 pid_t pid;
6004 Py_cpu_set *cpu_set;
6005
Benjamin Petersona17a5d62011-08-09 16:49:13 -05006006 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006007 &pid, &cpu_set_type, &cpu_set))
6008 return NULL;
6009 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
6010 return posix_error();
6011 Py_RETURN_NONE;
6012}
6013
6014PyDoc_STRVAR(posix_sched_getaffinity__doc__,
6015"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
6016Return the affinity of the process with PID *pid*.\n\
6017The returned cpu_set will be of size *ncpus*.");
6018
6019static PyObject *
6020posix_sched_getaffinity(PyObject *self, PyObject *args)
6021{
6022 pid_t pid;
6023 int ncpus;
6024 Py_cpu_set *res;
6025
Benjamin Peterson7ac92142011-08-03 08:54:26 -05006026 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006027 &pid, &ncpus))
6028 return NULL;
6029 res = make_new_cpu_set(&cpu_set_type, ncpus);
6030 if (!res)
6031 return NULL;
6032 if (sched_getaffinity(pid, res->size, res->set)) {
6033 Py_DECREF(res);
6034 return posix_error();
6035 }
6036 return (PyObject *)res;
6037}
6038
Benjamin Peterson2740af82011-08-02 17:41:34 -05006039#endif /* HAVE_SCHED_SETAFFINITY */
6040
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006041#endif /* HAVE_SCHED_H */
6042
Neal Norwitzb59798b2003-03-21 01:43:31 +00006043/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006044/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6045#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006046#define DEV_PTY_FILE "/dev/ptc"
6047#define HAVE_DEV_PTMX
6048#else
6049#define DEV_PTY_FILE "/dev/ptmx"
6050#endif
6051
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006052#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006053#ifdef HAVE_PTY_H
6054#include <pty.h>
6055#else
6056#ifdef HAVE_LIBUTIL_H
6057#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006058#else
6059#ifdef HAVE_UTIL_H
6060#include <util.h>
6061#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006062#endif /* HAVE_LIBUTIL_H */
6063#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006064#ifdef HAVE_STROPTS_H
6065#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006066#endif
6067#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006068
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006069#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006071"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006073
6074static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006075posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006076{
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006078#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006080#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006081#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006083#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006085#endif
6086#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006087
Thomas Wouters70c21a12000-07-14 14:28:33 +00006088#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006089 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6090 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006091#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6093 if (slave_name == NULL)
6094 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006095
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 slave_fd = open(slave_name, O_RDWR);
6097 if (slave_fd < 0)
6098 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006099#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6101 if (master_fd < 0)
6102 return posix_error();
6103 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6104 /* change permission of slave */
6105 if (grantpt(master_fd) < 0) {
6106 PyOS_setsig(SIGCHLD, sig_saved);
6107 return posix_error();
6108 }
6109 /* unlock slave */
6110 if (unlockpt(master_fd) < 0) {
6111 PyOS_setsig(SIGCHLD, sig_saved);
6112 return posix_error();
6113 }
6114 PyOS_setsig(SIGCHLD, sig_saved);
6115 slave_name = ptsname(master_fd); /* get name of slave */
6116 if (slave_name == NULL)
6117 return posix_error();
6118 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6119 if (slave_fd < 0)
6120 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006121#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006122 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6123 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006124#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006125 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006126#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006127#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006128#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006129
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006131
Fred Drake8cef4cf2000-06-28 16:40:38 +00006132}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006133#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006134
6135#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006138Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6139Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006141
6142static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006143posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006144{
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 int master_fd = -1, result = 0;
6146 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006147
Victor Stinner8c62be82010-05-06 00:08:46 +00006148 _PyImport_AcquireLock();
6149 pid = forkpty(&master_fd, NULL, NULL, NULL);
6150 if (pid == 0) {
6151 /* child: this clobbers and resets the import lock. */
6152 PyOS_AfterFork();
6153 } else {
6154 /* parent: release the import lock. */
6155 result = _PyImport_ReleaseLock();
6156 }
6157 if (pid == -1)
6158 return posix_error();
6159 if (result < 0) {
6160 /* Don't clobber the OSError if the fork failed. */
6161 PyErr_SetString(PyExc_RuntimeError,
6162 "not holding the import lock");
6163 return NULL;
6164 }
6165 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006166}
6167#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Ross Lagerwall7807c352011-03-17 20:20:30 +02006169
Guido van Rossumad0ee831995-03-01 10:34:45 +00006170#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006172"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006174
Barry Warsaw53699e91996-12-10 23:23:01 +00006175static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006176posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006177{
Victor Stinner8c62be82010-05-06 00:08:46 +00006178 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006179}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006180#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006182
Guido van Rossumad0ee831995-03-01 10:34:45 +00006183#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006184PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006185"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006186Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006187
Barry Warsaw53699e91996-12-10 23:23:01 +00006188static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006189posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006190{
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006192}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006193#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006194
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006195
Guido van Rossumad0ee831995-03-01 10:34:45 +00006196#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006197PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006198"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006199Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006200
Barry Warsaw53699e91996-12-10 23:23:01 +00006201static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006202posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006203{
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006205}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006206#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006208
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006210"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006212
Barry Warsaw53699e91996-12-10 23:23:01 +00006213static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006214posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006215{
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006217}
6218
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006219#ifdef HAVE_GETGROUPLIST
6220PyDoc_STRVAR(posix_getgrouplist__doc__,
6221"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6222Returns a list of groups to which a user belongs.\n\n\
6223 user: username to lookup\n\
6224 group: base group id of the user");
6225
6226static PyObject *
6227posix_getgrouplist(PyObject *self, PyObject *args)
6228{
6229#ifdef NGROUPS_MAX
6230#define MAX_GROUPS NGROUPS_MAX
6231#else
6232 /* defined to be 16 on Solaris7, so this should be a small number */
6233#define MAX_GROUPS 64
6234#endif
6235
6236 const char *user;
6237 int i, ngroups;
6238 PyObject *list;
6239#ifdef __APPLE__
6240 int *groups, basegid;
6241#else
6242 gid_t *groups, basegid;
6243#endif
6244 ngroups = MAX_GROUPS;
6245
6246 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6247 return NULL;
6248
6249#ifdef __APPLE__
6250 groups = PyMem_Malloc(ngroups * sizeof(int));
6251#else
6252 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6253#endif
6254 if (groups == NULL)
6255 return PyErr_NoMemory();
6256
6257 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6258 PyMem_Del(groups);
6259 return posix_error();
6260 }
6261
6262 list = PyList_New(ngroups);
6263 if (list == NULL) {
6264 PyMem_Del(groups);
6265 return NULL;
6266 }
6267
6268 for (i = 0; i < ngroups; i++) {
6269 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6270 if (o == NULL) {
6271 Py_DECREF(list);
6272 PyMem_Del(groups);
6273 return NULL;
6274 }
6275 PyList_SET_ITEM(list, i, o);
6276 }
6277
6278 PyMem_Del(groups);
6279
6280 return list;
6281}
6282#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006283
Fred Drakec9680921999-12-13 16:37:25 +00006284#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006286"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006288
6289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006290posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006291{
6292 PyObject *result = NULL;
6293
Fred Drakec9680921999-12-13 16:37:25 +00006294#ifdef NGROUPS_MAX
6295#define MAX_GROUPS NGROUPS_MAX
6296#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006298#define MAX_GROUPS 64
6299#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006301
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006302 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006303 * This is a helper variable to store the intermediate result when
6304 * that happens.
6305 *
6306 * To keep the code readable the OSX behaviour is unconditional,
6307 * according to the POSIX spec this should be safe on all unix-y
6308 * systems.
6309 */
6310 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006312
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006314 if (n < 0) {
6315 if (errno == EINVAL) {
6316 n = getgroups(0, NULL);
6317 if (n == -1) {
6318 return posix_error();
6319 }
6320 if (n == 0) {
6321 /* Avoid malloc(0) */
6322 alt_grouplist = grouplist;
6323 } else {
6324 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6325 if (alt_grouplist == NULL) {
6326 errno = EINVAL;
6327 return posix_error();
6328 }
6329 n = getgroups(n, alt_grouplist);
6330 if (n == -1) {
6331 PyMem_Free(alt_grouplist);
6332 return posix_error();
6333 }
6334 }
6335 } else {
6336 return posix_error();
6337 }
6338 }
6339 result = PyList_New(n);
6340 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 int i;
6342 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006343 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006345 Py_DECREF(result);
6346 result = NULL;
6347 break;
Fred Drakec9680921999-12-13 16:37:25 +00006348 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006350 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006351 }
6352
6353 if (alt_grouplist != grouplist) {
6354 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006356
Fred Drakec9680921999-12-13 16:37:25 +00006357 return result;
6358}
6359#endif
6360
Antoine Pitroub7572f02009-12-02 20:46:48 +00006361#ifdef HAVE_INITGROUPS
6362PyDoc_STRVAR(posix_initgroups__doc__,
6363"initgroups(username, gid) -> None\n\n\
6364Call the system initgroups() to initialize the group access list with all of\n\
6365the groups of which the specified username is a member, plus the specified\n\
6366group id.");
6367
6368static PyObject *
6369posix_initgroups(PyObject *self, PyObject *args)
6370{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006371 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006373 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006375
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006376 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6377 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006379 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006380
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006381 res = initgroups(username, (gid_t) gid);
6382 Py_DECREF(oname);
6383 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 Py_INCREF(Py_None);
6387 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006388}
6389#endif
6390
Martin v. Löwis606edc12002-06-13 21:09:11 +00006391#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006392PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006393"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006394Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006395
6396static PyObject *
6397posix_getpgid(PyObject *self, PyObject *args)
6398{
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 pid_t pid, pgid;
6400 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6401 return NULL;
6402 pgid = getpgid(pid);
6403 if (pgid < 0)
6404 return posix_error();
6405 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006406}
6407#endif /* HAVE_GETPGID */
6408
6409
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Barry Warsaw53699e91996-12-10 23:23:01 +00006415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006416posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006417{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006418#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006420#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006422#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006423}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006424#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006426
Guido van Rossumb6775db1994-08-01 11:34:53 +00006427#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006428PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006429"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006430Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006431
Barry Warsaw53699e91996-12-10 23:23:01 +00006432static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006433posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006434{
Guido van Rossum64933891994-10-20 21:56:42 +00006435#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006437#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006439#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 return posix_error();
6441 Py_INCREF(Py_None);
6442 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006443}
6444
Guido van Rossumb6775db1994-08-01 11:34:53 +00006445#endif /* HAVE_SETPGRP */
6446
Guido van Rossumad0ee831995-03-01 10:34:45 +00006447#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006448
6449#ifdef MS_WINDOWS
6450#include <tlhelp32.h>
6451
6452static PyObject*
6453win32_getppid()
6454{
6455 HANDLE snapshot;
6456 pid_t mypid;
6457 PyObject* result = NULL;
6458 BOOL have_record;
6459 PROCESSENTRY32 pe;
6460
6461 mypid = getpid(); /* This function never fails */
6462
6463 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6464 if (snapshot == INVALID_HANDLE_VALUE)
6465 return PyErr_SetFromWindowsErr(GetLastError());
6466
6467 pe.dwSize = sizeof(pe);
6468 have_record = Process32First(snapshot, &pe);
6469 while (have_record) {
6470 if (mypid == (pid_t)pe.th32ProcessID) {
6471 /* We could cache the ulong value in a static variable. */
6472 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6473 break;
6474 }
6475
6476 have_record = Process32Next(snapshot, &pe);
6477 }
6478
6479 /* If our loop exits and our pid was not found (result will be NULL)
6480 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6481 * error anyway, so let's raise it. */
6482 if (!result)
6483 result = PyErr_SetFromWindowsErr(GetLastError());
6484
6485 CloseHandle(snapshot);
6486
6487 return result;
6488}
6489#endif /*MS_WINDOWS*/
6490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006491PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006492"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006493Return the parent's process id. If the parent process has already exited,\n\
6494Windows machines will still return its id; others systems will return the id\n\
6495of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006496
Barry Warsaw53699e91996-12-10 23:23:01 +00006497static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006498posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006499{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006500#ifdef MS_WINDOWS
6501 return win32_getppid();
6502#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006504#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006505}
6506#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006507
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006508
Fred Drake12c6e2d1999-12-14 21:25:03 +00006509#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006510PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006511"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006513
6514static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006515posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006516{
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006518#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006519 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006520 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006521
6522 if (GetUserNameW(user_name, &num_chars)) {
6523 /* num_chars is the number of unicode chars plus null terminator */
6524 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006525 }
6526 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006527 result = PyErr_SetFromWindowsErr(GetLastError());
6528#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 char *name;
6530 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006531
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 errno = 0;
6533 name = getlogin();
6534 if (name == NULL) {
6535 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006536 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006537 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006538 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 }
6540 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006541 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006543#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006544 return result;
6545}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006546#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006547
Guido van Rossumad0ee831995-03-01 10:34:45 +00006548#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006549PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006550"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006551Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006552
Barry Warsaw53699e91996-12-10 23:23:01 +00006553static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006554posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006555{
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006557}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006558#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006560
Guido van Rossumad0ee831995-03-01 10:34:45 +00006561#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006563"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006564Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006565
Barry Warsaw53699e91996-12-10 23:23:01 +00006566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006567posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006568{
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 pid_t pid;
6570 int sig;
6571 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6572 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006573#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006574 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6575 APIRET rc;
6576 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006577 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006578
6579 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6580 APIRET rc;
6581 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006582 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006583
6584 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006585 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006586#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 if (kill(pid, sig) == -1)
6588 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006589#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 Py_INCREF(Py_None);
6591 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006592}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006593#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006594
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006595#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006597"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006599
6600static PyObject *
6601posix_killpg(PyObject *self, PyObject *args)
6602{
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 int sig;
6604 pid_t pgid;
6605 /* XXX some man pages make the `pgid` parameter an int, others
6606 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6607 take the same type. Moreover, pid_t is always at least as wide as
6608 int (else compilation of this module fails), which is safe. */
6609 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6610 return NULL;
6611 if (killpg(pgid, sig) == -1)
6612 return posix_error();
6613 Py_INCREF(Py_None);
6614 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006615}
6616#endif
6617
Brian Curtineb24d742010-04-12 17:16:38 +00006618#ifdef MS_WINDOWS
6619PyDoc_STRVAR(win32_kill__doc__,
6620"kill(pid, sig)\n\n\
6621Kill a process with a signal.");
6622
6623static PyObject *
6624win32_kill(PyObject *self, PyObject *args)
6625{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006626 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 DWORD pid, sig, err;
6628 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006629
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6631 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006632
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 /* Console processes which share a common console can be sent CTRL+C or
6634 CTRL+BREAK events, provided they handle said events. */
6635 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6636 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6637 err = GetLastError();
6638 PyErr_SetFromWindowsErr(err);
6639 }
6640 else
6641 Py_RETURN_NONE;
6642 }
Brian Curtineb24d742010-04-12 17:16:38 +00006643
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6645 attempt to open and terminate the process. */
6646 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6647 if (handle == NULL) {
6648 err = GetLastError();
6649 return PyErr_SetFromWindowsErr(err);
6650 }
Brian Curtineb24d742010-04-12 17:16:38 +00006651
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 if (TerminateProcess(handle, sig) == 0) {
6653 err = GetLastError();
6654 result = PyErr_SetFromWindowsErr(err);
6655 } else {
6656 Py_INCREF(Py_None);
6657 result = Py_None;
6658 }
Brian Curtineb24d742010-04-12 17:16:38 +00006659
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 CloseHandle(handle);
6661 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006662}
6663#endif /* MS_WINDOWS */
6664
Guido van Rossumc0125471996-06-28 18:55:32 +00006665#ifdef HAVE_PLOCK
6666
6667#ifdef HAVE_SYS_LOCK_H
6668#include <sys/lock.h>
6669#endif
6670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006672"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006674
Barry Warsaw53699e91996-12-10 23:23:01 +00006675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006676posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006677{
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 int op;
6679 if (!PyArg_ParseTuple(args, "i:plock", &op))
6680 return NULL;
6681 if (plock(op) == -1)
6682 return posix_error();
6683 Py_INCREF(Py_None);
6684 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006685}
6686#endif
6687
Guido van Rossumb6775db1994-08-01 11:34:53 +00006688#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Set the current process's user id.");
6692
Barry Warsaw53699e91996-12-10 23:23:01 +00006693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006694posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006695{
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 long uid_arg;
6697 uid_t uid;
6698 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6699 return NULL;
6700 uid = uid_arg;
6701 if (uid != uid_arg) {
6702 PyErr_SetString(PyExc_OverflowError, "user id too big");
6703 return NULL;
6704 }
6705 if (setuid(uid) < 0)
6706 return posix_error();
6707 Py_INCREF(Py_None);
6708 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006709}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006710#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006712
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006713#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006714PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006715"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006716Set the current process's effective user id.");
6717
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006718static PyObject *
6719posix_seteuid (PyObject *self, PyObject *args)
6720{
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 long euid_arg;
6722 uid_t euid;
6723 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6724 return NULL;
6725 euid = euid_arg;
6726 if (euid != euid_arg) {
6727 PyErr_SetString(PyExc_OverflowError, "user id too big");
6728 return NULL;
6729 }
6730 if (seteuid(euid) < 0) {
6731 return posix_error();
6732 } else {
6733 Py_INCREF(Py_None);
6734 return Py_None;
6735 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006736}
6737#endif /* HAVE_SETEUID */
6738
6739#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006740PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006741"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006742Set the current process's effective group id.");
6743
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006744static PyObject *
6745posix_setegid (PyObject *self, PyObject *args)
6746{
Victor Stinner8c62be82010-05-06 00:08:46 +00006747 long egid_arg;
6748 gid_t egid;
6749 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6750 return NULL;
6751 egid = egid_arg;
6752 if (egid != egid_arg) {
6753 PyErr_SetString(PyExc_OverflowError, "group id too big");
6754 return NULL;
6755 }
6756 if (setegid(egid) < 0) {
6757 return posix_error();
6758 } else {
6759 Py_INCREF(Py_None);
6760 return Py_None;
6761 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006762}
6763#endif /* HAVE_SETEGID */
6764
6765#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006766PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006767"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768Set the current process's real and effective user ids.");
6769
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006770static PyObject *
6771posix_setreuid (PyObject *self, PyObject *args)
6772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 long ruid_arg, euid_arg;
6774 uid_t ruid, euid;
6775 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6776 return NULL;
6777 if (ruid_arg == -1)
6778 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6779 else
6780 ruid = ruid_arg; /* otherwise, assign from our long */
6781 if (euid_arg == -1)
6782 euid = (uid_t)-1;
6783 else
6784 euid = euid_arg;
6785 if ((euid_arg != -1 && euid != euid_arg) ||
6786 (ruid_arg != -1 && ruid != ruid_arg)) {
6787 PyErr_SetString(PyExc_OverflowError, "user id too big");
6788 return NULL;
6789 }
6790 if (setreuid(ruid, euid) < 0) {
6791 return posix_error();
6792 } else {
6793 Py_INCREF(Py_None);
6794 return Py_None;
6795 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006796}
6797#endif /* HAVE_SETREUID */
6798
6799#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006800PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006801"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006802Set the current process's real and effective group ids.");
6803
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006804static PyObject *
6805posix_setregid (PyObject *self, PyObject *args)
6806{
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 long rgid_arg, egid_arg;
6808 gid_t rgid, egid;
6809 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6810 return NULL;
6811 if (rgid_arg == -1)
6812 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6813 else
6814 rgid = rgid_arg; /* otherwise, assign from our long */
6815 if (egid_arg == -1)
6816 egid = (gid_t)-1;
6817 else
6818 egid = egid_arg;
6819 if ((egid_arg != -1 && egid != egid_arg) ||
6820 (rgid_arg != -1 && rgid != rgid_arg)) {
6821 PyErr_SetString(PyExc_OverflowError, "group id too big");
6822 return NULL;
6823 }
6824 if (setregid(rgid, egid) < 0) {
6825 return posix_error();
6826 } else {
6827 Py_INCREF(Py_None);
6828 return Py_None;
6829 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006830}
6831#endif /* HAVE_SETREGID */
6832
Guido van Rossumb6775db1994-08-01 11:34:53 +00006833#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006834PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006835"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006836Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006837
Barry Warsaw53699e91996-12-10 23:23:01 +00006838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006839posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006840{
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 long gid_arg;
6842 gid_t gid;
6843 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6844 return NULL;
6845 gid = gid_arg;
6846 if (gid != gid_arg) {
6847 PyErr_SetString(PyExc_OverflowError, "group id too big");
6848 return NULL;
6849 }
6850 if (setgid(gid) < 0)
6851 return posix_error();
6852 Py_INCREF(Py_None);
6853 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006854}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006855#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006856
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006857#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006859"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006860Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006861
6862static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006863posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006864{
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 int i, len;
6866 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 if (!PySequence_Check(groups)) {
6869 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6870 return NULL;
6871 }
6872 len = PySequence_Size(groups);
6873 if (len > MAX_GROUPS) {
6874 PyErr_SetString(PyExc_ValueError, "too many groups");
6875 return NULL;
6876 }
6877 for(i = 0; i < len; i++) {
6878 PyObject *elem;
6879 elem = PySequence_GetItem(groups, i);
6880 if (!elem)
6881 return NULL;
6882 if (!PyLong_Check(elem)) {
6883 PyErr_SetString(PyExc_TypeError,
6884 "groups must be integers");
6885 Py_DECREF(elem);
6886 return NULL;
6887 } else {
6888 unsigned long x = PyLong_AsUnsignedLong(elem);
6889 if (PyErr_Occurred()) {
6890 PyErr_SetString(PyExc_TypeError,
6891 "group id too big");
6892 Py_DECREF(elem);
6893 return NULL;
6894 }
6895 grouplist[i] = x;
6896 /* read back the value to see if it fitted in gid_t */
6897 if (grouplist[i] != x) {
6898 PyErr_SetString(PyExc_TypeError,
6899 "group id too big");
6900 Py_DECREF(elem);
6901 return NULL;
6902 }
6903 }
6904 Py_DECREF(elem);
6905 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006906
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 if (setgroups(len, grouplist) < 0)
6908 return posix_error();
6909 Py_INCREF(Py_None);
6910 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006911}
6912#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006913
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6915static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006916wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917{
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 PyObject *result;
6919 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006920 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 if (pid == -1)
6923 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 if (struct_rusage == NULL) {
6926 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6927 if (m == NULL)
6928 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006929 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 Py_DECREF(m);
6931 if (struct_rusage == NULL)
6932 return NULL;
6933 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6936 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6937 if (!result)
6938 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006939
6940#ifndef doubletime
6941#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6942#endif
6943
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006945 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006947 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6950 SET_INT(result, 2, ru->ru_maxrss);
6951 SET_INT(result, 3, ru->ru_ixrss);
6952 SET_INT(result, 4, ru->ru_idrss);
6953 SET_INT(result, 5, ru->ru_isrss);
6954 SET_INT(result, 6, ru->ru_minflt);
6955 SET_INT(result, 7, ru->ru_majflt);
6956 SET_INT(result, 8, ru->ru_nswap);
6957 SET_INT(result, 9, ru->ru_inblock);
6958 SET_INT(result, 10, ru->ru_oublock);
6959 SET_INT(result, 11, ru->ru_msgsnd);
6960 SET_INT(result, 12, ru->ru_msgrcv);
6961 SET_INT(result, 13, ru->ru_nsignals);
6962 SET_INT(result, 14, ru->ru_nvcsw);
6963 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006964#undef SET_INT
6965
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 if (PyErr_Occurred()) {
6967 Py_DECREF(result);
6968 return NULL;
6969 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006970
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972}
6973#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6974
6975#ifdef HAVE_WAIT3
6976PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006977"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006978Wait for completion of a child process.");
6979
6980static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006981posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006982{
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 pid_t pid;
6984 int options;
6985 struct rusage ru;
6986 WAIT_TYPE status;
6987 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006988
Victor Stinner4195b5c2012-02-08 23:03:19 +01006989 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006991
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 Py_BEGIN_ALLOW_THREADS
6993 pid = wait3(&status, options, &ru);
6994 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006995
Victor Stinner4195b5c2012-02-08 23:03:19 +01006996 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006997}
6998#endif /* HAVE_WAIT3 */
6999
7000#ifdef HAVE_WAIT4
7001PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007002"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007003Wait for completion of a given child process.");
7004
7005static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007006posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007007{
Victor Stinner8c62be82010-05-06 00:08:46 +00007008 pid_t pid;
7009 int options;
7010 struct rusage ru;
7011 WAIT_TYPE status;
7012 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007013
Victor Stinner4195b5c2012-02-08 23:03:19 +01007014 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007016
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 Py_BEGIN_ALLOW_THREADS
7018 pid = wait4(pid, &status, options, &ru);
7019 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007020
Victor Stinner4195b5c2012-02-08 23:03:19 +01007021 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007022}
7023#endif /* HAVE_WAIT4 */
7024
Ross Lagerwall7807c352011-03-17 20:20:30 +02007025#if defined(HAVE_WAITID) && !defined(__APPLE__)
7026PyDoc_STRVAR(posix_waitid__doc__,
7027"waitid(idtype, id, options) -> waitid_result\n\n\
7028Wait for the completion of one or more child processes.\n\n\
7029idtype can be P_PID, P_PGID or P_ALL.\n\
7030id specifies the pid to wait on.\n\
7031options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
7032or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
7033Returns either waitid_result or None if WNOHANG is specified and there are\n\
7034no children in a waitable state.");
7035
7036static PyObject *
7037posix_waitid(PyObject *self, PyObject *args)
7038{
7039 PyObject *result;
7040 idtype_t idtype;
7041 id_t id;
7042 int options, res;
7043 siginfo_t si;
7044 si.si_pid = 0;
7045 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7046 return NULL;
7047 Py_BEGIN_ALLOW_THREADS
7048 res = waitid(idtype, id, &si, options);
7049 Py_END_ALLOW_THREADS
7050 if (res == -1)
7051 return posix_error();
7052
7053 if (si.si_pid == 0)
7054 Py_RETURN_NONE;
7055
7056 result = PyStructSequence_New(&WaitidResultType);
7057 if (!result)
7058 return NULL;
7059
7060 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
7061 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
7062 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7063 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7064 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7065 if (PyErr_Occurred()) {
7066 Py_DECREF(result);
7067 return NULL;
7068 }
7069
7070 return result;
7071}
7072#endif
7073
Guido van Rossumb6775db1994-08-01 11:34:53 +00007074#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007075PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007076"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007078
Barry Warsaw53699e91996-12-10 23:23:01 +00007079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007080posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007081{
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 pid_t pid;
7083 int options;
7084 WAIT_TYPE status;
7085 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007086
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7088 return NULL;
7089 Py_BEGIN_ALLOW_THREADS
7090 pid = waitpid(pid, &status, options);
7091 Py_END_ALLOW_THREADS
7092 if (pid == -1)
7093 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007094
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007096}
7097
Tim Petersab034fa2002-02-01 11:27:43 +00007098#elif defined(HAVE_CWAIT)
7099
7100/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007101PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007102"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007103"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007104
7105static PyObject *
7106posix_waitpid(PyObject *self, PyObject *args)
7107{
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 Py_intptr_t pid;
7109 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007110
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7112 return NULL;
7113 Py_BEGIN_ALLOW_THREADS
7114 pid = _cwait(&status, pid, options);
7115 Py_END_ALLOW_THREADS
7116 if (pid == -1)
7117 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007118
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 /* shift the status left a byte so this is more like the POSIX waitpid */
7120 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007121}
7122#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007123
Guido van Rossumad0ee831995-03-01 10:34:45 +00007124#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007125PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007126"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007128
Barry Warsaw53699e91996-12-10 23:23:01 +00007129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007130posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007131{
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 pid_t pid;
7133 WAIT_TYPE status;
7134 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007135
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 Py_BEGIN_ALLOW_THREADS
7137 pid = wait(&status);
7138 Py_END_ALLOW_THREADS
7139 if (pid == -1)
7140 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007141
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007143}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007144#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007146
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7148PyDoc_STRVAR(readlink__doc__,
7149"readlink(path, *, dir_fd=None) -> path\n\n\
7150Return a string representing the path to which the symbolic link points.\n\
7151\n\
7152If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7153 and path should be relative; path will then be relative to that directory.\n\
7154dir_fd may not be implemented on your platform.\n\
7155 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007156#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007157
Guido van Rossumb6775db1994-08-01 11:34:53 +00007158#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007159
Barry Warsaw53699e91996-12-10 23:23:01 +00007160static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007161posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007162{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163 path_t path;
7164 int dir_fd = DEFAULT_DIR_FD;
7165 char buffer[MAXPATHLEN];
7166 ssize_t length;
7167 PyObject *return_value = NULL;
7168 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007169
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 memset(&path, 0, sizeof(path));
7171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7172 path_converter, &path,
7173#ifdef HAVE_READLINKAT
7174 dir_fd_converter, &dir_fd
7175#else
7176 dir_fd_unavailable, &dir_fd
7177#endif
7178 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007179 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007180
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007182#ifdef HAVE_READLINKAT
7183 if (dir_fd != DEFAULT_DIR_FD)
7184 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007185 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007186#endif
7187 length = readlink(path.narrow, buffer, sizeof(buffer));
7188 Py_END_ALLOW_THREADS
7189
7190 if (length < 0) {
7191 return_value = path_posix_error("readlink", &path);
7192 goto exit;
7193 }
7194
7195 if (PyUnicode_Check(path.object))
7196 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7197 else
7198 return_value = PyBytes_FromStringAndSize(buffer, length);
7199exit:
7200 path_cleanup(&path);
7201 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007202}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007203
7204
Guido van Rossumb6775db1994-08-01 11:34:53 +00007205#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007207
Larry Hastings9cf065c2012-06-22 16:30:09 -07007208#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007209PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007210"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7211Create a symbolic link pointing to src named dst.\n\n\
7212target_is_directory is required on Windows if the target is to be\n\
7213 interpreted as a directory. (On Windows, symlink requires\n\
7214 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7215 target_is_directory is ignored on non-Windows platforms.\n\
7216\n\
7217If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7218 and path should be relative; path will then be relative to that directory.\n\
7219dir_fd may not be implemented on your platform.\n\
7220 If it is unavailable, using it will raise a NotImplementedError.");
7221
7222#if defined(MS_WINDOWS)
7223
7224/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7225static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7226static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7227static int
7228check_CreateSymbolicLink()
7229{
7230 HINSTANCE hKernel32;
7231 /* only recheck */
7232 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7233 return 1;
7234 hKernel32 = GetModuleHandleW(L"KERNEL32");
7235 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7236 "CreateSymbolicLinkW");
7237 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7238 "CreateSymbolicLinkA");
7239 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7240}
7241
7242#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007243
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007244static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007245posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007246{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007247 path_t src;
7248 path_t dst;
7249 int dir_fd = DEFAULT_DIR_FD;
7250 int target_is_directory = 0;
7251 static char *keywords[] = {"src", "dst", "target_is_directory",
7252 "dir_fd", NULL};
7253 PyObject *return_value;
7254#ifdef MS_WINDOWS
7255 DWORD result;
7256#else
7257 int result;
7258#endif
7259
7260 memset(&src, 0, sizeof(src));
7261 src.argument_name = "src";
7262 memset(&dst, 0, sizeof(dst));
7263 dst.argument_name = "dst";
7264
7265#ifdef MS_WINDOWS
7266 if (!check_CreateSymbolicLink()) {
7267 PyErr_SetString(PyExc_NotImplementedError,
7268 "CreateSymbolicLink functions not found");
7269 return NULL;
7270 }
7271 if (!win32_can_symlink) {
7272 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7273 return NULL;
7274 }
7275#endif
7276
7277 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7278 keywords,
7279 path_converter, &src,
7280 path_converter, &dst,
7281 &target_is_directory,
7282#ifdef HAVE_SYMLINKAT
7283 dir_fd_converter, &dir_fd
7284#else
7285 dir_fd_unavailable, &dir_fd
7286#endif
7287 ))
7288 return NULL;
7289
7290 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7291 PyErr_SetString(PyExc_ValueError,
7292 "symlink: src and dst must be the same type");
7293 return_value = NULL;
7294 goto exit;
7295 }
7296
7297#ifdef MS_WINDOWS
7298 Py_BEGIN_ALLOW_THREADS
7299 if (dst.wide)
7300 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7301 target_is_directory);
7302 else
7303 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7304 target_is_directory);
7305 Py_END_ALLOW_THREADS
7306
7307 if (!result) {
7308 return_value = win32_error_object("symlink", src.object);
7309 goto exit;
7310 }
7311
7312#else
7313
7314 Py_BEGIN_ALLOW_THREADS
7315#if HAVE_SYMLINKAT
7316 if (dir_fd != DEFAULT_DIR_FD)
7317 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7318 else
7319#endif
7320 result = symlink(src.narrow, dst.narrow);
7321 Py_END_ALLOW_THREADS
7322
7323 if (result) {
7324 return_value = path_error("symlink", &dst);
7325 goto exit;
7326 }
7327#endif
7328
7329 return_value = Py_None;
7330 Py_INCREF(Py_None);
7331 goto exit; /* silence "unused label" warning */
7332exit:
7333 path_cleanup(&src);
7334 path_cleanup(&dst);
7335 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007336}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007337
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007338#endif /* HAVE_SYMLINK */
7339
Larry Hastings9cf065c2012-06-22 16:30:09 -07007340
Brian Curtind40e6f72010-07-08 21:39:08 +00007341#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7342
Brian Curtind40e6f72010-07-08 21:39:08 +00007343static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007344win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007345{
7346 wchar_t *path;
7347 DWORD n_bytes_returned;
7348 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007349 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007350 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007351 HANDLE reparse_point_handle;
7352
7353 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7354 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7355 wchar_t *print_name;
7356
Larry Hastings9cf065c2012-06-22 16:30:09 -07007357 static char *keywords[] = {"path", "dir_fd", NULL};
7358
7359 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7360 &po,
7361 dir_fd_unavailable, &dir_fd
7362 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007363 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007364
Victor Stinnereb5657a2011-09-30 01:44:27 +02007365 path = PyUnicode_AsUnicode(po);
7366 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007367 return NULL;
7368
7369 /* First get a handle to the reparse point */
7370 Py_BEGIN_ALLOW_THREADS
7371 reparse_point_handle = CreateFileW(
7372 path,
7373 0,
7374 0,
7375 0,
7376 OPEN_EXISTING,
7377 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7378 0);
7379 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007380
Brian Curtind40e6f72010-07-08 21:39:08 +00007381 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007382 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007383
Brian Curtind40e6f72010-07-08 21:39:08 +00007384 Py_BEGIN_ALLOW_THREADS
7385 /* New call DeviceIoControl to read the reparse point */
7386 io_result = DeviceIoControl(
7387 reparse_point_handle,
7388 FSCTL_GET_REPARSE_POINT,
7389 0, 0, /* in buffer */
7390 target_buffer, sizeof(target_buffer),
7391 &n_bytes_returned,
7392 0 /* we're not using OVERLAPPED_IO */
7393 );
7394 CloseHandle(reparse_point_handle);
7395 Py_END_ALLOW_THREADS
7396
7397 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007398 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007399
7400 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7401 {
7402 PyErr_SetString(PyExc_ValueError,
7403 "not a symbolic link");
7404 return NULL;
7405 }
Brian Curtin74e45612010-07-09 15:58:59 +00007406 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7407 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7408
7409 result = PyUnicode_FromWideChar(print_name,
7410 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007411 return result;
7412}
7413
7414#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7415
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007416
Larry Hastings605a62d2012-06-24 04:33:36 -07007417static PyStructSequence_Field times_result_fields[] = {
7418 {"user", "user time"},
7419 {"system", "system time"},
7420 {"children_user", "user time of children"},
7421 {"children_system", "system time of children"},
7422 {"elapsed", "elapsed time since an arbitrary point in the past"},
7423 {NULL}
7424};
7425
7426PyDoc_STRVAR(times_result__doc__,
7427"times_result: Result from os.times().\n\n\
7428This object may be accessed either as a tuple of\n\
7429 (user, system, children_user, children_system, elapsed),\n\
7430or via the attributes user, system, children_user, children_system,\n\
7431and elapsed.\n\
7432\n\
7433See os.times for more information.");
7434
7435static PyStructSequence_Desc times_result_desc = {
7436 "times_result", /* name */
7437 times_result__doc__, /* doc */
7438 times_result_fields,
7439 5
7440};
7441
7442static PyTypeObject TimesResultType;
7443
7444
7445#if defined(HAVE_TIMES) || defined(MS_WINDOWS)
7446
7447static PyObject *
7448build_times_result(double user, double system,
7449 double children_user, double children_system,
7450 double elapsed)
7451{
7452 PyObject *value = PyStructSequence_New(&TimesResultType);
7453 if (value == NULL)
7454 return NULL;
7455
7456#define SET(i, field) \
7457 { \
7458 PyObject *o = PyFloat_FromDouble(field); \
7459 if (!o) { \
7460 Py_DECREF(value); \
7461 return NULL; \
7462 } \
7463 PyStructSequence_SET_ITEM(value, i, o); \
7464 } \
7465
7466 SET(0, user);
7467 SET(1, system);
7468 SET(2, children_user);
7469 SET(3, children_system);
7470 SET(4, elapsed);
7471
7472#undef SET
7473
7474 return value;
7475}
7476
7477PyDoc_STRVAR(posix_times__doc__,
7478"times() -> times_result\n\n\
7479Return an object containing floating point numbers indicating process\n\
7480times. The object behaves like a named tuple with these fields:\n\
7481 (utime, stime, cutime, cstime, elapsed_time)");
7482
7483#endif
7484
7485
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007486#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007487#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7488static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007489system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007490{
7491 ULONG value = 0;
7492
7493 Py_BEGIN_ALLOW_THREADS
7494 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7495 Py_END_ALLOW_THREADS
7496
7497 return value;
7498}
7499
7500static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007501posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007502{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007503 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007504 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007505 (double)0 /* t.tms_utime / HZ */,
7506 (double)0 /* t.tms_stime / HZ */,
7507 (double)0 /* t.tms_cutime / HZ */,
7508 (double)0 /* t.tms_cstime / HZ */,
7509 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007510}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007511#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007512#define NEED_TICKS_PER_SECOND
7513static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007514static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007515posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007516{
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 struct tms t;
7518 clock_t c;
7519 errno = 0;
7520 c = times(&t);
7521 if (c == (clock_t) -1)
7522 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07007523 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007524 (double)t.tms_utime / ticks_per_second,
7525 (double)t.tms_stime / ticks_per_second,
7526 (double)t.tms_cutime / ticks_per_second,
7527 (double)t.tms_cstime / ticks_per_second,
7528 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007529}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007530#endif /* not OS2 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007531#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007532static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007533posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007534{
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 FILETIME create, exit, kernel, user;
7536 HANDLE hProc;
7537 hProc = GetCurrentProcess();
7538 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7539 /* The fields of a FILETIME structure are the hi and lo part
7540 of a 64-bit value expressed in 100 nanosecond units.
7541 1e7 is one second in such units; 1e-7 the inverse.
7542 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7543 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007544 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 (double)(user.dwHighDateTime*429.4967296 +
7546 user.dwLowDateTime*1e-7),
7547 (double)(kernel.dwHighDateTime*429.4967296 +
7548 kernel.dwLowDateTime*1e-7),
7549 (double)0,
7550 (double)0,
7551 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007552}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007553#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007555
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007556#ifdef HAVE_GETSID
7557PyDoc_STRVAR(posix_getsid__doc__,
7558"getsid(pid) -> sid\n\n\
7559Call the system call getsid().");
7560
7561static PyObject *
7562posix_getsid(PyObject *self, PyObject *args)
7563{
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 pid_t pid;
7565 int sid;
7566 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7567 return NULL;
7568 sid = getsid(pid);
7569 if (sid < 0)
7570 return posix_error();
7571 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007572}
7573#endif /* HAVE_GETSID */
7574
7575
Guido van Rossumb6775db1994-08-01 11:34:53 +00007576#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007577PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007578"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007579Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007580
Barry Warsaw53699e91996-12-10 23:23:01 +00007581static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007582posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 if (setsid() < 0)
7585 return posix_error();
7586 Py_INCREF(Py_None);
7587 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007588}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007590
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007592PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007593"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007594Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007595
Barry Warsaw53699e91996-12-10 23:23:01 +00007596static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007597posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 pid_t pid;
7600 int pgrp;
7601 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7602 return NULL;
7603 if (setpgid(pid, pgrp) < 0)
7604 return posix_error();
7605 Py_INCREF(Py_None);
7606 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007608#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007613"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Barry Warsaw53699e91996-12-10 23:23:01 +00007616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007617posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007618{
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 int fd;
7620 pid_t pgid;
7621 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7622 return NULL;
7623 pgid = tcgetpgrp(fd);
7624 if (pgid < 0)
7625 return posix_error();
7626 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007627}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007628#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007630
Guido van Rossumb6775db1994-08-01 11:34:53 +00007631#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007632PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007633"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007634Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007635
Barry Warsaw53699e91996-12-10 23:23:01 +00007636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007637posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007638{
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 int fd;
7640 pid_t pgid;
7641 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7642 return NULL;
7643 if (tcsetpgrp(fd, pgid) < 0)
7644 return posix_error();
7645 Py_INCREF(Py_None);
7646 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007648#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007649
Guido van Rossum687dd131993-05-17 08:34:16 +00007650/* Functions acting on file descriptors */
7651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007652PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007653"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7654Open a file for low level IO. Returns a file handle (integer).\n\
7655\n\
7656If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7657 and path should be relative; path will then be relative to that directory.\n\
7658dir_fd may not be implemented on your platform.\n\
7659 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007660
Barry Warsaw53699e91996-12-10 23:23:01 +00007661static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007662posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007663{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007664 path_t path;
7665 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007667 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007669 PyObject *return_value = NULL;
7670 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007671
Larry Hastings9cf065c2012-06-22 16:30:09 -07007672 memset(&path, 0, sizeof(path));
7673 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7674 path_converter, &path,
7675 &flags, &mode,
7676#ifdef HAVE_OPENAT
7677 dir_fd_converter, &dir_fd
7678#else
7679 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007680#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007681 ))
7682 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007683
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007685#ifdef MS_WINDOWS
7686 if (path.wide)
7687 fd = _wopen(path.wide, flags, mode);
7688 else
7689#endif
7690#ifdef HAVE_OPENAT
7691 if (dir_fd != DEFAULT_DIR_FD)
7692 fd = openat(dir_fd, path.narrow, flags, mode);
7693 else
7694#endif
7695 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007697
Larry Hastings9cf065c2012-06-22 16:30:09 -07007698 if (fd == -1) {
7699#ifdef MS_WINDOWS
7700 /* force use of posix_error here for exact backwards compatibility */
7701 if (path.wide)
7702 return_value = posix_error();
7703 else
7704#endif
7705 return_value = path_error("open", &path);
7706 goto exit;
7707 }
7708
7709 return_value = PyLong_FromLong((long)fd);
7710
7711exit:
7712 path_cleanup(&path);
7713 return return_value;
7714}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007715
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007716PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007717"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007718Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007719
Barry Warsaw53699e91996-12-10 23:23:01 +00007720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007721posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007722{
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 int fd, res;
7724 if (!PyArg_ParseTuple(args, "i:close", &fd))
7725 return NULL;
7726 if (!_PyVerify_fd(fd))
7727 return posix_error();
7728 Py_BEGIN_ALLOW_THREADS
7729 res = close(fd);
7730 Py_END_ALLOW_THREADS
7731 if (res < 0)
7732 return posix_error();
7733 Py_INCREF(Py_None);
7734 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007735}
7736
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007737
Victor Stinner8c62be82010-05-06 00:08:46 +00007738PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007739"closerange(fd_low, fd_high)\n\n\
7740Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7741
7742static PyObject *
7743posix_closerange(PyObject *self, PyObject *args)
7744{
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 int fd_from, fd_to, i;
7746 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7747 return NULL;
7748 Py_BEGIN_ALLOW_THREADS
7749 for (i = fd_from; i < fd_to; i++)
7750 if (_PyVerify_fd(i))
7751 close(i);
7752 Py_END_ALLOW_THREADS
7753 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007754}
7755
7756
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007757PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007758"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007759Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007760
Barry Warsaw53699e91996-12-10 23:23:01 +00007761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007762posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007763{
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 int fd;
7765 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7766 return NULL;
7767 if (!_PyVerify_fd(fd))
7768 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 if (fd < 0)
7771 return posix_error();
7772 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007773}
7774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007776PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007777"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007778Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007779
Barry Warsaw53699e91996-12-10 23:23:01 +00007780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007781posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007782{
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 int fd, fd2, res;
7784 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7785 return NULL;
7786 if (!_PyVerify_fd_dup2(fd, fd2))
7787 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 if (res < 0)
7790 return posix_error();
7791 Py_INCREF(Py_None);
7792 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007793}
7794
Ross Lagerwall7807c352011-03-17 20:20:30 +02007795#ifdef HAVE_LOCKF
7796PyDoc_STRVAR(posix_lockf__doc__,
7797"lockf(fd, cmd, len)\n\n\
7798Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7799fd is an open file descriptor.\n\
7800cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7801F_TEST.\n\
7802len specifies the section of the file to lock.");
7803
7804static PyObject *
7805posix_lockf(PyObject *self, PyObject *args)
7806{
7807 int fd, cmd, res;
7808 off_t len;
7809 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7810 &fd, &cmd, _parse_off_t, &len))
7811 return NULL;
7812
7813 Py_BEGIN_ALLOW_THREADS
7814 res = lockf(fd, cmd, len);
7815 Py_END_ALLOW_THREADS
7816
7817 if (res < 0)
7818 return posix_error();
7819
7820 Py_RETURN_NONE;
7821}
7822#endif
7823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007824
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007825PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007826"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007827Set the current position of a file descriptor.\n\
7828Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007829
Barry Warsaw53699e91996-12-10 23:23:01 +00007830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007831posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007832{
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007834#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007836#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007838#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007839 PyObject *posobj;
7840 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007842#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7844 switch (how) {
7845 case 0: how = SEEK_SET; break;
7846 case 1: how = SEEK_CUR; break;
7847 case 2: how = SEEK_END; break;
7848 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007849#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007850
Ross Lagerwall8e749672011-03-17 21:54:07 +02007851#if !defined(HAVE_LARGEFILE_SUPPORT)
7852 pos = PyLong_AsLong(posobj);
7853#else
7854 pos = PyLong_AsLongLong(posobj);
7855#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 if (PyErr_Occurred())
7857 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007858
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 if (!_PyVerify_fd(fd))
7860 return posix_error();
7861 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007862#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007864#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007866#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 Py_END_ALLOW_THREADS
7868 if (res < 0)
7869 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007870
7871#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007873#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007875#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007876}
7877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007879PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007880"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007881Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007882
Barry Warsaw53699e91996-12-10 23:23:01 +00007883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007884posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007885{
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 int fd, size;
7887 Py_ssize_t n;
7888 PyObject *buffer;
7889 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7890 return NULL;
7891 if (size < 0) {
7892 errno = EINVAL;
7893 return posix_error();
7894 }
7895 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7896 if (buffer == NULL)
7897 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007898 if (!_PyVerify_fd(fd)) {
7899 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007901 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 Py_BEGIN_ALLOW_THREADS
7903 n = read(fd, PyBytes_AS_STRING(buffer), size);
7904 Py_END_ALLOW_THREADS
7905 if (n < 0) {
7906 Py_DECREF(buffer);
7907 return posix_error();
7908 }
7909 if (n != size)
7910 _PyBytes_Resize(&buffer, n);
7911 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007912}
7913
Ross Lagerwall7807c352011-03-17 20:20:30 +02007914#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7915 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007916static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007917iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7918{
7919 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007920 Py_ssize_t blen, total = 0;
7921
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007922 *iov = PyMem_New(struct iovec, cnt);
7923 if (*iov == NULL) {
7924 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007925 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007926 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007927
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007928 *buf = PyMem_New(Py_buffer, cnt);
7929 if (*buf == NULL) {
7930 PyMem_Del(*iov);
7931 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007932 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007933 }
7934
7935 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007936 PyObject *item = PySequence_GetItem(seq, i);
7937 if (item == NULL)
7938 goto fail;
7939 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7940 Py_DECREF(item);
7941 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007942 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007943 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007944 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007945 blen = (*buf)[i].len;
7946 (*iov)[i].iov_len = blen;
7947 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007948 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007949 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007950
7951fail:
7952 PyMem_Del(*iov);
7953 for (j = 0; j < i; j++) {
7954 PyBuffer_Release(&(*buf)[j]);
7955 }
7956 PyMem_Del(*buf);
7957 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007958}
7959
7960static void
7961iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7962{
7963 int i;
7964 PyMem_Del(iov);
7965 for (i = 0; i < cnt; i++) {
7966 PyBuffer_Release(&buf[i]);
7967 }
7968 PyMem_Del(buf);
7969}
7970#endif
7971
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972#ifdef HAVE_READV
7973PyDoc_STRVAR(posix_readv__doc__,
7974"readv(fd, buffers) -> bytesread\n\n\
7975Read from a file descriptor into a number of writable buffers. buffers\n\
7976is an arbitrary sequence of writable buffers.\n\
7977Returns the total number of bytes read.");
7978
7979static PyObject *
7980posix_readv(PyObject *self, PyObject *args)
7981{
7982 int fd, cnt;
7983 Py_ssize_t n;
7984 PyObject *seq;
7985 struct iovec *iov;
7986 Py_buffer *buf;
7987
7988 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7989 return NULL;
7990 if (!PySequence_Check(seq)) {
7991 PyErr_SetString(PyExc_TypeError,
7992 "readv() arg 2 must be a sequence");
7993 return NULL;
7994 }
7995 cnt = PySequence_Size(seq);
7996
7997 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7998 return NULL;
7999
8000 Py_BEGIN_ALLOW_THREADS
8001 n = readv(fd, iov, cnt);
8002 Py_END_ALLOW_THREADS
8003
8004 iov_cleanup(iov, buf, cnt);
8005 return PyLong_FromSsize_t(n);
8006}
8007#endif
8008
8009#ifdef HAVE_PREAD
8010PyDoc_STRVAR(posix_pread__doc__,
8011"pread(fd, buffersize, offset) -> string\n\n\
8012Read from a file descriptor, fd, at a position of offset. It will read up\n\
8013to buffersize number of bytes. The file offset remains unchanged.");
8014
8015static PyObject *
8016posix_pread(PyObject *self, PyObject *args)
8017{
8018 int fd, size;
8019 off_t offset;
8020 Py_ssize_t n;
8021 PyObject *buffer;
8022 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8023 return NULL;
8024
8025 if (size < 0) {
8026 errno = EINVAL;
8027 return posix_error();
8028 }
8029 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8030 if (buffer == NULL)
8031 return NULL;
8032 if (!_PyVerify_fd(fd)) {
8033 Py_DECREF(buffer);
8034 return posix_error();
8035 }
8036 Py_BEGIN_ALLOW_THREADS
8037 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8038 Py_END_ALLOW_THREADS
8039 if (n < 0) {
8040 Py_DECREF(buffer);
8041 return posix_error();
8042 }
8043 if (n != size)
8044 _PyBytes_Resize(&buffer, n);
8045 return buffer;
8046}
8047#endif
8048
8049PyDoc_STRVAR(posix_write__doc__,
8050"write(fd, string) -> byteswritten\n\n\
8051Write a string to a file descriptor.");
8052
8053static PyObject *
8054posix_write(PyObject *self, PyObject *args)
8055{
8056 Py_buffer pbuf;
8057 int fd;
8058 Py_ssize_t size, len;
8059
8060 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8061 return NULL;
8062 if (!_PyVerify_fd(fd)) {
8063 PyBuffer_Release(&pbuf);
8064 return posix_error();
8065 }
8066 len = pbuf.len;
8067 Py_BEGIN_ALLOW_THREADS
8068#if defined(MS_WIN64) || defined(MS_WINDOWS)
8069 if (len > INT_MAX)
8070 len = INT_MAX;
8071 size = write(fd, pbuf.buf, (int)len);
8072#else
8073 size = write(fd, pbuf.buf, len);
8074#endif
8075 Py_END_ALLOW_THREADS
8076 PyBuffer_Release(&pbuf);
8077 if (size < 0)
8078 return posix_error();
8079 return PyLong_FromSsize_t(size);
8080}
8081
8082#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008083PyDoc_STRVAR(posix_sendfile__doc__,
8084"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8085sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8086 -> byteswritten\n\
8087Copy nbytes bytes from file descriptor in to file descriptor out.");
8088
8089static PyObject *
8090posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8091{
8092 int in, out;
8093 Py_ssize_t ret;
8094 off_t offset;
8095
8096#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8097#ifndef __APPLE__
8098 Py_ssize_t len;
8099#endif
8100 PyObject *headers = NULL, *trailers = NULL;
8101 Py_buffer *hbuf, *tbuf;
8102 off_t sbytes;
8103 struct sf_hdtr sf;
8104 int flags = 0;
8105 sf.headers = NULL;
8106 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008107 static char *keywords[] = {"out", "in",
8108 "offset", "count",
8109 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110
8111#ifdef __APPLE__
8112 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008113 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008114#else
8115 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008116 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008117#endif
8118 &headers, &trailers, &flags))
8119 return NULL;
8120 if (headers != NULL) {
8121 if (!PySequence_Check(headers)) {
8122 PyErr_SetString(PyExc_TypeError,
8123 "sendfile() headers must be a sequence or None");
8124 return NULL;
8125 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008126 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008127 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008128 if (sf.hdr_cnt > 0 &&
8129 !(i = iov_setup(&(sf.headers), &hbuf,
8130 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008131 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008132#ifdef __APPLE__
8133 sbytes += i;
8134#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008135 }
8136 }
8137 if (trailers != NULL) {
8138 if (!PySequence_Check(trailers)) {
8139 PyErr_SetString(PyExc_TypeError,
8140 "sendfile() trailers must be a sequence or None");
8141 return NULL;
8142 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008143 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008145 if (sf.trl_cnt > 0 &&
8146 !(i = iov_setup(&(sf.trailers), &tbuf,
8147 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008148 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008149#ifdef __APPLE__
8150 sbytes += i;
8151#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008152 }
8153 }
8154
8155 Py_BEGIN_ALLOW_THREADS
8156#ifdef __APPLE__
8157 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8158#else
8159 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8160#endif
8161 Py_END_ALLOW_THREADS
8162
8163 if (sf.headers != NULL)
8164 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8165 if (sf.trailers != NULL)
8166 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8167
8168 if (ret < 0) {
8169 if ((errno == EAGAIN) || (errno == EBUSY)) {
8170 if (sbytes != 0) {
8171 // some data has been sent
8172 goto done;
8173 }
8174 else {
8175 // no data has been sent; upper application is supposed
8176 // to retry on EAGAIN or EBUSY
8177 return posix_error();
8178 }
8179 }
8180 return posix_error();
8181 }
8182 goto done;
8183
8184done:
8185 #if !defined(HAVE_LARGEFILE_SUPPORT)
8186 return Py_BuildValue("l", sbytes);
8187 #else
8188 return Py_BuildValue("L", sbytes);
8189 #endif
8190
8191#else
8192 Py_ssize_t count;
8193 PyObject *offobj;
8194 static char *keywords[] = {"out", "in",
8195 "offset", "count", NULL};
8196 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8197 keywords, &out, &in, &offobj, &count))
8198 return NULL;
8199#ifdef linux
8200 if (offobj == Py_None) {
8201 Py_BEGIN_ALLOW_THREADS
8202 ret = sendfile(out, in, NULL, count);
8203 Py_END_ALLOW_THREADS
8204 if (ret < 0)
8205 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008206 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207 }
8208#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008209 if (!_parse_off_t(offobj, &offset))
8210 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008211 Py_BEGIN_ALLOW_THREADS
8212 ret = sendfile(out, in, &offset, count);
8213 Py_END_ALLOW_THREADS
8214 if (ret < 0)
8215 return posix_error();
8216 return Py_BuildValue("n", ret);
8217#endif
8218}
8219#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008221PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008222"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008223Like stat(), but for an open file descriptor.\n\
8224Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008225
Barry Warsaw53699e91996-12-10 23:23:01 +00008226static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008227posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008228{
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 int fd;
8230 STRUCT_STAT st;
8231 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008232 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008234#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 /* on OpenVMS we must ensure that all bytes are written to the file */
8236 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008237#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 if (!_PyVerify_fd(fd))
8239 return posix_error();
8240 Py_BEGIN_ALLOW_THREADS
8241 res = FSTAT(fd, &st);
8242 Py_END_ALLOW_THREADS
8243 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008244#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008246#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008248#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 }
Tim Peters5aa91602002-01-30 05:46:57 +00008250
Victor Stinner4195b5c2012-02-08 23:03:19 +01008251 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008252}
8253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008254PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008255"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008256Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008257connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008258
8259static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008260posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008261{
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 int fd;
8263 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8264 return NULL;
8265 if (!_PyVerify_fd(fd))
8266 return PyBool_FromLong(0);
8267 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008268}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008269
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008270#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008271PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008272"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008273Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008274
Barry Warsaw53699e91996-12-10 23:23:01 +00008275static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008276posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008277{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008278#if defined(PYOS_OS2)
8279 HFILE read, write;
8280 APIRET rc;
8281
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008282 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008283 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008284 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008285
8286 return Py_BuildValue("(ii)", read, write);
8287#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008288#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008289 int fds[2];
8290 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 if (res != 0)
8293 return posix_error();
8294 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008295#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 HANDLE read, write;
8297 int read_fd, write_fd;
8298 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 if (!ok)
8301 return win32_error("CreatePipe", NULL);
8302 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8303 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8304 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008305#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008306#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008307}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008308#endif /* HAVE_PIPE */
8309
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008310#ifdef HAVE_PIPE2
8311PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008312"pipe2(flags) -> (read_end, write_end)\n\n\
8313Create a pipe with flags set atomically.\n\
8314flags can be constructed by ORing together one or more of these values:\n\
8315O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008316");
8317
8318static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008319posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008320{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008321 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008322 int fds[2];
8323 int res;
8324
Charles-François Natali368f34b2011-06-06 19:49:47 +02008325 flags = PyLong_AsLong(arg);
8326 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008327 return NULL;
8328
8329 res = pipe2(fds, flags);
8330 if (res != 0)
8331 return posix_error();
8332 return Py_BuildValue("(ii)", fds[0], fds[1]);
8333}
8334#endif /* HAVE_PIPE2 */
8335
Ross Lagerwall7807c352011-03-17 20:20:30 +02008336#ifdef HAVE_WRITEV
8337PyDoc_STRVAR(posix_writev__doc__,
8338"writev(fd, buffers) -> byteswritten\n\n\
8339Write the contents of buffers to a file descriptor, where buffers is an\n\
8340arbitrary sequence of buffers.\n\
8341Returns the total bytes written.");
8342
8343static PyObject *
8344posix_writev(PyObject *self, PyObject *args)
8345{
8346 int fd, cnt;
8347 Py_ssize_t res;
8348 PyObject *seq;
8349 struct iovec *iov;
8350 Py_buffer *buf;
8351 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8352 return NULL;
8353 if (!PySequence_Check(seq)) {
8354 PyErr_SetString(PyExc_TypeError,
8355 "writev() arg 2 must be a sequence");
8356 return NULL;
8357 }
8358 cnt = PySequence_Size(seq);
8359
8360 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8361 return NULL;
8362 }
8363
8364 Py_BEGIN_ALLOW_THREADS
8365 res = writev(fd, iov, cnt);
8366 Py_END_ALLOW_THREADS
8367
8368 iov_cleanup(iov, buf, cnt);
8369 return PyLong_FromSsize_t(res);
8370}
8371#endif
8372
8373#ifdef HAVE_PWRITE
8374PyDoc_STRVAR(posix_pwrite__doc__,
8375"pwrite(fd, string, offset) -> byteswritten\n\n\
8376Write string to a file descriptor, fd, from offset, leaving the file\n\
8377offset unchanged.");
8378
8379static PyObject *
8380posix_pwrite(PyObject *self, PyObject *args)
8381{
8382 Py_buffer pbuf;
8383 int fd;
8384 off_t offset;
8385 Py_ssize_t size;
8386
8387 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8388 return NULL;
8389
8390 if (!_PyVerify_fd(fd)) {
8391 PyBuffer_Release(&pbuf);
8392 return posix_error();
8393 }
8394 Py_BEGIN_ALLOW_THREADS
8395 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8396 Py_END_ALLOW_THREADS
8397 PyBuffer_Release(&pbuf);
8398 if (size < 0)
8399 return posix_error();
8400 return PyLong_FromSsize_t(size);
8401}
8402#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008403
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008404#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008405PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008406"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8407Create a FIFO (a POSIX named pipe).\n\
8408\n\
8409If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8410 and path should be relative; path will then be relative to that directory.\n\
8411dir_fd may not be implemented on your platform.\n\
8412 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008413
Barry Warsaw53699e91996-12-10 23:23:01 +00008414static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008415posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008416{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008417 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008419 int dir_fd = DEFAULT_DIR_FD;
8420 int result;
8421 PyObject *return_value = NULL;
8422 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8423
8424 memset(&path, 0, sizeof(path));
8425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8426 path_converter, &path,
8427 &mode,
8428#ifdef HAVE_MKFIFOAT
8429 dir_fd_converter, &dir_fd
8430#else
8431 dir_fd_unavailable, &dir_fd
8432#endif
8433 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008435
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008437#ifdef HAVE_MKFIFOAT
8438 if (dir_fd != DEFAULT_DIR_FD)
8439 result = mkfifoat(dir_fd, path.narrow, mode);
8440 else
8441#endif
8442 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008444
8445 if (result < 0) {
8446 return_value = posix_error();
8447 goto exit;
8448 }
8449
8450 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008452
8453exit:
8454 path_cleanup(&path);
8455 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008456}
8457#endif
8458
Neal Norwitz11690112002-07-30 01:08:28 +00008459#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008460PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008461"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008462Create a filesystem node (file, device special file or named pipe)\n\
8463named filename. mode specifies both the permissions to use and the\n\
8464type of node to be created, being combined (bitwise OR) with one of\n\
8465S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008466device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008467os.makedev()), otherwise it is ignored.\n\
8468\n\
8469If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8470 and path should be relative; path will then be relative to that directory.\n\
8471dir_fd may not be implemented on your platform.\n\
8472 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008473
8474
8475static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008476posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008477{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008478 path_t path;
8479 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008480 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008481 int dir_fd = DEFAULT_DIR_FD;
8482 int result;
8483 PyObject *return_value = NULL;
8484 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8485
8486 memset(&path, 0, sizeof(path));
8487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8488 path_converter, &path,
8489 &mode, &device,
8490#ifdef HAVE_MKNODAT
8491 dir_fd_converter, &dir_fd
8492#else
8493 dir_fd_unavailable, &dir_fd
8494#endif
8495 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008497
Victor Stinner8c62be82010-05-06 00:08:46 +00008498 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008499#ifdef HAVE_MKNODAT
8500 if (dir_fd != DEFAULT_DIR_FD)
8501 result = mknodat(dir_fd, path.narrow, mode, device);
8502 else
8503#endif
8504 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008506
8507 if (result < 0) {
8508 return_value = posix_error();
8509 goto exit;
8510 }
8511
8512 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008514
Larry Hastings9cf065c2012-06-22 16:30:09 -07008515exit:
8516 path_cleanup(&path);
8517 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008518}
8519#endif
8520
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008521#ifdef HAVE_DEVICE_MACROS
8522PyDoc_STRVAR(posix_major__doc__,
8523"major(device) -> major number\n\
8524Extracts a device major number from a raw device number.");
8525
8526static PyObject *
8527posix_major(PyObject *self, PyObject *args)
8528{
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 int device;
8530 if (!PyArg_ParseTuple(args, "i:major", &device))
8531 return NULL;
8532 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008533}
8534
8535PyDoc_STRVAR(posix_minor__doc__,
8536"minor(device) -> minor number\n\
8537Extracts a device minor number from a raw device number.");
8538
8539static PyObject *
8540posix_minor(PyObject *self, PyObject *args)
8541{
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 int device;
8543 if (!PyArg_ParseTuple(args, "i:minor", &device))
8544 return NULL;
8545 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008546}
8547
8548PyDoc_STRVAR(posix_makedev__doc__,
8549"makedev(major, minor) -> device number\n\
8550Composes a raw device number from the major and minor device numbers.");
8551
8552static PyObject *
8553posix_makedev(PyObject *self, PyObject *args)
8554{
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 int major, minor;
8556 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8557 return NULL;
8558 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008559}
8560#endif /* device macros */
8561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008562
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008563#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008564PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008565"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008566Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008567
Barry Warsaw53699e91996-12-10 23:23:01 +00008568static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008569posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008570{
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 int fd;
8572 off_t length;
8573 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008574
Ross Lagerwall7807c352011-03-17 20:20:30 +02008575 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008577
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 Py_BEGIN_ALLOW_THREADS
8579 res = ftruncate(fd, length);
8580 Py_END_ALLOW_THREADS
8581 if (res < 0)
8582 return posix_error();
8583 Py_INCREF(Py_None);
8584 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008585}
8586#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008587
Ross Lagerwall7807c352011-03-17 20:20:30 +02008588#ifdef HAVE_TRUNCATE
8589PyDoc_STRVAR(posix_truncate__doc__,
8590"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008591Truncate the file given by path to length bytes.\n\
8592On some platforms, path may also be specified as an open file descriptor.\n\
8593 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594
8595static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008596posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597{
Georg Brandl306336b2012-06-24 12:55:33 +02008598 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008599 off_t length;
8600 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008601 PyObject *result = NULL;
8602 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008603
Georg Brandl306336b2012-06-24 12:55:33 +02008604 memset(&path, 0, sizeof(path));
8605#ifdef HAVE_FTRUNCATE
8606 path.allow_fd = 1;
8607#endif
8608 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8609 path_converter, &path,
8610 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008611 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008612
8613 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008614#ifdef HAVE_FTRUNCATE
8615 if (path.fd != -1)
8616 res = ftruncate(path.fd, length);
8617 else
8618#endif
8619 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008620 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008621 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008622 result = path_posix_error("truncate", &path);
8623 else {
8624 Py_INCREF(Py_None);
8625 result = Py_None;
8626 }
8627 path_cleanup(&path);
8628 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008629}
8630#endif
8631
8632#ifdef HAVE_POSIX_FALLOCATE
8633PyDoc_STRVAR(posix_posix_fallocate__doc__,
8634"posix_fallocate(fd, offset, len)\n\n\
8635Ensures that enough disk space is allocated for the file specified by fd\n\
8636starting from offset and continuing for len bytes.");
8637
8638static PyObject *
8639posix_posix_fallocate(PyObject *self, PyObject *args)
8640{
8641 off_t len, offset;
8642 int res, fd;
8643
8644 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8645 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8646 return NULL;
8647
8648 Py_BEGIN_ALLOW_THREADS
8649 res = posix_fallocate(fd, offset, len);
8650 Py_END_ALLOW_THREADS
8651 if (res != 0) {
8652 errno = res;
8653 return posix_error();
8654 }
8655 Py_RETURN_NONE;
8656}
8657#endif
8658
8659#ifdef HAVE_POSIX_FADVISE
8660PyDoc_STRVAR(posix_posix_fadvise__doc__,
8661"posix_fadvise(fd, offset, len, advice)\n\n\
8662Announces an intention to access data in a specific pattern thus allowing\n\
8663the kernel to make optimizations.\n\
8664The advice applies to the region of the file specified by fd starting at\n\
8665offset and continuing for len bytes.\n\
8666advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8667POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8668POSIX_FADV_DONTNEED.");
8669
8670static PyObject *
8671posix_posix_fadvise(PyObject *self, PyObject *args)
8672{
8673 off_t len, offset;
8674 int res, fd, advice;
8675
8676 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8677 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8678 return NULL;
8679
8680 Py_BEGIN_ALLOW_THREADS
8681 res = posix_fadvise(fd, offset, len, advice);
8682 Py_END_ALLOW_THREADS
8683 if (res != 0) {
8684 errno = res;
8685 return posix_error();
8686 }
8687 Py_RETURN_NONE;
8688}
8689#endif
8690
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008691#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008692PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008693"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008694Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008695
Fred Drake762e2061999-08-26 17:23:54 +00008696/* Save putenv() parameters as values here, so we can collect them when they
8697 * get re-set with another call for the same key. */
8698static PyObject *posix_putenv_garbage;
8699
Tim Peters5aa91602002-01-30 05:46:57 +00008700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008701posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008702{
Victor Stinner84ae1182010-05-06 22:05:07 +00008703 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008704#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008705 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008706 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008707
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008709 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008710 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008712
Victor Stinner65170952011-11-22 22:16:17 +01008713 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008714 if (newstr == NULL) {
8715 PyErr_NoMemory();
8716 goto error;
8717 }
Victor Stinner65170952011-11-22 22:16:17 +01008718 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8719 PyErr_Format(PyExc_ValueError,
8720 "the environment variable is longer than %u characters",
8721 _MAX_ENV);
8722 goto error;
8723 }
8724
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008726 if (newenv == NULL)
8727 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008730 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008732#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008733 PyObject *os1, *os2;
8734 char *s1, *s2;
8735 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008736
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008737 if (!PyArg_ParseTuple(args,
8738 "O&O&:putenv",
8739 PyUnicode_FSConverter, &os1,
8740 PyUnicode_FSConverter, &os2))
8741 return NULL;
8742 s1 = PyBytes_AsString(os1);
8743 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008744
Victor Stinner65170952011-11-22 22:16:17 +01008745 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008746 if (newstr == NULL) {
8747 PyErr_NoMemory();
8748 goto error;
8749 }
8750
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008754 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008756#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008757
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 /* Install the first arg and newstr in posix_putenv_garbage;
8759 * this will cause previous value to be collected. This has to
8760 * happen after the real putenv() call because the old value
8761 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008762 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 /* really not much we can do; just leak */
8764 PyErr_Clear();
8765 }
8766 else {
8767 Py_DECREF(newstr);
8768 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008769
Martin v. Löwis011e8422009-05-05 04:43:17 +00008770#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 Py_DECREF(os1);
8772 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008773#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008774 Py_RETURN_NONE;
8775
8776error:
8777#ifndef MS_WINDOWS
8778 Py_DECREF(os1);
8779 Py_DECREF(os2);
8780#endif
8781 Py_XDECREF(newstr);
8782 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008783}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008784#endif /* putenv */
8785
Guido van Rossumc524d952001-10-19 01:31:59 +00008786#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008787PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008788"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008789Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008790
8791static PyObject *
8792posix_unsetenv(PyObject *self, PyObject *args)
8793{
Victor Stinner65170952011-11-22 22:16:17 +01008794 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008795#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008796 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008797#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008798
8799 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008800
Victor Stinner65170952011-11-22 22:16:17 +01008801 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008802 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008803
Victor Stinner984890f2011-11-24 13:53:38 +01008804#ifdef HAVE_BROKEN_UNSETENV
8805 unsetenv(PyBytes_AS_STRING(name));
8806#else
Victor Stinner65170952011-11-22 22:16:17 +01008807 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008808 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008809 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008810 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008811 }
Victor Stinner984890f2011-11-24 13:53:38 +01008812#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008813
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 /* Remove the key from posix_putenv_garbage;
8815 * this will cause it to be collected. This has to
8816 * happen after the real unsetenv() call because the
8817 * old value was still accessible until then.
8818 */
Victor Stinner65170952011-11-22 22:16:17 +01008819 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 /* really not much we can do; just leak */
8821 PyErr_Clear();
8822 }
Victor Stinner65170952011-11-22 22:16:17 +01008823 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008824 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008825}
8826#endif /* unsetenv */
8827
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008828PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008829"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008830Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008831
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008833posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008834{
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 int code;
8836 char *message;
8837 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8838 return NULL;
8839 message = strerror(code);
8840 if (message == NULL) {
8841 PyErr_SetString(PyExc_ValueError,
8842 "strerror() argument out of range");
8843 return NULL;
8844 }
Victor Stinner1b579672011-12-17 05:47:23 +01008845 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008846}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008847
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008848
Guido van Rossumc9641791998-08-04 15:26:23 +00008849#ifdef HAVE_SYS_WAIT_H
8850
Fred Drake106c1a02002-04-23 15:58:02 +00008851#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008852PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008853"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008854Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008855
8856static PyObject *
8857posix_WCOREDUMP(PyObject *self, PyObject *args)
8858{
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 WAIT_TYPE status;
8860 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008861
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8863 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008864
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008866}
8867#endif /* WCOREDUMP */
8868
8869#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008870PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008871"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008872Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008873job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008874
8875static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008876posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008877{
Victor Stinner8c62be82010-05-06 00:08:46 +00008878 WAIT_TYPE status;
8879 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008880
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8882 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008883
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008885}
8886#endif /* WIFCONTINUED */
8887
Guido van Rossumc9641791998-08-04 15:26:23 +00008888#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008889PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008890"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008891Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008892
8893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008894posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008895{
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 WAIT_TYPE status;
8897 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008898
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8900 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008901
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008903}
8904#endif /* WIFSTOPPED */
8905
8906#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008907PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008908"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008909Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008910
8911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008912posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008913{
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 WAIT_TYPE status;
8915 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008916
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8918 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008919
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008921}
8922#endif /* WIFSIGNALED */
8923
8924#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008925PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008926"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008927Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008928system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008929
8930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008931posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008932{
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 WAIT_TYPE status;
8934 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008935
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8937 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008938
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008940}
8941#endif /* WIFEXITED */
8942
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008943#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008944PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008945"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008946Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008947
8948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008949posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008950{
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 WAIT_TYPE status;
8952 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008953
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8955 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008956
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008958}
8959#endif /* WEXITSTATUS */
8960
8961#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008962PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008963"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008964Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008965value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008966
8967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008968posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008969{
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 WAIT_TYPE status;
8971 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008972
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8974 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008975
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008977}
8978#endif /* WTERMSIG */
8979
8980#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008981PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008982"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008983Return the signal that stopped the process that provided\n\
8984the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008985
8986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008987posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008988{
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 WAIT_TYPE status;
8990 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008991
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8993 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008994
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008996}
8997#endif /* WSTOPSIG */
8998
8999#endif /* HAVE_SYS_WAIT_H */
9000
9001
Thomas Wouters477c8d52006-05-27 19:21:47 +00009002#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009003#ifdef _SCO_DS
9004/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9005 needed definitions in sys/statvfs.h */
9006#define _SVID3
9007#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009008#include <sys/statvfs.h>
9009
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009010static PyObject*
9011_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9013 if (v == NULL)
9014 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009015
9016#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9018 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9019 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9020 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9021 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9022 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9023 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9024 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9025 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9026 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009027#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9029 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9030 PyStructSequence_SET_ITEM(v, 2,
9031 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9032 PyStructSequence_SET_ITEM(v, 3,
9033 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9034 PyStructSequence_SET_ITEM(v, 4,
9035 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9036 PyStructSequence_SET_ITEM(v, 5,
9037 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9038 PyStructSequence_SET_ITEM(v, 6,
9039 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9040 PyStructSequence_SET_ITEM(v, 7,
9041 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9042 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9043 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009044#endif
9045
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009047}
9048
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009049PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009050"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009051Perform an fstatvfs system call on the given fd.\n\
9052Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009053
9054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009055posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009056{
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 int fd, res;
9058 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009059
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9061 return NULL;
9062 Py_BEGIN_ALLOW_THREADS
9063 res = fstatvfs(fd, &st);
9064 Py_END_ALLOW_THREADS
9065 if (res != 0)
9066 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009067
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009069}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009070#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009071
9072
Thomas Wouters477c8d52006-05-27 19:21:47 +00009073#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009074#include <sys/statvfs.h>
9075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009076PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009077"statvfs(path)\n\n\
9078Perform a statvfs system call on the given path.\n\
9079\n\
9080path may always be specified as a string.\n\
9081On some platforms, path may also be specified as an open file descriptor.\n\
9082 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009083
9084static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009085posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009086{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009087 static char *keywords[] = {"path", NULL};
9088 path_t path;
9089 int result;
9090 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009092
Larry Hastings9cf065c2012-06-22 16:30:09 -07009093 memset(&path, 0, sizeof(path));
9094#ifdef HAVE_FSTATVFS
9095 path.allow_fd = 1;
9096#endif
9097 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9098 path_converter, &path
9099 ))
9100 return NULL;
9101
9102 Py_BEGIN_ALLOW_THREADS
9103#ifdef HAVE_FSTATVFS
9104 if (path.fd != -1) {
9105#ifdef __APPLE__
9106 /* handle weak-linking on Mac OS X 10.3 */
9107 if (fstatvfs == NULL) {
9108 fd_specified("statvfs", path.fd);
9109 goto exit;
9110 }
9111#endif
9112 result = fstatvfs(path.fd, &st);
9113 }
9114 else
9115#endif
9116 result = statvfs(path.narrow, &st);
9117 Py_END_ALLOW_THREADS
9118
9119 if (result) {
9120 return_value = path_posix_error("statvfs", &path);
9121 goto exit;
9122 }
9123
9124 return_value = _pystatvfs_fromstructstatvfs(st);
9125
9126exit:
9127 path_cleanup(&path);
9128 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009129}
9130#endif /* HAVE_STATVFS */
9131
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009132#ifdef MS_WINDOWS
9133PyDoc_STRVAR(win32__getdiskusage__doc__,
9134"_getdiskusage(path) -> (total, free)\n\n\
9135Return disk usage statistics about the given path as (total, free) tuple.");
9136
9137static PyObject *
9138win32__getdiskusage(PyObject *self, PyObject *args)
9139{
9140 BOOL retval;
9141 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009142 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009143
Victor Stinner6139c1b2011-11-09 22:14:14 +01009144 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009145 return NULL;
9146
9147 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009148 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009149 Py_END_ALLOW_THREADS
9150 if (retval == 0)
9151 return PyErr_SetFromWindowsErr(0);
9152
9153 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9154}
9155#endif
9156
9157
Fred Drakec9680921999-12-13 16:37:25 +00009158/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9159 * It maps strings representing configuration variable names to
9160 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009161 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009162 * rarely-used constants. There are three separate tables that use
9163 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009164 *
9165 * This code is always included, even if none of the interfaces that
9166 * need it are included. The #if hackery needed to avoid it would be
9167 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009168 */
9169struct constdef {
9170 char *name;
9171 long value;
9172};
9173
Fred Drake12c6e2d1999-12-14 21:25:03 +00009174static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009175conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009176 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009177{
Christian Heimes217cfd12007-12-02 14:31:20 +00009178 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009179 *valuep = PyLong_AS_LONG(arg);
9180 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009181 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009182 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009183 /* look up the value in the table using a binary search */
9184 size_t lo = 0;
9185 size_t mid;
9186 size_t hi = tablesize;
9187 int cmp;
9188 const char *confname;
9189 if (!PyUnicode_Check(arg)) {
9190 PyErr_SetString(PyExc_TypeError,
9191 "configuration names must be strings or integers");
9192 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009194 confname = _PyUnicode_AsString(arg);
9195 if (confname == NULL)
9196 return 0;
9197 while (lo < hi) {
9198 mid = (lo + hi) / 2;
9199 cmp = strcmp(confname, table[mid].name);
9200 if (cmp < 0)
9201 hi = mid;
9202 else if (cmp > 0)
9203 lo = mid + 1;
9204 else {
9205 *valuep = table[mid].value;
9206 return 1;
9207 }
9208 }
9209 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9210 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009211 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009212}
9213
9214
9215#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9216static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009217#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009219#endif
9220#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009222#endif
Fred Drakec9680921999-12-13 16:37:25 +00009223#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009225#endif
9226#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009228#endif
9229#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009231#endif
9232#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
9235#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
9238#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009240#endif
9241#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
9244#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009246#endif
9247#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009249#endif
9250#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
9253#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009255#endif
9256#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009268#ifdef _PC_ACL_ENABLED
9269 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9270#endif
9271#ifdef _PC_MIN_HOLE_SIZE
9272 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9273#endif
9274#ifdef _PC_ALLOC_SIZE_MIN
9275 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9276#endif
9277#ifdef _PC_REC_INCR_XFER_SIZE
9278 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9279#endif
9280#ifdef _PC_REC_MAX_XFER_SIZE
9281 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9282#endif
9283#ifdef _PC_REC_MIN_XFER_SIZE
9284 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9285#endif
9286#ifdef _PC_REC_XFER_ALIGN
9287 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9288#endif
9289#ifdef _PC_SYMLINK_MAX
9290 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9291#endif
9292#ifdef _PC_XATTR_ENABLED
9293 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9294#endif
9295#ifdef _PC_XATTR_EXISTS
9296 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9297#endif
9298#ifdef _PC_TIMESTAMP_RESOLUTION
9299 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9300#endif
Fred Drakec9680921999-12-13 16:37:25 +00009301};
9302
Fred Drakec9680921999-12-13 16:37:25 +00009303static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009304conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009305{
9306 return conv_confname(arg, valuep, posix_constants_pathconf,
9307 sizeof(posix_constants_pathconf)
9308 / sizeof(struct constdef));
9309}
9310#endif
9311
9312#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009313PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009314"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009315Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009316If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009317
9318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009319posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009320{
9321 PyObject *result = NULL;
9322 int name, fd;
9323
Fred Drake12c6e2d1999-12-14 21:25:03 +00009324 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9325 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009326 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009327
Stefan Krah0e803b32010-11-26 16:16:47 +00009328 errno = 0;
9329 limit = fpathconf(fd, name);
9330 if (limit == -1 && errno != 0)
9331 posix_error();
9332 else
9333 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009334 }
9335 return result;
9336}
9337#endif
9338
9339
9340#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009341PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009342"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009343Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009344If there is no limit, return -1.\n\
9345On some platforms, path may also be specified as an open file descriptor.\n\
9346 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009347
9348static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009349posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009350{
Georg Brandl306336b2012-06-24 12:55:33 +02009351 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009352 PyObject *result = NULL;
9353 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009354 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009355
Georg Brandl306336b2012-06-24 12:55:33 +02009356 memset(&path, 0, sizeof(path));
9357#ifdef HAVE_FPATHCONF
9358 path.allow_fd = 1;
9359#endif
9360 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9361 path_converter, &path,
9362 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009364
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009366#ifdef HAVE_FPATHCONF
9367 if (path.fd != -1)
9368 limit = fpathconf(path.fd, name);
9369 else
9370#endif
9371 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 if (limit == -1 && errno != 0) {
9373 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009374 /* could be a path or name problem */
9375 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009376 else
Georg Brandl306336b2012-06-24 12:55:33 +02009377 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 }
9379 else
9380 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009381 }
Georg Brandl306336b2012-06-24 12:55:33 +02009382 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009383 return result;
9384}
9385#endif
9386
9387#ifdef HAVE_CONFSTR
9388static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009389#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009391#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009392#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009394#endif
9395#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009397#endif
Fred Draked86ed291999-12-15 15:34:33 +00009398#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009400#endif
9401#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009403#endif
9404#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009406#endif
9407#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009409#endif
Fred Drakec9680921999-12-13 16:37:25 +00009410#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009412#endif
9413#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009415#endif
9416#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009418#endif
9419#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
9422#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009424#endif
9425#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009427#endif
9428#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009430#endif
9431#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009433#endif
Fred Draked86ed291999-12-15 15:34:33 +00009434#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009436#endif
Fred Drakec9680921999-12-13 16:37:25 +00009437#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
Fred Draked86ed291999-12-15 15:34:33 +00009440#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009442#endif
9443#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009445#endif
9446#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009448#endif
9449#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009451#endif
Fred Drakec9680921999-12-13 16:37:25 +00009452#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
9476#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
9479#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009481#endif
9482#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009484#endif
9485#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009487#endif
9488#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009490#endif
9491#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
Fred Draked86ed291999-12-15 15:34:33 +00009500#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009502#endif
9503#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009505#endif
9506#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009508#endif
9509#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009511#endif
9512#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009514#endif
9515#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009517#endif
9518#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009520#endif
9521#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009523#endif
9524#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
9527#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009529#endif
9530#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
9536#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
Fred Drakec9680921999-12-13 16:37:25 +00009539};
9540
9541static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009542conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009543{
9544 return conv_confname(arg, valuep, posix_constants_confstr,
9545 sizeof(posix_constants_confstr)
9546 / sizeof(struct constdef));
9547}
9548
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009549PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009550"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009551Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009552
9553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009554posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009555{
9556 PyObject *result = NULL;
9557 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009558 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009559 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009560
Victor Stinnercb043522010-09-10 23:49:04 +00009561 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9562 return NULL;
9563
9564 errno = 0;
9565 len = confstr(name, buffer, sizeof(buffer));
9566 if (len == 0) {
9567 if (errno) {
9568 posix_error();
9569 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009570 }
9571 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009572 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009573 }
9574 }
Victor Stinnercb043522010-09-10 23:49:04 +00009575
9576 if ((unsigned int)len >= sizeof(buffer)) {
9577 char *buf = PyMem_Malloc(len);
9578 if (buf == NULL)
9579 return PyErr_NoMemory();
9580 confstr(name, buf, len);
9581 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9582 PyMem_Free(buf);
9583 }
9584 else
9585 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009586 return result;
9587}
9588#endif
9589
9590
9591#ifdef HAVE_SYSCONF
9592static struct constdef posix_constants_sysconf[] = {
9593#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
Fred Draked86ed291999-12-15 15:34:33 +00009623#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009625#endif
9626#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009628#endif
Fred Drakec9680921999-12-13 16:37:25 +00009629#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
Fred Drakec9680921999-12-13 16:37:25 +00009632#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
Fred Draked86ed291999-12-15 15:34:33 +00009647#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009649#endif
Fred Drakec9680921999-12-13 16:37:25 +00009650#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
9659#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
9662#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
Fred Draked86ed291999-12-15 15:34:33 +00009665#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
Fred Drakec9680921999-12-13 16:37:25 +00009668#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
Fred Draked86ed291999-12-15 15:34:33 +00009737#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009739#endif
Fred Drakec9680921999-12-13 16:37:25 +00009740#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
Fred Draked86ed291999-12-15 15:34:33 +00009749#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
Fred Drakec9680921999-12-13 16:37:25 +00009752#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
Fred Draked86ed291999-12-15 15:34:33 +00009755#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
Fred Draked86ed291999-12-15 15:34:33 +00009773#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009775#endif
Fred Drakec9680921999-12-13 16:37:25 +00009776#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
Fred Draked86ed291999-12-15 15:34:33 +00009797#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
Fred Draked86ed291999-12-15 15:34:33 +00009806#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009808#endif
Fred Drakec9680921999-12-13 16:37:25 +00009809#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
Fred Draked86ed291999-12-15 15:34:33 +00009836#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
Fred Drakec9680921999-12-13 16:37:25 +00009842#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
Fred Draked86ed291999-12-15 15:34:33 +00009947#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009949#endif
Fred Drakec9680921999-12-13 16:37:25 +00009950#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085};
10086
10087static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010088conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010089{
10090 return conv_confname(arg, valuep, posix_constants_sysconf,
10091 sizeof(posix_constants_sysconf)
10092 / sizeof(struct constdef));
10093}
10094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010095PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010096"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010097Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010098
10099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010100posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010101{
10102 PyObject *result = NULL;
10103 int name;
10104
10105 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10106 int value;
10107
10108 errno = 0;
10109 value = sysconf(name);
10110 if (value == -1 && errno != 0)
10111 posix_error();
10112 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010113 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010114 }
10115 return result;
10116}
10117#endif
10118
10119
Fred Drakebec628d1999-12-15 18:31:10 +000010120/* This code is used to ensure that the tables of configuration value names
10121 * are in sorted order as required by conv_confname(), and also to build the
10122 * the exported dictionaries that are used to publish information about the
10123 * names available on the host platform.
10124 *
10125 * Sorting the table at runtime ensures that the table is properly ordered
10126 * when used, even for platforms we're not able to test on. It also makes
10127 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010128 */
Fred Drakebec628d1999-12-15 18:31:10 +000010129
10130static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010131cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010132{
10133 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010135 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010137
10138 return strcmp(c1->name, c2->name);
10139}
10140
10141static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010142setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010144{
Fred Drakebec628d1999-12-15 18:31:10 +000010145 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010146 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010147
10148 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10149 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010150 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010152
Barry Warsaw3155db32000-04-13 15:20:40 +000010153 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 PyObject *o = PyLong_FromLong(table[i].value);
10155 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10156 Py_XDECREF(o);
10157 Py_DECREF(d);
10158 return -1;
10159 }
10160 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010161 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010162 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010163}
10164
Fred Drakebec628d1999-12-15 18:31:10 +000010165/* Return -1 on failure, 0 on success. */
10166static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010167setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010168{
10169#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010170 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010171 sizeof(posix_constants_pathconf)
10172 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010173 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010174 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010175#endif
10176#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010177 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010178 sizeof(posix_constants_confstr)
10179 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010180 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010181 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010182#endif
10183#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010184 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010185 sizeof(posix_constants_sysconf)
10186 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010187 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010188 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010189#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010190 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010191}
Fred Draked86ed291999-12-15 15:34:33 +000010192
10193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010194PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010195"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010196Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010197in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010198
10199static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010200posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010201{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010202 abort();
10203 /*NOTREACHED*/
10204 Py_FatalError("abort() called from Python code didn't abort!");
10205 return NULL;
10206}
Fred Drakebec628d1999-12-15 18:31:10 +000010207
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010208#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010209PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010210"startfile(filepath [, operation]) - Start a file with its associated\n\
10211application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010212\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010213When \"operation\" is not specified or \"open\", this acts like\n\
10214double-clicking the file in Explorer, or giving the file name as an\n\
10215argument to the DOS \"start\" command: the file is opened with whatever\n\
10216application (if any) its extension is associated.\n\
10217When another \"operation\" is given, it specifies what should be done with\n\
10218the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010219\n\
10220startfile returns as soon as the associated application is launched.\n\
10221There is no option to wait for the application to close, and no way\n\
10222to retrieve the application's exit status.\n\
10223\n\
10224The filepath is relative to the current directory. If you want to use\n\
10225an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010226the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010227
10228static PyObject *
10229win32_startfile(PyObject *self, PyObject *args)
10230{
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 PyObject *ofilepath;
10232 char *filepath;
10233 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010234 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010236
Victor Stinnereb5657a2011-09-30 01:44:27 +020010237 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 if (!PyArg_ParseTuple(args, "U|s:startfile",
10239 &unipath, &operation)) {
10240 PyErr_Clear();
10241 goto normal;
10242 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010243
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010245 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010247 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 PyErr_Clear();
10249 operation = NULL;
10250 goto normal;
10251 }
10252 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010253
Victor Stinnereb5657a2011-09-30 01:44:27 +020010254 wpath = PyUnicode_AsUnicode(unipath);
10255 if (wpath == NULL)
10256 goto normal;
10257 if (uoperation) {
10258 woperation = PyUnicode_AsUnicode(uoperation);
10259 if (woperation == NULL)
10260 goto normal;
10261 }
10262 else
10263 woperation = NULL;
10264
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010266 rc = ShellExecuteW((HWND)0, woperation, wpath,
10267 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 Py_END_ALLOW_THREADS
10269
Victor Stinnereb5657a2011-09-30 01:44:27 +020010270 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010272 win32_error_object("startfile", unipath);
10273 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 }
10275 Py_INCREF(Py_None);
10276 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010277
10278normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10280 PyUnicode_FSConverter, &ofilepath,
10281 &operation))
10282 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010283 if (win32_warn_bytes_api()) {
10284 Py_DECREF(ofilepath);
10285 return NULL;
10286 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 filepath = PyBytes_AsString(ofilepath);
10288 Py_BEGIN_ALLOW_THREADS
10289 rc = ShellExecute((HWND)0, operation, filepath,
10290 NULL, NULL, SW_SHOWNORMAL);
10291 Py_END_ALLOW_THREADS
10292 if (rc <= (HINSTANCE)32) {
10293 PyObject *errval = win32_error("startfile", filepath);
10294 Py_DECREF(ofilepath);
10295 return errval;
10296 }
10297 Py_DECREF(ofilepath);
10298 Py_INCREF(Py_None);
10299 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010300}
10301#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010302
Martin v. Löwis438b5342002-12-27 10:16:42 +000010303#ifdef HAVE_GETLOADAVG
10304PyDoc_STRVAR(posix_getloadavg__doc__,
10305"getloadavg() -> (float, float, float)\n\n\
10306Return the number of processes in the system run queue averaged over\n\
10307the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10308was unobtainable");
10309
10310static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010311posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010312{
10313 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010314 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010315 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10316 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010317 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010318 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010319}
10320#endif
10321
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010322PyDoc_STRVAR(device_encoding__doc__,
10323"device_encoding(fd) -> str\n\n\
10324Return a string describing the encoding of the device\n\
10325if the output is a terminal; else return None.");
10326
10327static PyObject *
10328device_encoding(PyObject *self, PyObject *args)
10329{
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010331
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10333 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010334
10335 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010336}
10337
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010338#ifdef __VMS
10339/* Use openssl random routine */
10340#include <openssl/rand.h>
10341PyDoc_STRVAR(vms_urandom__doc__,
10342"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +000010343Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010344
10345static PyObject*
10346vms_urandom(PyObject *self, PyObject *args)
10347{
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 int howMany;
10349 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010350
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 /* Read arguments */
10352 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10353 return NULL;
10354 if (howMany < 0)
10355 return PyErr_Format(PyExc_ValueError,
10356 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010357
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 /* Allocate bytes */
10359 result = PyBytes_FromStringAndSize(NULL, howMany);
10360 if (result != NULL) {
10361 /* Get random data */
10362 if (RAND_pseudo_bytes((unsigned char*)
10363 PyBytes_AS_STRING(result),
10364 howMany) < 0) {
10365 Py_DECREF(result);
10366 return PyErr_Format(PyExc_ValueError,
10367 "RAND_pseudo_bytes");
10368 }
10369 }
10370 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010371}
10372#endif
10373
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010374#ifdef HAVE_SETRESUID
10375PyDoc_STRVAR(posix_setresuid__doc__,
10376"setresuid(ruid, euid, suid)\n\n\
10377Set the current process's real, effective, and saved user ids.");
10378
10379static PyObject*
10380posix_setresuid (PyObject *self, PyObject *args)
10381{
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 /* We assume uid_t is no larger than a long. */
10383 long ruid, euid, suid;
10384 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10385 return NULL;
10386 if (setresuid(ruid, euid, suid) < 0)
10387 return posix_error();
10388 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010389}
10390#endif
10391
10392#ifdef HAVE_SETRESGID
10393PyDoc_STRVAR(posix_setresgid__doc__,
10394"setresgid(rgid, egid, sgid)\n\n\
10395Set the current process's real, effective, and saved group ids.");
10396
10397static PyObject*
10398posix_setresgid (PyObject *self, PyObject *args)
10399{
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 /* We assume uid_t is no larger than a long. */
10401 long rgid, egid, sgid;
10402 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10403 return NULL;
10404 if (setresgid(rgid, egid, sgid) < 0)
10405 return posix_error();
10406 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010407}
10408#endif
10409
10410#ifdef HAVE_GETRESUID
10411PyDoc_STRVAR(posix_getresuid__doc__,
10412"getresuid() -> (ruid, euid, suid)\n\n\
10413Get tuple of the current process's real, effective, and saved user ids.");
10414
10415static PyObject*
10416posix_getresuid (PyObject *self, PyObject *noargs)
10417{
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 uid_t ruid, euid, suid;
10419 long l_ruid, l_euid, l_suid;
10420 if (getresuid(&ruid, &euid, &suid) < 0)
10421 return posix_error();
10422 /* Force the values into long's as we don't know the size of uid_t. */
10423 l_ruid = ruid;
10424 l_euid = euid;
10425 l_suid = suid;
10426 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010427}
10428#endif
10429
10430#ifdef HAVE_GETRESGID
10431PyDoc_STRVAR(posix_getresgid__doc__,
10432"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010433Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010434
10435static PyObject*
10436posix_getresgid (PyObject *self, PyObject *noargs)
10437{
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 uid_t rgid, egid, sgid;
10439 long l_rgid, l_egid, l_sgid;
10440 if (getresgid(&rgid, &egid, &sgid) < 0)
10441 return posix_error();
10442 /* Force the values into long's as we don't know the size of uid_t. */
10443 l_rgid = rgid;
10444 l_egid = egid;
10445 l_sgid = sgid;
10446 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010447}
10448#endif
10449
Benjamin Peterson9428d532011-09-14 11:45:52 -040010450#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10454Return the value of extended attribute attribute on path.\n\
10455\n\
10456path may be either a string or an open file descriptor.\n\
10457If follow_symlinks is False, and the last element of the path is a symbolic\n\
10458 link, getxattr will examine the symbolic link itself instead of the file\n\
10459 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010460
10461static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010462posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010464 path_t path;
10465 path_t attribute;
10466 int follow_symlinks = 1;
10467 PyObject *buffer = NULL;
10468 int i;
10469 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010470
Larry Hastings9cf065c2012-06-22 16:30:09 -070010471 memset(&path, 0, sizeof(path));
10472 memset(&attribute, 0, sizeof(attribute));
10473 path.allow_fd = 1;
10474 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10475 path_converter, &path,
10476 path_converter, &attribute,
10477 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010478 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010479
Larry Hastings9cf065c2012-06-22 16:30:09 -070010480 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10481 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010482
Larry Hastings9cf065c2012-06-22 16:30:09 -070010483 for (i = 0; ; i++) {
10484 void *ptr;
10485 ssize_t result;
10486 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10487 Py_ssize_t buffer_size = buffer_sizes[i];
10488 if (!buffer_size) {
10489 path_error("getxattr", &path);
10490 goto exit;
10491 }
10492 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10493 if (!buffer)
10494 goto exit;
10495 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010496
Larry Hastings9cf065c2012-06-22 16:30:09 -070010497 Py_BEGIN_ALLOW_THREADS;
10498 if (path.fd >= 0)
10499 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10500 else if (follow_symlinks)
10501 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10502 else
10503 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10504 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010505
Larry Hastings9cf065c2012-06-22 16:30:09 -070010506 if (result < 0) {
10507 Py_DECREF(buffer);
10508 buffer = NULL;
10509 if (errno == ERANGE)
10510 continue;
10511 path_error("getxattr", &path);
10512 goto exit;
10513 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010514
Larry Hastings9cf065c2012-06-22 16:30:09 -070010515 if (result != buffer_size) {
10516 /* Can only shrink. */
10517 _PyBytes_Resize(&buffer, result);
10518 }
10519 break;
10520 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010521
Larry Hastings9cf065c2012-06-22 16:30:09 -070010522exit:
10523 path_cleanup(&path);
10524 path_cleanup(&attribute);
10525 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010526}
10527
10528PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010529"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10530Set extended attribute attribute on path to value.\n\
10531path may be either a string or an open file descriptor.\n\
10532If follow_symlinks is False, and the last element of the path is a symbolic\n\
10533 link, setxattr will modify the symbolic link itself instead of the file\n\
10534 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010535
10536static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010537posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010538{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010539 path_t path;
10540 path_t attribute;
10541 Py_buffer value;
10542 int flags = 0;
10543 int follow_symlinks = 1;
10544 int result;
10545 PyObject *return_value = NULL;
10546 static char *keywords[] = {"path", "attribute", "value",
10547 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010548
Larry Hastings9cf065c2012-06-22 16:30:09 -070010549 memset(&path, 0, sizeof(path));
10550 path.allow_fd = 1;
10551 memset(&attribute, 0, sizeof(attribute));
10552 memset(&value, 0, sizeof(value));
10553 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10554 keywords,
10555 path_converter, &path,
10556 path_converter, &attribute,
10557 &value, &flags,
10558 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010559 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010560
10561 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10562 goto exit;
10563
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010565 if (path.fd > -1)
10566 result = fsetxattr(path.fd, attribute.narrow,
10567 value.buf, value.len, flags);
10568 else if (follow_symlinks)
10569 result = setxattr(path.narrow, attribute.narrow,
10570 value.buf, value.len, flags);
10571 else
10572 result = lsetxattr(path.narrow, attribute.narrow,
10573 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010574 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010575
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576 if (result) {
10577 return_value = path_error("setxattr", &path);
10578 goto exit;
10579 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580
Larry Hastings9cf065c2012-06-22 16:30:09 -070010581 return_value = Py_None;
10582 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584exit:
10585 path_cleanup(&path);
10586 path_cleanup(&attribute);
10587 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010588
Larry Hastings9cf065c2012-06-22 16:30:09 -070010589 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010590}
10591
10592PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010593"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10594Remove extended attribute attribute on path.\n\
10595path may be either a string or an open file descriptor.\n\
10596If follow_symlinks is False, and the last element of the path is a symbolic\n\
10597 link, removexattr will modify the symbolic link itself instead of the file\n\
10598 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010599
10600static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010602{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010603 path_t path;
10604 path_t attribute;
10605 int follow_symlinks = 1;
10606 int result;
10607 PyObject *return_value = NULL;
10608 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 memset(&path, 0, sizeof(path));
10611 memset(&attribute, 0, sizeof(attribute));
10612 path.allow_fd = 1;
10613 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10614 keywords,
10615 path_converter, &path,
10616 path_converter, &attribute,
10617 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010618 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010619
10620 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10621 goto exit;
10622
Benjamin Peterson799bd802011-08-31 22:15:17 -040010623 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010624 if (path.fd > -1)
10625 result = fremovexattr(path.fd, attribute.narrow);
10626 else if (follow_symlinks)
10627 result = removexattr(path.narrow, attribute.narrow);
10628 else
10629 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010631
Larry Hastings9cf065c2012-06-22 16:30:09 -070010632 if (result) {
10633 return_value = path_error("removexattr", &path);
10634 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010636
Larry Hastings9cf065c2012-06-22 16:30:09 -070010637 return_value = Py_None;
10638 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639
Larry Hastings9cf065c2012-06-22 16:30:09 -070010640exit:
10641 path_cleanup(&path);
10642 path_cleanup(&attribute);
10643
10644 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010645}
10646
10647PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010648"listxattr(path='.', *, follow_symlinks=True)\n\n\
10649Return a list of extended attributes on path.\n\
10650\n\
10651path may be either None, a string, or an open file descriptor.\n\
10652if path is None, listxattr will examine the current directory.\n\
10653If follow_symlinks is False, and the last element of the path is a symbolic\n\
10654 link, listxattr will examine the symbolic link itself instead of the file\n\
10655 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656
10657static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010659{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010660 path_t path;
10661 int follow_symlinks = 1;
10662 Py_ssize_t i;
10663 PyObject *result = NULL;
10664 char *buffer = NULL;
10665 char *name;
10666 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010667
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 memset(&path, 0, sizeof(path));
10669 path.allow_fd = 1;
10670 path.fd = -1;
10671 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10672 path_converter, &path,
10673 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675
Larry Hastings9cf065c2012-06-22 16:30:09 -070010676 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10677 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679 name = path.narrow ? path.narrow : ".";
10680 for (i = 0; ; i++) {
10681 char *start, *trace, *end;
10682 ssize_t length;
10683 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10684 Py_ssize_t buffer_size = buffer_sizes[i];
10685 if (!buffer_size) {
10686 // ERANGE
10687 path_error("listxattr", &path);
10688 break;
10689 }
10690 buffer = PyMem_MALLOC(buffer_size);
10691 if (!buffer) {
10692 PyErr_NoMemory();
10693 break;
10694 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696 Py_BEGIN_ALLOW_THREADS;
10697 if (path.fd > -1)
10698 length = flistxattr(path.fd, buffer, buffer_size);
10699 else if (follow_symlinks)
10700 length = listxattr(name, buffer, buffer_size);
10701 else
10702 length = llistxattr(name, buffer, buffer_size);
10703 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 if (length < 0) {
10706 if (errno == ERANGE)
10707 continue;
10708 path_error("listxattr", &path);
10709 break;
10710 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010711
Larry Hastings9cf065c2012-06-22 16:30:09 -070010712 result = PyList_New(0);
10713 if (!result) {
10714 goto exit;
10715 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010716
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 end = buffer + length;
10718 for (trace = start = buffer; trace != end; trace++) {
10719 if (!*trace) {
10720 int error;
10721 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10722 trace - start);
10723 if (!attribute) {
10724 Py_DECREF(result);
10725 result = NULL;
10726 goto exit;
10727 }
10728 error = PyList_Append(result, attribute);
10729 Py_DECREF(attribute);
10730 if (error) {
10731 Py_DECREF(result);
10732 result = NULL;
10733 goto exit;
10734 }
10735 start = trace + 1;
10736 }
10737 }
10738 break;
10739 }
10740exit:
10741 path_cleanup(&path);
10742 if (buffer)
10743 PyMem_FREE(buffer);
10744 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010745}
10746
Benjamin Peterson9428d532011-09-14 11:45:52 -040010747#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010748
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010749
Georg Brandl2fb477c2012-02-21 00:33:36 +010010750PyDoc_STRVAR(posix_urandom__doc__,
10751"urandom(n) -> str\n\n\
10752Return n random bytes suitable for cryptographic use.");
10753
10754static PyObject *
10755posix_urandom(PyObject *self, PyObject *args)
10756{
10757 Py_ssize_t size;
10758 PyObject *result;
10759 int ret;
10760
10761 /* Read arguments */
10762 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10763 return NULL;
10764 if (size < 0)
10765 return PyErr_Format(PyExc_ValueError,
10766 "negative argument not allowed");
10767 result = PyBytes_FromStringAndSize(NULL, size);
10768 if (result == NULL)
10769 return NULL;
10770
10771 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10772 PyBytes_GET_SIZE(result));
10773 if (ret == -1) {
10774 Py_DECREF(result);
10775 return NULL;
10776 }
10777 return result;
10778}
10779
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010780/* Terminal size querying */
10781
10782static PyTypeObject TerminalSizeType;
10783
10784PyDoc_STRVAR(TerminalSize_docstring,
10785 "A tuple of (columns, lines) for holding terminal window size");
10786
10787static PyStructSequence_Field TerminalSize_fields[] = {
10788 {"columns", "width of the terminal window in characters"},
10789 {"lines", "height of the terminal window in characters"},
10790 {NULL, NULL}
10791};
10792
10793static PyStructSequence_Desc TerminalSize_desc = {
10794 "os.terminal_size",
10795 TerminalSize_docstring,
10796 TerminalSize_fields,
10797 2,
10798};
10799
10800#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10801PyDoc_STRVAR(termsize__doc__,
10802 "Return the size of the terminal window as (columns, lines).\n" \
10803 "\n" \
10804 "The optional argument fd (default standard output) specifies\n" \
10805 "which file descriptor should be queried.\n" \
10806 "\n" \
10807 "If the file descriptor is not connected to a terminal, an OSError\n" \
10808 "is thrown.\n" \
10809 "\n" \
10810 "This function will only be defined if an implementation is\n" \
10811 "available for this system.\n" \
10812 "\n" \
10813 "shutil.get_terminal_size is the high-level function which should \n" \
10814 "normally be used, os.get_terminal_size is the low-level implementation.");
10815
10816static PyObject*
10817get_terminal_size(PyObject *self, PyObject *args)
10818{
10819 int columns, lines;
10820 PyObject *termsize;
10821
10822 int fd = fileno(stdout);
10823 /* Under some conditions stdout may not be connected and
10824 * fileno(stdout) may point to an invalid file descriptor. For example
10825 * GUI apps don't have valid standard streams by default.
10826 *
10827 * If this happens, and the optional fd argument is not present,
10828 * the ioctl below will fail returning EBADF. This is what we want.
10829 */
10830
10831 if (!PyArg_ParseTuple(args, "|i", &fd))
10832 return NULL;
10833
10834#ifdef TERMSIZE_USE_IOCTL
10835 {
10836 struct winsize w;
10837 if (ioctl(fd, TIOCGWINSZ, &w))
10838 return PyErr_SetFromErrno(PyExc_OSError);
10839 columns = w.ws_col;
10840 lines = w.ws_row;
10841 }
10842#endif /* TERMSIZE_USE_IOCTL */
10843
10844#ifdef TERMSIZE_USE_CONIO
10845 {
10846 DWORD nhandle;
10847 HANDLE handle;
10848 CONSOLE_SCREEN_BUFFER_INFO csbi;
10849 switch (fd) {
10850 case 0: nhandle = STD_INPUT_HANDLE;
10851 break;
10852 case 1: nhandle = STD_OUTPUT_HANDLE;
10853 break;
10854 case 2: nhandle = STD_ERROR_HANDLE;
10855 break;
10856 default:
10857 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10858 }
10859 handle = GetStdHandle(nhandle);
10860 if (handle == NULL)
10861 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10862 if (handle == INVALID_HANDLE_VALUE)
10863 return PyErr_SetFromWindowsErr(0);
10864
10865 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10866 return PyErr_SetFromWindowsErr(0);
10867
10868 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10869 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10870 }
10871#endif /* TERMSIZE_USE_CONIO */
10872
10873 termsize = PyStructSequence_New(&TerminalSizeType);
10874 if (termsize == NULL)
10875 return NULL;
10876 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10877 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10878 if (PyErr_Occurred()) {
10879 Py_DECREF(termsize);
10880 return NULL;
10881 }
10882 return termsize;
10883}
10884#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10885
10886
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010887static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010888 {"access", (PyCFunction)posix_access,
10889 METH_VARARGS | METH_KEYWORDS,
10890 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010891#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010893#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010894 {"chdir", (PyCFunction)posix_chdir,
10895 METH_VARARGS | METH_KEYWORDS,
10896 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010897#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010898 {"chflags", (PyCFunction)posix_chflags,
10899 METH_VARARGS | METH_KEYWORDS,
10900 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010901#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010902 {"chmod", (PyCFunction)posix_chmod,
10903 METH_VARARGS | METH_KEYWORDS,
10904 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010905#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010907#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010908#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010909 {"chown", (PyCFunction)posix_chown,
10910 METH_VARARGS | METH_KEYWORDS,
10911 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010912#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010913#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010915#endif /* HAVE_LCHMOD */
10916#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010918#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010919#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010921#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010922#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010924#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010925#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010927#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010928#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010930#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010931#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10933 METH_NOARGS, posix_getcwd__doc__},
10934 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10935 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010936#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010937#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10938 {"link", (PyCFunction)posix_link,
10939 METH_VARARGS | METH_KEYWORDS,
10940 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010941#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010942 {"listdir", (PyCFunction)posix_listdir,
10943 METH_VARARGS | METH_KEYWORDS,
10944 posix_listdir__doc__},
10945 {"lstat", (PyCFunction)posix_lstat,
10946 METH_VARARGS | METH_KEYWORDS,
10947 posix_lstat__doc__},
10948 {"mkdir", (PyCFunction)posix_mkdir,
10949 METH_VARARGS | METH_KEYWORDS,
10950 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010951#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010953#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010954#ifdef HAVE_GETPRIORITY
10955 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10956#endif /* HAVE_GETPRIORITY */
10957#ifdef HAVE_SETPRIORITY
10958 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10959#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010960#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010961 {"readlink", (PyCFunction)posix_readlink,
10962 METH_VARARGS | METH_KEYWORDS,
10963 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010964#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010965#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010966 {"readlink", (PyCFunction)win_readlink,
10967 METH_VARARGS | METH_KEYWORDS,
10968 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010969#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010970 {"rename", (PyCFunction)posix_rename,
10971 METH_VARARGS | METH_KEYWORDS,
10972 posix_rename__doc__},
10973 {"replace", (PyCFunction)posix_replace,
10974 METH_VARARGS | METH_KEYWORDS,
10975 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010976 {"rmdir", (PyCFunction)posix_rmdir,
10977 METH_VARARGS | METH_KEYWORDS,
10978 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010979 {"stat", (PyCFunction)posix_stat,
10980 METH_VARARGS | METH_KEYWORDS,
10981 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010983#if defined(HAVE_SYMLINK)
10984 {"symlink", (PyCFunction)posix_symlink,
10985 METH_VARARGS | METH_KEYWORDS,
10986 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010987#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010988#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010990#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010992#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010994#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 {"unlink", (PyCFunction)posix_unlink,
10996 METH_VARARGS | METH_KEYWORDS,
10997 posix_unlink__doc__},
10998 {"remove", (PyCFunction)posix_unlink,
10999 METH_VARARGS | METH_KEYWORDS,
11000 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011001 {"utime", (PyCFunction)posix_utime,
11002 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011003#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011005#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011007#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 {"execve", (PyCFunction)posix_execve,
11010 METH_VARARGS | METH_KEYWORDS,
11011 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011012#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011013#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11015 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011016#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
11018 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011019#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000011020#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011021#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011023#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011024#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011026#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011027#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011028#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011029 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11030 {"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 +020011031#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011032#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011033 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011034#endif
11035#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011036 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011037#endif
11038#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011039 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011040#endif
11041#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011042 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011043#endif
11044#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011045 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011046#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011047 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011048#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011049 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11050 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11051#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011052#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011053#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011055#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011056#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011058#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011059#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011061#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011062#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011064#endif /* HAVE_GETEUID */
11065#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011067#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011068#ifdef HAVE_GETGROUPLIST
11069 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11070#endif
Fred Drakec9680921999-12-13 16:37:25 +000011071#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011073#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011075#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011077#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011078#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011080#endif /* HAVE_GETPPID */
11081#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011083#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011084#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011086#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011087#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011089#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011090#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011092#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011093#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011095#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011096#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11098 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011099#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011100#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011102#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011103#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011105#endif /* HAVE_SETEUID */
11106#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011108#endif /* HAVE_SETEGID */
11109#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011111#endif /* HAVE_SETREUID */
11112#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011114#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011115#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011117#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011118#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011120#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011121#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011123#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011124#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011126#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011127#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011129#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011130#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011132#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011133#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011134 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011135#endif /* HAVE_WAIT3 */
11136#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011137 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011138#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011139#if defined(HAVE_WAITID) && !defined(__APPLE__)
11140 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11141#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011142#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011144#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011145#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011147#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011148#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011150#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011151#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011153#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011154#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011156#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011157#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011159#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011160 {"open", (PyCFunction)posix_open,\
11161 METH_VARARGS | METH_KEYWORDS,
11162 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11164 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11165 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11166 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11167 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011168#ifdef HAVE_LOCKF
11169 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11170#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11172 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011173#ifdef HAVE_READV
11174 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11175#endif
11176#ifdef HAVE_PREAD
11177 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11178#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011180#ifdef HAVE_WRITEV
11181 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11182#endif
11183#ifdef HAVE_PWRITE
11184 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11185#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011186#ifdef HAVE_SENDFILE
11187 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11188 posix_sendfile__doc__},
11189#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011190 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011192#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011194#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011195#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011196 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011197#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011198#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011199 {"mkfifo", (PyCFunction)posix_mkfifo,
11200 METH_VARARGS | METH_KEYWORDS,
11201 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011202#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011203#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011204 {"mknod", (PyCFunction)posix_mknod,
11205 METH_VARARGS | METH_KEYWORDS,
11206 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011207#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011208#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11210 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11211 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011212#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011213#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011215#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011216#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011217 {"truncate", (PyCFunction)posix_truncate,
11218 METH_VARARGS | METH_KEYWORDS,
11219 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011220#endif
11221#ifdef HAVE_POSIX_FALLOCATE
11222 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11223#endif
11224#ifdef HAVE_POSIX_FADVISE
11225 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11226#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011227#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011229#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011230#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011232#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011234#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011236#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011237#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011239#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011240#ifdef HAVE_SYNC
11241 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11242#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011243#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011245#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011246#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011247#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011249#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011250#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011252#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011253#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011255#endif /* WIFSTOPPED */
11256#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011258#endif /* WIFSIGNALED */
11259#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011261#endif /* WIFEXITED */
11262#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011264#endif /* WEXITSTATUS */
11265#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011267#endif /* WTERMSIG */
11268#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011270#endif /* WSTOPSIG */
11271#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011272#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011274#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011275#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011276 {"statvfs", (PyCFunction)posix_statvfs,
11277 METH_VARARGS | METH_KEYWORDS,
11278 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011279#endif
Fred Drakec9680921999-12-13 16:37:25 +000011280#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011282#endif
11283#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011285#endif
11286#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011288#endif
11289#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011290 {"pathconf", (PyCFunction)posix_pathconf,
11291 METH_VARARGS | METH_KEYWORDS,
11292 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011293#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011295#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011297 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011298 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011299 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011300 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011301#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011302#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011304#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011305 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011306#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011308#endif
11309#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011311#endif
11312#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011314#endif
11315#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011317#endif
11318
Benjamin Peterson9428d532011-09-14 11:45:52 -040011319#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011320 {"setxattr", (PyCFunction)posix_setxattr,
11321 METH_VARARGS | METH_KEYWORDS,
11322 posix_setxattr__doc__},
11323 {"getxattr", (PyCFunction)posix_getxattr,
11324 METH_VARARGS | METH_KEYWORDS,
11325 posix_getxattr__doc__},
11326 {"removexattr", (PyCFunction)posix_removexattr,
11327 METH_VARARGS | METH_KEYWORDS,
11328 posix_removexattr__doc__},
11329 {"listxattr", (PyCFunction)posix_listxattr,
11330 METH_VARARGS | METH_KEYWORDS,
11331 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011332#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011333#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11334 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11335#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011337};
11338
11339
Barry Warsaw4a342091996-12-19 23:50:02 +000011340static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011341ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011342{
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011344}
11345
Guido van Rossumd48f2521997-12-05 22:19:34 +000011346#if defined(PYOS_OS2)
11347/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011348static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011349{
11350 APIRET rc;
11351 ULONG values[QSV_MAX+1];
11352 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011353 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011354
11355 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011356 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011357 Py_END_ALLOW_THREADS
11358
11359 if (rc != NO_ERROR) {
11360 os2_error(rc);
11361 return -1;
11362 }
11363
Fred Drake4d1e64b2002-04-15 19:40:07 +000011364 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11365 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11366 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11367 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11368 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11369 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11370 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011371
11372 switch (values[QSV_VERSION_MINOR]) {
11373 case 0: ver = "2.00"; break;
11374 case 10: ver = "2.10"; break;
11375 case 11: ver = "2.11"; break;
11376 case 30: ver = "3.00"; break;
11377 case 40: ver = "4.00"; break;
11378 case 50: ver = "5.00"; break;
11379 default:
Tim Peters885d4572001-11-28 20:27:42 +000011380 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011382 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011383 ver = &tmp[0];
11384 }
11385
11386 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011387 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011388 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011389
11390 /* Add Indicator of Which Drive was Used to Boot the System */
11391 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11392 tmp[1] = ':';
11393 tmp[2] = '\0';
11394
Fred Drake4d1e64b2002-04-15 19:40:07 +000011395 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011396}
11397#endif
11398
Brian Curtin52173d42010-12-02 18:29:18 +000011399#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011400static int
Brian Curtin52173d42010-12-02 18:29:18 +000011401enable_symlink()
11402{
11403 HANDLE tok;
11404 TOKEN_PRIVILEGES tok_priv;
11405 LUID luid;
11406 int meth_idx = 0;
11407
11408 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011409 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011410
11411 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011412 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011413
11414 tok_priv.PrivilegeCount = 1;
11415 tok_priv.Privileges[0].Luid = luid;
11416 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11417
11418 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11419 sizeof(TOKEN_PRIVILEGES),
11420 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011421 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011422
Brian Curtin3b4499c2010-12-28 14:31:47 +000011423 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11424 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011425}
11426#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11427
Barry Warsaw4a342091996-12-19 23:50:02 +000011428static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011429all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011430{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011431#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011433#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011434#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011436#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011437#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011439#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011440#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011442#endif
Fred Drakec9680921999-12-13 16:37:25 +000011443#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011445#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011446#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011448#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011449#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011451#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011452#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011454#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011455#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011457#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011458#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011460#endif
11461#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011463#endif
11464#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011466#endif
11467#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011469#endif
11470#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011472#endif
11473#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011475#endif
11476#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011478#endif
11479#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011481#endif
11482#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011484#endif
11485#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011487#endif
11488#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011490#endif
11491#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011493#endif
11494#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011496#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011497#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011499#endif
11500#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011502#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011503#ifdef O_XATTR
11504 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11505#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011506#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011508#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011509#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011511#endif
11512#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011514#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011515#ifdef O_EXEC
11516 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11517#endif
11518#ifdef O_SEARCH
11519 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11520#endif
11521#ifdef O_TTY_INIT
11522 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11523#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011524#ifdef PRIO_PROCESS
11525 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11526#endif
11527#ifdef PRIO_PGRP
11528 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11529#endif
11530#ifdef PRIO_USER
11531 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11532#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011533#ifdef O_CLOEXEC
11534 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11535#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011536#ifdef O_ACCMODE
11537 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11538#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011539
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011540
Jesus Cea94363612012-06-22 18:32:07 +020011541#ifdef SEEK_HOLE
11542 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11543#endif
11544#ifdef SEEK_DATA
11545 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11546#endif
11547
Tim Peters5aa91602002-01-30 05:46:57 +000011548/* MS Windows */
11549#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 /* Don't inherit in child processes. */
11551 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011552#endif
11553#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011554 /* Optimize for short life (keep in memory). */
11555 /* MS forgot to define this one with a non-underscore form too. */
11556 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011557#endif
11558#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 /* Automatically delete when last handle is closed. */
11560 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011561#endif
11562#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011563 /* Optimize for random access. */
11564 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011565#endif
11566#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 /* Optimize for sequential access. */
11568 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011569#endif
11570
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011571/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011572#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 /* Send a SIGIO signal whenever input or output
11574 becomes available on file descriptor */
11575 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011576#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011577#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 /* Direct disk access. */
11579 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011580#endif
11581#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 /* Must be a directory. */
11583 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011584#endif
11585#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 /* Do not follow links. */
11587 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011588#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011589#ifdef O_NOLINKS
11590 /* Fails if link count of the named file is greater than 1 */
11591 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11592#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011593#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 /* Do not update the access time. */
11595 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011596#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011597
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011599#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011601#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011602#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011604#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011605#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011607#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011608#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011610#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011611#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011613#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011614#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011616#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011617#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011619#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011620#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011622#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011623#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011625#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011626#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011628#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011629#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011631#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011632#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011634#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011635#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011637#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011638#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011640#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011641#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011643#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011644#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011645 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011646#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011647#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011649#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011650
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011651 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011652#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011653 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011654#endif /* ST_RDONLY */
11655#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011656 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011657#endif /* ST_NOSUID */
11658
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011659 /* FreeBSD sendfile() constants */
11660#ifdef SF_NODISKIO
11661 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11662#endif
11663#ifdef SF_MNOWAIT
11664 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11665#endif
11666#ifdef SF_SYNC
11667 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11668#endif
11669
Ross Lagerwall7807c352011-03-17 20:20:30 +020011670 /* constants for posix_fadvise */
11671#ifdef POSIX_FADV_NORMAL
11672 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11673#endif
11674#ifdef POSIX_FADV_SEQUENTIAL
11675 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11676#endif
11677#ifdef POSIX_FADV_RANDOM
11678 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11679#endif
11680#ifdef POSIX_FADV_NOREUSE
11681 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11682#endif
11683#ifdef POSIX_FADV_WILLNEED
11684 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11685#endif
11686#ifdef POSIX_FADV_DONTNEED
11687 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11688#endif
11689
11690 /* constants for waitid */
11691#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11692 if (ins(d, "P_PID", (long)P_PID)) return -1;
11693 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11694 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11695#endif
11696#ifdef WEXITED
11697 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11698#endif
11699#ifdef WNOWAIT
11700 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11701#endif
11702#ifdef WSTOPPED
11703 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11704#endif
11705#ifdef CLD_EXITED
11706 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11707#endif
11708#ifdef CLD_DUMPED
11709 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11710#endif
11711#ifdef CLD_TRAPPED
11712 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11713#endif
11714#ifdef CLD_CONTINUED
11715 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11716#endif
11717
11718 /* constants for lockf */
11719#ifdef F_LOCK
11720 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11721#endif
11722#ifdef F_TLOCK
11723 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11724#endif
11725#ifdef F_ULOCK
11726 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11727#endif
11728#ifdef F_TEST
11729 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11730#endif
11731
Guido van Rossum246bc171999-02-01 23:54:31 +000011732#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011733#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11735 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11736 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11737 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11738 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11739 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11740 if (ins(d, "P_PM", (long)P_PM)) return -1;
11741 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11742 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11743 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11744 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11745 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11746 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11747 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11748 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11749 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11750 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11751 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11752 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11753 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011754#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011755 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11756 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11757 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11758 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11759 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011760#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011761#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011762
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011763#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011764 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011765 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11766 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11767#ifdef SCHED_SPORADIC
11768 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11769#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011770#ifdef SCHED_BATCH
11771 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11772#endif
11773#ifdef SCHED_IDLE
11774 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11775#endif
11776#ifdef SCHED_RESET_ON_FORK
11777 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11778#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011779#ifdef SCHED_SYS
11780 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11781#endif
11782#ifdef SCHED_IA
11783 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11784#endif
11785#ifdef SCHED_FSS
11786 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11787#endif
11788#ifdef SCHED_FX
11789 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11790#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011791#endif
11792
Benjamin Peterson9428d532011-09-14 11:45:52 -040011793#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011794 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11795 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11796 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11797#endif
11798
Victor Stinner8b905bd2011-10-25 13:34:04 +020011799#ifdef RTLD_LAZY
11800 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11801#endif
11802#ifdef RTLD_NOW
11803 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11804#endif
11805#ifdef RTLD_GLOBAL
11806 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11807#endif
11808#ifdef RTLD_LOCAL
11809 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11810#endif
11811#ifdef RTLD_NODELETE
11812 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11813#endif
11814#ifdef RTLD_NOLOAD
11815 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11816#endif
11817#ifdef RTLD_DEEPBIND
11818 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11819#endif
11820
Guido van Rossumd48f2521997-12-05 22:19:34 +000011821#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011822 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011823#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011825}
11826
11827
Tim Peters5aa91602002-01-30 05:46:57 +000011828#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011829#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011830#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011831
11832#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011833#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011834#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011835
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011836#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011837#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011838#define MODNAME "posix"
11839#endif
11840
Martin v. Löwis1a214512008-06-11 05:26:20 +000011841static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011842 PyModuleDef_HEAD_INIT,
11843 MODNAME,
11844 posix__doc__,
11845 -1,
11846 posix_methods,
11847 NULL,
11848 NULL,
11849 NULL,
11850 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011851};
11852
11853
Larry Hastings9cf065c2012-06-22 16:30:09 -070011854static char *have_functions[] = {
11855
11856#ifdef HAVE_FACCESSAT
11857 "HAVE_FACCESSAT",
11858#endif
11859
11860#ifdef HAVE_FCHDIR
11861 "HAVE_FCHDIR",
11862#endif
11863
11864#ifdef HAVE_FCHMOD
11865 "HAVE_FCHMOD",
11866#endif
11867
11868#ifdef HAVE_FCHMODAT
11869 "HAVE_FCHMODAT",
11870#endif
11871
11872#ifdef HAVE_FCHOWN
11873 "HAVE_FCHOWN",
11874#endif
11875
11876#ifdef HAVE_FEXECVE
11877 "HAVE_FEXECVE",
11878#endif
11879
11880#ifdef HAVE_FDOPENDIR
11881 "HAVE_FDOPENDIR",
11882#endif
11883
Georg Brandl306336b2012-06-24 12:55:33 +020011884#ifdef HAVE_FPATHCONF
11885 "HAVE_FPATHCONF",
11886#endif
11887
Larry Hastings9cf065c2012-06-22 16:30:09 -070011888#ifdef HAVE_FSTATAT
11889 "HAVE_FSTATAT",
11890#endif
11891
11892#ifdef HAVE_FSTATVFS
11893 "HAVE_FSTATVFS",
11894#endif
11895
Georg Brandl306336b2012-06-24 12:55:33 +020011896#ifdef HAVE_FTRUNCATE
11897 "HAVE_FTRUNCATE",
11898#endif
11899
Larry Hastings9cf065c2012-06-22 16:30:09 -070011900#ifdef HAVE_FUTIMENS
11901 "HAVE_FUTIMENS",
11902#endif
11903
11904#ifdef HAVE_FUTIMES
11905 "HAVE_FUTIMES",
11906#endif
11907
11908#ifdef HAVE_FUTIMESAT
11909 "HAVE_FUTIMESAT",
11910#endif
11911
11912#ifdef HAVE_LINKAT
11913 "HAVE_LINKAT",
11914#endif
11915
11916#ifdef HAVE_LCHFLAGS
11917 "HAVE_LCHFLAGS",
11918#endif
11919
11920#ifdef HAVE_LCHMOD
11921 "HAVE_LCHMOD",
11922#endif
11923
11924#ifdef HAVE_LCHOWN
11925 "HAVE_LCHOWN",
11926#endif
11927
11928#ifdef HAVE_LSTAT
11929 "HAVE_LSTAT",
11930#endif
11931
11932#ifdef HAVE_LUTIMES
11933 "HAVE_LUTIMES",
11934#endif
11935
11936#ifdef HAVE_MKDIRAT
11937 "HAVE_MKDIRAT",
11938#endif
11939
11940#ifdef HAVE_MKFIFOAT
11941 "HAVE_MKFIFOAT",
11942#endif
11943
11944#ifdef HAVE_MKNODAT
11945 "HAVE_MKNODAT",
11946#endif
11947
11948#ifdef HAVE_OPENAT
11949 "HAVE_OPENAT",
11950#endif
11951
11952#ifdef HAVE_READLINKAT
11953 "HAVE_READLINKAT",
11954#endif
11955
11956#ifdef HAVE_RENAMEAT
11957 "HAVE_RENAMEAT",
11958#endif
11959
11960#ifdef HAVE_SYMLINKAT
11961 "HAVE_SYMLINKAT",
11962#endif
11963
11964#ifdef HAVE_UNLINKAT
11965 "HAVE_UNLINKAT",
11966#endif
11967
11968#ifdef HAVE_UTIMENSAT
11969 "HAVE_UTIMENSAT",
11970#endif
11971
11972#ifdef MS_WINDOWS
11973 "MS_WINDOWS",
11974#endif
11975
11976 NULL
11977};
11978
11979
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011980PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011981INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011982{
Victor Stinner8c62be82010-05-06 00:08:46 +000011983 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011984 PyObject *list;
11985 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011986
Brian Curtin52173d42010-12-02 18:29:18 +000011987#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011988 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011989#endif
11990
Victor Stinner8c62be82010-05-06 00:08:46 +000011991 m = PyModule_Create(&posixmodule);
11992 if (m == NULL)
11993 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011994
Victor Stinner8c62be82010-05-06 00:08:46 +000011995 /* Initialize environ dictionary */
11996 v = convertenviron();
11997 Py_XINCREF(v);
11998 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11999 return NULL;
12000 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012001
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 if (all_ins(m))
12003 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012004
Victor Stinner8c62be82010-05-06 00:08:46 +000012005 if (setup_confname_tables(m))
12006 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012007
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 Py_INCREF(PyExc_OSError);
12009 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012010
Benjamin Peterson2740af82011-08-02 17:41:34 -050012011#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012012 if (PyType_Ready(&cpu_set_type) < 0)
12013 return NULL;
12014 Py_INCREF(&cpu_set_type);
12015 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050012016#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012017
Guido van Rossumb3d39562000-01-31 18:41:26 +000012018#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012019 if (posix_putenv_garbage == NULL)
12020 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012021#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012022
Victor Stinner8c62be82010-05-06 00:08:46 +000012023 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012024#if defined(HAVE_WAITID) && !defined(__APPLE__)
12025 waitid_result_desc.name = MODNAME ".waitid_result";
12026 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
12027#endif
12028
Victor Stinner8c62be82010-05-06 00:08:46 +000012029 stat_result_desc.name = MODNAME ".stat_result";
12030 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12031 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12032 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
12033 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
12034 structseq_new = StatResultType.tp_new;
12035 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012036
Victor Stinner8c62be82010-05-06 00:08:46 +000012037 statvfs_result_desc.name = MODNAME ".statvfs_result";
12038 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012039#ifdef NEED_TICKS_PER_SECOND
12040# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012042# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012043 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012044# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012045 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012046# endif
12047#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012048
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012049#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012050 sched_param_desc.name = MODNAME ".sched_param";
12051 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
12052 SchedParamType.tp_new = sched_param_new;
12053#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012054
12055 /* initialize TerminalSize_info */
12056 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
12057 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000012058 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012059#if defined(HAVE_WAITID) && !defined(__APPLE__)
12060 Py_INCREF((PyObject*) &WaitidResultType);
12061 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12062#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012063 Py_INCREF((PyObject*) &StatResultType);
12064 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12065 Py_INCREF((PyObject*) &StatVFSResultType);
12066 PyModule_AddObject(m, "statvfs_result",
12067 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012068
12069#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012070 Py_INCREF(&SchedParamType);
12071 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012072#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012073
Larry Hastings605a62d2012-06-24 04:33:36 -070012074 times_result_desc.name = MODNAME ".times_result";
12075 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
12076 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12077
12078 uname_result_desc.name = MODNAME ".uname_result";
12079 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
12080 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12081
Thomas Wouters477c8d52006-05-27 19:21:47 +000012082#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 /*
12084 * Step 2 of weak-linking support on Mac OS X.
12085 *
12086 * The code below removes functions that are not available on the
12087 * currently active platform.
12088 *
12089 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012090 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012091 * OSX 10.4.
12092 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012093#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012094 if (fstatvfs == NULL) {
12095 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12096 return NULL;
12097 }
12098 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012099#endif /* HAVE_FSTATVFS */
12100
12101#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012102 if (statvfs == NULL) {
12103 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12104 return NULL;
12105 }
12106 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012107#endif /* HAVE_STATVFS */
12108
12109# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012110 if (lchown == NULL) {
12111 if (PyObject_DelAttrString(m, "lchown") == -1) {
12112 return NULL;
12113 }
12114 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012115#endif /* HAVE_LCHOWN */
12116
12117
12118#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012119
12120 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12121
Larry Hastings6fe20b32012-04-19 15:07:49 -070012122 billion = PyLong_FromLong(1000000000);
12123 if (!billion)
12124 return NULL;
12125
Larry Hastings9cf065c2012-06-22 16:30:09 -070012126 /* suppress "function not used" warnings */
12127 {
12128 int ignored;
12129 fd_specified("", -1);
12130 follow_symlinks_specified("", 1);
12131 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12132 dir_fd_converter(Py_None, &ignored);
12133 dir_fd_unavailable(Py_None, &ignored);
12134 }
12135
12136 /*
12137 * provide list of locally available functions
12138 * so os.py can populate support_* lists
12139 */
12140 list = PyList_New(0);
12141 if (!list)
12142 return NULL;
12143 for (trace = have_functions; *trace; trace++) {
12144 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12145 if (!unicode)
12146 return NULL;
12147 if (PyList_Append(list, unicode))
12148 return NULL;
12149 Py_DECREF(unicode);
12150 }
12151 PyModule_AddObject(m, "_have_functions", list);
12152
12153 initialized = 1;
12154
Victor Stinner8c62be82010-05-06 00:08:46 +000012155 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012156
Guido van Rossumb6775db1994-08-01 11:34:53 +000012157}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012158
12159#ifdef __cplusplus
12160}
12161#endif