blob: 90838c9efc457128f9de7f2f33a1f9bb703a9f5b [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
Trent Nelson9a461052012-09-18 21:50:06 -0400417/*
418 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
419 * without the int cast, the value gets interpreted as uint (4291925331),
420 * which doesn't play nicely with all the initializer lines in this file that
421 * look like this:
422 * int dir_fd = DEFAULT_DIR_FD;
423 */
424#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700425#else
426#define DEFAULT_DIR_FD (-100)
427#endif
428
429static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200430_fd_converter(PyObject *o, int *p, const char *allowed)
431{
432 int overflow;
433 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
434 if (PyFloat_Check(o) ||
435 (long_value == -1 && !overflow && PyErr_Occurred())) {
436 PyErr_Clear();
437 PyErr_Format(PyExc_TypeError,
438 "argument should be %s, not %.200s",
439 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700440 return 0;
441 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200442 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is greater than maximum");
445 return 0;
446 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200447 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700448 PyErr_SetString(PyExc_OverflowError,
449 "signed integer is less than minimum");
450 return 0;
451 }
452 *p = (int)long_value;
453 return 1;
454}
455
456static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200457dir_fd_converter(PyObject *o, void *p)
458{
459 if (o == Py_None) {
460 *(int *)p = DEFAULT_DIR_FD;
461 return 1;
462 }
463 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700464}
465
466
467
468/*
469 * A PyArg_ParseTuple "converter" function
470 * that handles filesystem paths in the manner
471 * preferred by the os module.
472 *
473 * path_converter accepts (Unicode) strings and their
474 * subclasses, and bytes and their subclasses. What
475 * it does with the argument depends on the platform:
476 *
477 * * On Windows, if we get a (Unicode) string we
478 * extract the wchar_t * and return it; if we get
479 * bytes we extract the char * and return that.
480 *
481 * * On all other platforms, strings are encoded
482 * to bytes using PyUnicode_FSConverter, then we
483 * extract the char * from the bytes object and
484 * return that.
485 *
486 * path_converter also optionally accepts signed
487 * integers (representing open file descriptors) instead
488 * of path strings.
489 *
490 * Input fields:
491 * path.nullable
492 * If nonzero, the path is permitted to be None.
493 * path.allow_fd
494 * If nonzero, the path is permitted to be a file handle
495 * (a signed int) instead of a string.
496 * path.function_name
497 * If non-NULL, path_converter will use that as the name
498 * of the function in error messages.
499 * (If path.argument_name is NULL it omits the function name.)
500 * path.argument_name
501 * If non-NULL, path_converter will use that as the name
502 * of the parameter in error messages.
503 * (If path.argument_name is NULL it uses "path".)
504 *
505 * Output fields:
506 * path.wide
507 * Points to the path if it was expressed as Unicode
508 * and was not encoded. (Only used on Windows.)
509 * path.narrow
510 * Points to the path if it was expressed as bytes,
511 * or it was Unicode and was encoded to bytes.
512 * path.fd
513 * Contains a file descriptor if path.accept_fd was true
514 * and the caller provided a signed integer instead of any
515 * sort of string.
516 *
517 * WARNING: if your "path" parameter is optional, and is
518 * unspecified, path_converter will never get called.
519 * So if you set allow_fd, you *MUST* initialize path.fd = -1
520 * yourself!
521 * path.length
522 * The length of the path in characters, if specified as
523 * a string.
524 * path.object
525 * The original object passed in.
526 * path.cleanup
527 * For internal use only. May point to a temporary object.
528 * (Pay no attention to the man behind the curtain.)
529 *
530 * At most one of path.wide or path.narrow will be non-NULL.
531 * If path was None and path.nullable was set,
532 * or if path was an integer and path.allow_fd was set,
533 * both path.wide and path.narrow will be NULL
534 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200535 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700536 * path_converter takes care to not write to the path_t
537 * unless it's successful. However it must reset the
538 * "cleanup" field each time it's called.
539 *
540 * Use as follows:
541 * path_t path;
542 * memset(&path, 0, sizeof(path));
543 * PyArg_ParseTuple(args, "O&", path_converter, &path);
544 * // ... use values from path ...
545 * path_cleanup(&path);
546 *
547 * (Note that if PyArg_Parse fails you don't need to call
548 * path_cleanup(). However it is safe to do so.)
549 */
550typedef struct {
551 char *function_name;
552 char *argument_name;
553 int nullable;
554 int allow_fd;
555 wchar_t *wide;
556 char *narrow;
557 int fd;
558 Py_ssize_t length;
559 PyObject *object;
560 PyObject *cleanup;
561} path_t;
562
563static void
564path_cleanup(path_t *path) {
565 if (path->cleanup) {
566 Py_DECREF(path->cleanup);
567 path->cleanup = NULL;
568 }
569}
570
571static int
572path_converter(PyObject *o, void *p) {
573 path_t *path = (path_t *)p;
574 PyObject *unicode, *bytes;
575 Py_ssize_t length;
576 char *narrow;
577
578#define FORMAT_EXCEPTION(exc, fmt) \
579 PyErr_Format(exc, "%s%s" fmt, \
580 path->function_name ? path->function_name : "", \
581 path->function_name ? ": " : "", \
582 path->argument_name ? path->argument_name : "path")
583
584 /* Py_CLEANUP_SUPPORTED support */
585 if (o == NULL) {
586 path_cleanup(path);
587 return 1;
588 }
589
590 /* ensure it's always safe to call path_cleanup() */
591 path->cleanup = NULL;
592
593 if (o == Py_None) {
594 if (!path->nullable) {
595 FORMAT_EXCEPTION(PyExc_TypeError,
596 "can't specify None for %s argument");
597 return 0;
598 }
599 path->wide = NULL;
600 path->narrow = NULL;
601 path->length = 0;
602 path->object = o;
603 path->fd = -1;
604 return 1;
605 }
606
607 unicode = PyUnicode_FromObject(o);
608 if (unicode) {
609#ifdef MS_WINDOWS
610 wchar_t *wide;
611 length = PyUnicode_GET_SIZE(unicode);
612 if (length > 32767) {
613 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
614 Py_DECREF(unicode);
615 return 0;
616 }
617
618 wide = PyUnicode_AsUnicode(unicode);
619 if (!wide) {
620 Py_DECREF(unicode);
621 return 0;
622 }
623
624 path->wide = wide;
625 path->narrow = NULL;
626 path->length = length;
627 path->object = o;
628 path->fd = -1;
629 path->cleanup = unicode;
630 return Py_CLEANUP_SUPPORTED;
631#else
632 int converted = PyUnicode_FSConverter(unicode, &bytes);
633 Py_DECREF(unicode);
634 if (!converted)
635 bytes = NULL;
636#endif
637 }
638 else {
639 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200640 if (PyObject_CheckBuffer(o))
641 bytes = PyBytes_FromObject(o);
642 else
643 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700644 if (!bytes) {
645 PyErr_Clear();
646 if (path->allow_fd) {
647 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200648 int result = _fd_converter(o, &fd,
649 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700650 if (result) {
651 path->wide = NULL;
652 path->narrow = NULL;
653 path->length = 0;
654 path->object = o;
655 path->fd = fd;
656 return result;
657 }
658 }
659 }
660 }
661
662 if (!bytes) {
663 if (!PyErr_Occurred())
664 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
665 return 0;
666 }
667
668#ifdef MS_WINDOWS
669 if (win32_warn_bytes_api()) {
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 length = PyBytes_GET_SIZE(bytes);
676#ifdef MS_WINDOWS
677 if (length > MAX_PATH) {
678 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
679 Py_DECREF(bytes);
680 return 0;
681 }
682#endif
683
684 narrow = PyBytes_AS_STRING(bytes);
685 if (length != strlen(narrow)) {
686 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
687 Py_DECREF(bytes);
688 return 0;
689 }
690
691 path->wide = NULL;
692 path->narrow = narrow;
693 path->length = length;
694 path->object = o;
695 path->fd = -1;
696 path->cleanup = bytes;
697 return Py_CLEANUP_SUPPORTED;
698}
699
700static void
701argument_unavailable_error(char *function_name, char *argument_name) {
702 PyErr_Format(PyExc_NotImplementedError,
703 "%s%s%s unavailable on this platform",
704 (function_name != NULL) ? function_name : "",
705 (function_name != NULL) ? ": ": "",
706 argument_name);
707}
708
709static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200710dir_fd_unavailable(PyObject *o, void *p)
711{
712 int dir_fd;
713 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700714 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200715 if (dir_fd != DEFAULT_DIR_FD) {
716 argument_unavailable_error(NULL, "dir_fd");
717 return 0;
718 }
719 *(int *)p = dir_fd;
720 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700721}
722
723static int
724fd_specified(char *function_name, int fd) {
725 if (fd == -1)
726 return 0;
727
728 argument_unavailable_error(function_name, "fd");
729 return 1;
730}
731
732static int
733follow_symlinks_specified(char *function_name, int follow_symlinks) {
734 if (follow_symlinks)
735 return 0;
736
737 argument_unavailable_error(function_name, "follow_symlinks");
738 return 1;
739}
740
741static int
742path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
743 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify dir_fd without matching path",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
754 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
755 PyErr_Format(PyExc_ValueError,
756 "%s: can't specify both dir_fd and fd",
757 function_name);
758 return 1;
759 }
760 return 0;
761}
762
763static int
764fd_and_follow_symlinks_invalid(char *function_name, int fd,
765 int follow_symlinks) {
766 if ((fd > 0) && (!follow_symlinks)) {
767 PyErr_Format(PyExc_ValueError,
768 "%s: cannot use fd and follow_symlinks together",
769 function_name);
770 return 1;
771 }
772 return 0;
773}
774
775static int
776dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
777 int follow_symlinks) {
778 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
779 PyErr_Format(PyExc_ValueError,
780 "%s: cannot use dir_fd and follow_symlinks together",
781 function_name);
782 return 1;
783 }
784 return 0;
785}
786
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200787/* A helper used by a number of POSIX-only functions */
788#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000789static int
790_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791{
792#if !defined(HAVE_LARGEFILE_SUPPORT)
793 *((off_t*)addr) = PyLong_AsLong(arg);
794#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000795 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000796#endif
797 if (PyErr_Occurred())
798 return 0;
799 return 1;
800}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200801#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000802
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000803#if defined _MSC_VER && _MSC_VER >= 1400
804/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200805 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * Normally, an invalid fd is likely to be a C program error and therefore
807 * an assertion can be useful, but it does contradict the POSIX standard
808 * which for write(2) states:
809 * "Otherwise, -1 shall be returned and errno set to indicate the error."
810 * "[EBADF] The fildes argument is not a valid file descriptor open for
811 * writing."
812 * Furthermore, python allows the user to enter any old integer
813 * as a fd and should merely raise a python exception on error.
814 * The Microsoft CRT doesn't provide an official way to check for the
815 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000816 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000817 * internal structures involved.
818 * The structures below must be updated for each version of visual studio
819 * according to the file internal.h in the CRT source, until MS comes
820 * up with a less hacky way to do this.
821 * (all of this is to avoid globally modifying the CRT behaviour using
822 * _set_invalid_parameter_handler() and _CrtSetReportMode())
823 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000824/* The actual size of the structure is determined at runtime.
825 * Only the first items must be present.
826 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000827typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000828 intptr_t osfhnd;
829 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000830} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000831
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000832extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000833#define IOINFO_L2E 5
834#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
835#define IOINFO_ARRAYS 64
836#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
837#define FOPEN 0x01
838#define _NO_CONSOLE_FILENO (intptr_t)-2
839
840/* This function emulates what the windows CRT does to validate file handles */
841int
842_PyVerify_fd(int fd)
843{
Victor Stinner8c62be82010-05-06 00:08:46 +0000844 const int i1 = fd >> IOINFO_L2E;
845 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000846
Antoine Pitrou22e41552010-08-15 18:07:50 +0000847 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000848
Victor Stinner8c62be82010-05-06 00:08:46 +0000849 /* Determine the actual size of the ioinfo structure,
850 * as used by the CRT loaded in memory
851 */
852 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
853 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
854 }
855 if (sizeof_ioinfo == 0) {
856 /* This should not happen... */
857 goto fail;
858 }
859
860 /* See that it isn't a special CLEAR fileno */
861 if (fd != _NO_CONSOLE_FILENO) {
862 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
863 * we check pointer validity and other info
864 */
865 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
866 /* finally, check that the file is open */
867 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
868 if (info->osfile & FOPEN) {
869 return 1;
870 }
871 }
872 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000873 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000874 errno = EBADF;
875 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000876}
877
878/* the special case of checking dup2. The target fd must be in a sensible range */
879static int
880_PyVerify_fd_dup2(int fd1, int fd2)
881{
Victor Stinner8c62be82010-05-06 00:08:46 +0000882 if (!_PyVerify_fd(fd1))
883 return 0;
884 if (fd2 == _NO_CONSOLE_FILENO)
885 return 0;
886 if ((unsigned)fd2 < _NHANDLE_)
887 return 1;
888 else
889 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000890}
891#else
892/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
893#define _PyVerify_fd_dup2(A, B) (1)
894#endif
895
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000896#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000897/* The following structure was copied from
898 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
899 include doesn't seem to be present in the Windows SDK (at least as included
900 with Visual Studio Express). */
901typedef struct _REPARSE_DATA_BUFFER {
902 ULONG ReparseTag;
903 USHORT ReparseDataLength;
904 USHORT Reserved;
905 union {
906 struct {
907 USHORT SubstituteNameOffset;
908 USHORT SubstituteNameLength;
909 USHORT PrintNameOffset;
910 USHORT PrintNameLength;
911 ULONG Flags;
912 WCHAR PathBuffer[1];
913 } SymbolicLinkReparseBuffer;
914
915 struct {
916 USHORT SubstituteNameOffset;
917 USHORT SubstituteNameLength;
918 USHORT PrintNameOffset;
919 USHORT PrintNameLength;
920 WCHAR PathBuffer[1];
921 } MountPointReparseBuffer;
922
923 struct {
924 UCHAR DataBuffer[1];
925 } GenericReparseBuffer;
926 };
927} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
928
929#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
930 GenericReparseBuffer)
931#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
932
933static int
Brian Curtind25aef52011-06-13 15:16:04 -0500934win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000935{
936 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
937 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
938 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000939
940 if (0 == DeviceIoControl(
941 reparse_point_handle,
942 FSCTL_GET_REPARSE_POINT,
943 NULL, 0, /* in buffer */
944 target_buffer, sizeof(target_buffer),
945 &n_bytes_returned,
946 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500947 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000948
949 if (reparse_tag)
950 *reparse_tag = rdb->ReparseTag;
951
Brian Curtind25aef52011-06-13 15:16:04 -0500952 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000953}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100954
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000955#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000956
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000958#ifdef WITH_NEXT_FRAMEWORK
959/* On Darwin/MacOSX a shared library or framework has no access to
960** environ directly, we must obtain it with _NSGetEnviron().
961*/
962#include <crt_externs.h>
963static char **environ;
964#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000965extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000966#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000967
Barry Warsaw53699e91996-12-10 23:23:01 +0000968static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000969convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000970{
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000972#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000974#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000975 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000976#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000977#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000978 APIRET rc;
979 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
980#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000981
Victor Stinner8c62be82010-05-06 00:08:46 +0000982 d = PyDict_New();
983 if (d == NULL)
984 return NULL;
985#ifdef WITH_NEXT_FRAMEWORK
986 if (environ == NULL)
987 environ = *_NSGetEnviron();
988#endif
989#ifdef MS_WINDOWS
990 /* _wenviron must be initialized in this way if the program is started
991 through main() instead of wmain(). */
992 _wgetenv(L"");
993 if (_wenviron == NULL)
994 return d;
995 /* This part ignores errors */
996 for (e = _wenviron; *e != NULL; e++) {
997 PyObject *k;
998 PyObject *v;
999 wchar_t *p = wcschr(*e, L'=');
1000 if (p == NULL)
1001 continue;
1002 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1003 if (k == NULL) {
1004 PyErr_Clear();
1005 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001006 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001007 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1008 if (v == NULL) {
1009 PyErr_Clear();
1010 Py_DECREF(k);
1011 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001012 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001013 if (PyDict_GetItem(d, k) == NULL) {
1014 if (PyDict_SetItem(d, k, v) != 0)
1015 PyErr_Clear();
1016 }
1017 Py_DECREF(k);
1018 Py_DECREF(v);
1019 }
1020#else
1021 if (environ == NULL)
1022 return d;
1023 /* This part ignores errors */
1024 for (e = environ; *e != NULL; e++) {
1025 PyObject *k;
1026 PyObject *v;
1027 char *p = strchr(*e, '=');
1028 if (p == NULL)
1029 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001030 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001031 if (k == NULL) {
1032 PyErr_Clear();
1033 continue;
1034 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001035 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001036 if (v == NULL) {
1037 PyErr_Clear();
1038 Py_DECREF(k);
1039 continue;
1040 }
1041 if (PyDict_GetItem(d, k) == NULL) {
1042 if (PyDict_SetItem(d, k, v) != 0)
1043 PyErr_Clear();
1044 }
1045 Py_DECREF(k);
1046 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001047 }
1048#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001049#if defined(PYOS_OS2)
1050 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1051 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1052 PyObject *v = PyBytes_FromString(buffer);
1053 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1054 Py_DECREF(v);
1055 }
1056 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1057 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1058 PyObject *v = PyBytes_FromString(buffer);
1059 PyDict_SetItemString(d, "ENDLIBPATH", v);
1060 Py_DECREF(v);
1061 }
1062#endif
1063 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001064}
1065
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001066/* Set a POSIX-specific error from errno, and return NULL */
1067
Barry Warsawd58d7641998-07-23 16:14:40 +00001068static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001069posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001070{
Victor Stinner8c62be82010-05-06 00:08:46 +00001071 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001072}
Barry Warsawd58d7641998-07-23 16:14:40 +00001073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001074posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001075{
Victor Stinner8c62be82010-05-06 00:08:46 +00001076 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001077}
1078
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001079
Mark Hammondef8b6542001-05-13 08:04:26 +00001080static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001081posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001082{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001083 PyObject *name_str, *rc;
1084 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1085 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001087 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1088 name_str);
1089 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001091}
1092
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001093#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001094static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001095win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096{
Victor Stinner8c62be82010-05-06 00:08:46 +00001097 /* XXX We should pass the function name along in the future.
1098 (winreg.c also wants to pass the function name.)
1099 This would however require an additional param to the
1100 Windows error object, which is non-trivial.
1101 */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001107}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001108
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001109static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001110win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001111{
Victor Stinner8c62be82010-05-06 00:08:46 +00001112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1116 else
1117 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001118}
1119
Victor Stinnereb5657a2011-09-30 01:44:27 +02001120static PyObject *
1121win32_error_object(char* function, PyObject* filename)
1122{
1123 /* XXX - see win32_error for comments on 'function' */
1124 errno = GetLastError();
1125 if (filename)
1126 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1127 PyExc_WindowsError,
1128 errno,
1129 filename);
1130 else
1131 return PyErr_SetFromWindowsErr(errno);
1132}
1133
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001134#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135
Larry Hastings9cf065c2012-06-22 16:30:09 -07001136/*
1137 * Some functions return Win32 errors, others only ever use posix_error
1138 * (this is for backwards compatibility with exceptions)
1139 */
1140static PyObject *
1141path_posix_error(char *function_name, path_t *path)
1142{
1143 if (path->narrow)
1144 return posix_error_with_filename(path->narrow);
1145 return posix_error();
1146}
1147
1148static PyObject *
1149path_error(char *function_name, path_t *path)
1150{
1151#ifdef MS_WINDOWS
1152 if (path->narrow)
1153 return win32_error(function_name, path->narrow);
1154 if (path->wide)
1155 return win32_error_unicode(function_name, path->wide);
1156 return win32_error(function_name, NULL);
1157#else
1158 return path_posix_error(function_name, path);
1159#endif
1160}
1161
Guido van Rossumd48f2521997-12-05 22:19:34 +00001162#if defined(PYOS_OS2)
1163/**********************************************************************
1164 * Helper Function to Trim and Format OS/2 Messages
1165 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001166static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001167os2_formatmsg(char *msgbuf, int msglen, char *reason)
1168{
1169 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1170
1171 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1172 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1173
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001174 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001175 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1176 }
1177
1178 /* Add Optional Reason Text */
1179 if (reason) {
1180 strcat(msgbuf, " : ");
1181 strcat(msgbuf, reason);
1182 }
1183}
1184
1185/**********************************************************************
1186 * Decode an OS/2 Operating System Error Code
1187 *
1188 * A convenience function to lookup an OS/2 error code and return a
1189 * text message we can use to raise a Python exception.
1190 *
1191 * Notes:
1192 * The messages for errors returned from the OS/2 kernel reside in
1193 * the file OSO001.MSG in the \OS2 directory hierarchy.
1194 *
1195 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001196static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001197os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1198{
1199 APIRET rc;
1200 ULONG msglen;
1201
1202 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1203 Py_BEGIN_ALLOW_THREADS
1204 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1205 errorcode, "oso001.msg", &msglen);
1206 Py_END_ALLOW_THREADS
1207
1208 if (rc == NO_ERROR)
1209 os2_formatmsg(msgbuf, msglen, reason);
1210 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001211 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001212 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001213
1214 return msgbuf;
1215}
1216
1217/* Set an OS/2-specific error and return NULL. OS/2 kernel
1218 errors are not in a global variable e.g. 'errno' nor are
1219 they congruent with posix error numbers. */
1220
Victor Stinner8c62be82010-05-06 00:08:46 +00001221static PyObject *
1222os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001223{
1224 char text[1024];
1225 PyObject *v;
1226
1227 os2_strerror(text, sizeof(text), code, "");
1228
1229 v = Py_BuildValue("(is)", code, text);
1230 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001231 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001232 Py_DECREF(v);
1233 }
1234 return NULL; /* Signal to Python that an Exception is Pending */
1235}
1236
1237#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001238
1239/* POSIX generic methods */
1240
Barry Warsaw53699e91996-12-10 23:23:01 +00001241static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001242posix_fildes(PyObject *fdobj, int (*func)(int))
1243{
Victor Stinner8c62be82010-05-06 00:08:46 +00001244 int fd;
1245 int res;
1246 fd = PyObject_AsFileDescriptor(fdobj);
1247 if (fd < 0)
1248 return NULL;
1249 if (!_PyVerify_fd(fd))
1250 return posix_error();
1251 Py_BEGIN_ALLOW_THREADS
1252 res = (*func)(fd);
1253 Py_END_ALLOW_THREADS
1254 if (res < 0)
1255 return posix_error();
1256 Py_INCREF(Py_None);
1257 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001258}
Guido van Rossum21142a01999-01-08 21:05:37 +00001259
1260static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001261posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001262{
Victor Stinner8c62be82010-05-06 00:08:46 +00001263 PyObject *opath1 = NULL;
1264 char *path1;
1265 int res;
1266 if (!PyArg_ParseTuple(args, format,
1267 PyUnicode_FSConverter, &opath1))
1268 return NULL;
1269 path1 = PyBytes_AsString(opath1);
1270 Py_BEGIN_ALLOW_THREADS
1271 res = (*func)(path1);
1272 Py_END_ALLOW_THREADS
1273 if (res < 0)
1274 return posix_error_with_allocated_filename(opath1);
1275 Py_DECREF(opath1);
1276 Py_INCREF(Py_None);
1277 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278}
1279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001281#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001283win32_1str(PyObject* args, char* func,
1284 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1285 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001286{
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001288 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001290
Victor Stinnereb5657a2011-09-30 01:44:27 +02001291 if (PyArg_ParseTuple(args, wformat, &uni))
1292 {
1293 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1294 if (wstr == NULL)
1295 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001297 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001298 Py_END_ALLOW_THREADS
1299 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001300 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001301 Py_INCREF(Py_None);
1302 return Py_None;
1303 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001304 PyErr_Clear();
1305
Victor Stinner8c62be82010-05-06 00:08:46 +00001306 if (!PyArg_ParseTuple(args, format, &ansi))
1307 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001308 if (win32_warn_bytes_api())
1309 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001310 Py_BEGIN_ALLOW_THREADS
1311 result = funcA(ansi);
1312 Py_END_ALLOW_THREADS
1313 if (!result)
1314 return win32_error(func, ansi);
1315 Py_INCREF(Py_None);
1316 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317
1318}
1319
1320/* This is a reimplementation of the C library's chdir function,
1321 but one that produces Win32 errors instead of DOS error codes.
1322 chdir is essentially a wrapper around SetCurrentDirectory; however,
1323 it also needs to set "magic" environment variables indicating
1324 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001325static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326win32_chdir(LPCSTR path)
1327{
Victor Stinner8c62be82010-05-06 00:08:46 +00001328 char new_path[MAX_PATH+1];
1329 int result;
1330 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001331
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if(!SetCurrentDirectoryA(path))
1333 return FALSE;
1334 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1335 if (!result)
1336 return FALSE;
1337 /* In the ANSI API, there should not be any paths longer
1338 than MAX_PATH. */
1339 assert(result <= MAX_PATH+1);
1340 if (strncmp(new_path, "\\\\", 2) == 0 ||
1341 strncmp(new_path, "//", 2) == 0)
1342 /* UNC path, nothing to do. */
1343 return TRUE;
1344 env[1] = new_path[0];
1345 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346}
1347
1348/* The Unicode version differs from the ANSI version
1349 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001350static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001351win32_wchdir(LPCWSTR path)
1352{
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1354 int result;
1355 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001356
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 if(!SetCurrentDirectoryW(path))
1358 return FALSE;
1359 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1360 if (!result)
1361 return FALSE;
1362 if (result > MAX_PATH+1) {
1363 new_path = malloc(result * sizeof(wchar_t));
1364 if (!new_path) {
1365 SetLastError(ERROR_OUTOFMEMORY);
1366 return FALSE;
1367 }
1368 result = GetCurrentDirectoryW(result, new_path);
1369 if (!result) {
1370 free(new_path);
1371 return FALSE;
1372 }
1373 }
1374 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1375 wcsncmp(new_path, L"//", 2) == 0)
1376 /* UNC path, nothing to do. */
1377 return TRUE;
1378 env[1] = new_path[0];
1379 result = SetEnvironmentVariableW(env, new_path);
1380 if (new_path != _new_path)
1381 free(new_path);
1382 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001383}
1384#endif
1385
Martin v. Löwis14694662006-02-03 12:54:16 +00001386#ifdef MS_WINDOWS
1387/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1388 - time stamps are restricted to second resolution
1389 - file modification times suffer from forth-and-back conversions between
1390 UTC and local time
1391 Therefore, we implement our own stat, based on the Win32 API directly.
1392*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001393#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001394
1395struct win32_stat{
1396 int st_dev;
1397 __int64 st_ino;
1398 unsigned short st_mode;
1399 int st_nlink;
1400 int st_uid;
1401 int st_gid;
1402 int st_rdev;
1403 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001405 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001406 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001407 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001408 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001409 int st_ctime_nsec;
1410};
1411
1412static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1413
1414static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001415FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001416{
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1418 /* Cannot simply cast and dereference in_ptr,
1419 since it might not be aligned properly */
1420 __int64 in;
1421 memcpy(&in, in_ptr, sizeof(in));
1422 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001423 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001424}
1425
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001427time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428{
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 /* XXX endianness */
1430 __int64 out;
1431 out = time_in + secs_between_epochs;
1432 out = out * 10000000 + nsec_in / 100;
1433 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001434}
1435
Martin v. Löwis14694662006-02-03 12:54:16 +00001436/* Below, we *know* that ugo+r is 0444 */
1437#if _S_IREAD != 0400
1438#error Unsupported C library
1439#endif
1440static int
1441attributes_to_mode(DWORD attr)
1442{
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 int m = 0;
1444 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1445 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1446 else
1447 m |= _S_IFREG;
1448 if (attr & FILE_ATTRIBUTE_READONLY)
1449 m |= 0444;
1450 else
1451 m |= 0666;
1452 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001453}
1454
1455static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001456attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001457{
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 memset(result, 0, sizeof(*result));
1459 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1460 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1461 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1462 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1463 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001464 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001465 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1467 /* first clear the S_IFMT bits */
1468 result->st_mode ^= (result->st_mode & 0170000);
1469 /* now set the bits that make this a symlink */
1470 result->st_mode |= 0120000;
1471 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001472
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001474}
1475
Guido van Rossumd8faa362007-04-27 19:54:29 +00001476static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001477attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001478{
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 HANDLE hFindFile;
1480 WIN32_FIND_DATAA FileData;
1481 hFindFile = FindFirstFileA(pszFile, &FileData);
1482 if (hFindFile == INVALID_HANDLE_VALUE)
1483 return FALSE;
1484 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001485 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001486 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001487 info->dwFileAttributes = FileData.dwFileAttributes;
1488 info->ftCreationTime = FileData.ftCreationTime;
1489 info->ftLastAccessTime = FileData.ftLastAccessTime;
1490 info->ftLastWriteTime = FileData.ftLastWriteTime;
1491 info->nFileSizeHigh = FileData.nFileSizeHigh;
1492 info->nFileSizeLow = FileData.nFileSizeLow;
1493/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001494 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1495 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001496 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001497}
1498
1499static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001500attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001501{
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 HANDLE hFindFile;
1503 WIN32_FIND_DATAW FileData;
1504 hFindFile = FindFirstFileW(pszFile, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE)
1506 return FALSE;
1507 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001508 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001509 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 info->dwFileAttributes = FileData.dwFileAttributes;
1511 info->ftCreationTime = FileData.ftCreationTime;
1512 info->ftLastAccessTime = FileData.ftLastAccessTime;
1513 info->ftLastWriteTime = FileData.ftLastWriteTime;
1514 info->nFileSizeHigh = FileData.nFileSizeHigh;
1515 info->nFileSizeLow = FileData.nFileSizeLow;
1516/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1518 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001520}
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1523static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001524static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1525 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001526static int
Brian Curtind25aef52011-06-13 15:16:04 -05001527check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001528{
Brian Curtind25aef52011-06-13 15:16:04 -05001529 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001530 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1531 DWORD);
1532
Brian Curtind25aef52011-06-13 15:16:04 -05001533 /* only recheck */
1534 if (!has_GetFinalPathNameByHandle)
1535 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001536 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001537 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1538 "GetFinalPathNameByHandleA");
1539 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1540 "GetFinalPathNameByHandleW");
1541 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1542 Py_GetFinalPathNameByHandleW;
1543 }
1544 return has_GetFinalPathNameByHandle;
1545}
1546
1547static BOOL
1548get_target_path(HANDLE hdl, wchar_t **target_path)
1549{
1550 int buf_size, result_length;
1551 wchar_t *buf;
1552
1553 /* We have a good handle to the target, use it to determine
1554 the target path name (then we'll call lstat on it). */
1555 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1556 VOLUME_NAME_DOS);
1557 if(!buf_size)
1558 return FALSE;
1559
1560 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001561 if (!buf) {
1562 SetLastError(ERROR_OUTOFMEMORY);
1563 return FALSE;
1564 }
1565
Brian Curtind25aef52011-06-13 15:16:04 -05001566 result_length = Py_GetFinalPathNameByHandleW(hdl,
1567 buf, buf_size, VOLUME_NAME_DOS);
1568
1569 if(!result_length) {
1570 free(buf);
1571 return FALSE;
1572 }
1573
1574 if(!CloseHandle(hdl)) {
1575 free(buf);
1576 return FALSE;
1577 }
1578
1579 buf[result_length] = 0;
1580
1581 *target_path = buf;
1582 return TRUE;
1583}
1584
1585static int
1586win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1587 BOOL traverse);
1588static int
1589win32_xstat_impl(const char *path, struct win32_stat *result,
1590 BOOL traverse)
1591{
Victor Stinner26de69d2011-06-17 15:15:38 +02001592 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001593 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001595 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001596 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 const char *dot;
1598
Brian Curtind25aef52011-06-13 15:16:04 -05001599 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001600 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1601 traverse reparse point. */
1602 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001603 }
1604
Brian Curtinf5e76d02010-11-24 13:14:05 +00001605 hFile = CreateFileA(
1606 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001607 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001608 0, /* share mode */
1609 NULL, /* security attributes */
1610 OPEN_EXISTING,
1611 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001612 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1613 Because of this, calls like GetFinalPathNameByHandle will return
1614 the symlink path agin and not the actual final path. */
1615 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1616 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001617 NULL);
1618
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001620 /* Either the target doesn't exist, or we don't have access to
1621 get a handle to it. If the former, we need to return an error.
1622 If the latter, we can use attributes_from_dir. */
1623 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 return -1;
1625 /* Could not get attributes on open file. Fall back to
1626 reading the directory. */
1627 if (!attributes_from_dir(path, &info, &reparse_tag))
1628 /* Very strange. This should not fail now */
1629 return -1;
1630 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1631 if (traverse) {
1632 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001633 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001634 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001635 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001637 } else {
1638 if (!GetFileInformationByHandle(hFile, &info)) {
1639 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001640 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001641 }
1642 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001643 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1644 return -1;
1645
1646 /* Close the outer open file handle now that we're about to
1647 reopen it with different flags. */
1648 if (!CloseHandle(hFile))
1649 return -1;
1650
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001651 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001652 /* In order to call GetFinalPathNameByHandle we need to open
1653 the file without the reparse handling flag set. */
1654 hFile2 = CreateFileA(
1655 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1656 NULL, OPEN_EXISTING,
1657 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1658 NULL);
1659 if (hFile2 == INVALID_HANDLE_VALUE)
1660 return -1;
1661
1662 if (!get_target_path(hFile2, &target_path))
1663 return -1;
1664
1665 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001666 free(target_path);
1667 return code;
1668 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001669 } else
1670 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001672 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673
1674 /* Set S_IEXEC if it is an .exe, .bat, ... */
1675 dot = strrchr(path, '.');
1676 if (dot) {
1677 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1678 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1679 result->st_mode |= 0111;
1680 }
1681 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682}
1683
1684static int
Brian Curtind25aef52011-06-13 15:16:04 -05001685win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1686 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687{
1688 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001689 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001691 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001692 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 const wchar_t *dot;
1694
Brian Curtind25aef52011-06-13 15:16:04 -05001695 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001696 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1697 traverse reparse point. */
1698 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001699 }
1700
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701 hFile = CreateFileW(
1702 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001703 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 0, /* share mode */
1705 NULL, /* security attributes */
1706 OPEN_EXISTING,
1707 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001708 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1709 Because of this, calls like GetFinalPathNameByHandle will return
1710 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001711 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001712 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001713 NULL);
1714
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716 /* Either the target doesn't exist, or we don't have access to
1717 get a handle to it. If the former, we need to return an error.
1718 If the latter, we can use attributes_from_dir. */
1719 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return -1;
1721 /* Could not get attributes on open file. Fall back to
1722 reading the directory. */
1723 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1724 /* Very strange. This should not fail now */
1725 return -1;
1726 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1727 if (traverse) {
1728 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001729 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001733 } else {
1734 if (!GetFileInformationByHandle(hFile, &info)) {
1735 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001736 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 }
1738 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001739 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1740 return -1;
1741
1742 /* Close the outer open file handle now that we're about to
1743 reopen it with different flags. */
1744 if (!CloseHandle(hFile))
1745 return -1;
1746
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001748 /* In order to call GetFinalPathNameByHandle we need to open
1749 the file without the reparse handling flag set. */
1750 hFile2 = CreateFileW(
1751 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1752 NULL, OPEN_EXISTING,
1753 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1754 NULL);
1755 if (hFile2 == INVALID_HANDLE_VALUE)
1756 return -1;
1757
1758 if (!get_target_path(hFile2, &target_path))
1759 return -1;
1760
1761 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001762 free(target_path);
1763 return code;
1764 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001765 } else
1766 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001768 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001769
1770 /* Set S_IEXEC if it is an .exe, .bat, ... */
1771 dot = wcsrchr(path, '.');
1772 if (dot) {
1773 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1774 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1775 result->st_mode |= 0111;
1776 }
1777 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778}
1779
1780static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001781win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001782{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001783 /* Protocol violation: we explicitly clear errno, instead of
1784 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001785 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001786 errno = 0;
1787 return code;
1788}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001789
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001790static int
1791win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1792{
1793 /* Protocol violation: we explicitly clear errno, instead of
1794 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001795 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001796 errno = 0;
1797 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001798}
Brian Curtind25aef52011-06-13 15:16:04 -05001799/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
1801 In Posix, stat automatically traverses symlinks and returns the stat
1802 structure for the target. In Windows, the equivalent GetFileAttributes by
1803 default does not traverse symlinks and instead returns attributes for
1804 the symlink.
1805
1806 Therefore, win32_lstat will get the attributes traditionally, and
1807 win32_stat will first explicitly resolve the symlink target and then will
1808 call win32_lstat on that result.
1809
Ezio Melotti4969f702011-03-15 05:59:46 +02001810 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001811
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001812static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001813win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001814{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001815 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001816}
1817
Victor Stinner8c62be82010-05-06 00:08:46 +00001818static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001819win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001820{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001821 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001822}
1823
1824static int
1825win32_stat(const char* path, struct win32_stat *result)
1826{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001827 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001828}
1829
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001830static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001831win32_stat_w(const wchar_t* path, struct win32_stat *result)
1832{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001834}
1835
1836static int
1837win32_fstat(int file_number, struct win32_stat *result)
1838{
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 BY_HANDLE_FILE_INFORMATION info;
1840 HANDLE h;
1841 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001842
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001843 if (!_PyVerify_fd(file_number))
1844 h = INVALID_HANDLE_VALUE;
1845 else
1846 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001847
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 /* Protocol violation: we explicitly clear errno, instead of
1849 setting it to a POSIX error. Callers should use GetLastError. */
1850 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001851
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 if (h == INVALID_HANDLE_VALUE) {
1853 /* This is really a C library error (invalid file handle).
1854 We set the Win32 error to the closes one matching. */
1855 SetLastError(ERROR_INVALID_HANDLE);
1856 return -1;
1857 }
1858 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001859
Victor Stinner8c62be82010-05-06 00:08:46 +00001860 type = GetFileType(h);
1861 if (type == FILE_TYPE_UNKNOWN) {
1862 DWORD error = GetLastError();
1863 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001864 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001865 }
1866 /* else: valid but unknown file */
1867 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001868
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 if (type != FILE_TYPE_DISK) {
1870 if (type == FILE_TYPE_CHAR)
1871 result->st_mode = _S_IFCHR;
1872 else if (type == FILE_TYPE_PIPE)
1873 result->st_mode = _S_IFIFO;
1874 return 0;
1875 }
1876
1877 if (!GetFileInformationByHandle(h, &info)) {
1878 return -1;
1879 }
1880
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001881 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001882 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1884 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001885}
1886
1887#endif /* MS_WINDOWS */
1888
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001889PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001890"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001892 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1894\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001895Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1896or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001897\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001898See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001899
1900static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 {"st_mode", "protection bits"},
1902 {"st_ino", "inode"},
1903 {"st_dev", "device"},
1904 {"st_nlink", "number of hard links"},
1905 {"st_uid", "user ID of owner"},
1906 {"st_gid", "group ID of owner"},
1907 {"st_size", "total size, in bytes"},
1908 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1909 {NULL, "integer time of last access"},
1910 {NULL, "integer time of last modification"},
1911 {NULL, "integer time of last change"},
1912 {"st_atime", "time of last access"},
1913 {"st_mtime", "time of last modification"},
1914 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001915 {"st_atime_ns", "time of last access in nanoseconds"},
1916 {"st_mtime_ns", "time of last modification in nanoseconds"},
1917 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001918#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001920#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001921#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001924#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001926#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001927#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001929#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001930#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001932#endif
1933#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001935#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001937};
1938
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001939#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001940#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001942#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001943#endif
1944
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001945#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001946#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1947#else
1948#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1949#endif
1950
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001951#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001952#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1953#else
1954#define ST_RDEV_IDX ST_BLOCKS_IDX
1955#endif
1956
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001957#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1958#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1959#else
1960#define ST_FLAGS_IDX ST_RDEV_IDX
1961#endif
1962
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001963#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001964#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001965#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001966#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001967#endif
1968
1969#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1970#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1971#else
1972#define ST_BIRTHTIME_IDX ST_GEN_IDX
1973#endif
1974
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 "stat_result", /* name */
1977 stat_result__doc__, /* doc */
1978 stat_result_fields,
1979 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980};
1981
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1984This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001985 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001986or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001988See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001989
1990static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 {"f_bsize", },
1992 {"f_frsize", },
1993 {"f_blocks", },
1994 {"f_bfree", },
1995 {"f_bavail", },
1996 {"f_files", },
1997 {"f_ffree", },
1998 {"f_favail", },
1999 {"f_flag", },
2000 {"f_namemax",},
2001 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002002};
2003
2004static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 "statvfs_result", /* name */
2006 statvfs_result__doc__, /* doc */
2007 statvfs_result_fields,
2008 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002009};
2010
Ross Lagerwall7807c352011-03-17 20:20:30 +02002011#if defined(HAVE_WAITID) && !defined(__APPLE__)
2012PyDoc_STRVAR(waitid_result__doc__,
2013"waitid_result: Result from waitid.\n\n\
2014This object may be accessed either as a tuple of\n\
2015 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2016or via the attributes si_pid, si_uid, and so on.\n\
2017\n\
2018See os.waitid for more information.");
2019
2020static PyStructSequence_Field waitid_result_fields[] = {
2021 {"si_pid", },
2022 {"si_uid", },
2023 {"si_signo", },
2024 {"si_status", },
2025 {"si_code", },
2026 {0}
2027};
2028
2029static PyStructSequence_Desc waitid_result_desc = {
2030 "waitid_result", /* name */
2031 waitid_result__doc__, /* doc */
2032 waitid_result_fields,
2033 5
2034};
2035static PyTypeObject WaitidResultType;
2036#endif
2037
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002038static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039static PyTypeObject StatResultType;
2040static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002041#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002042static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002043#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002044static newfunc structseq_new;
2045
2046static PyObject *
2047statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2048{
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence *result;
2050 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002051
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 result = (PyStructSequence*)structseq_new(type, args, kwds);
2053 if (!result)
2054 return NULL;
2055 /* If we have been initialized from a tuple,
2056 st_?time might be set to None. Initialize it
2057 from the int slots. */
2058 for (i = 7; i <= 9; i++) {
2059 if (result->ob_item[i+3] == Py_None) {
2060 Py_DECREF(Py_None);
2061 Py_INCREF(result->ob_item[i]);
2062 result->ob_item[i+3] = result->ob_item[i];
2063 }
2064 }
2065 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002066}
2067
2068
2069
2070/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002071static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002072
2073PyDoc_STRVAR(stat_float_times__doc__,
2074"stat_float_times([newval]) -> oldval\n\n\
2075Determine whether os.[lf]stat represents time stamps as float objects.\n\
2076If newval is True, future calls to stat() return floats, if it is False,\n\
2077future calls return ints. \n\
2078If newval is omitted, return the current setting.\n");
2079
2080static PyObject*
2081stat_float_times(PyObject* self, PyObject *args)
2082{
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 int newval = -1;
2084 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2085 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002086 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2087 "stat_float_times() is deprecated",
2088 1))
2089 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 if (newval == -1)
2091 /* Return old value */
2092 return PyBool_FromLong(_stat_float_times);
2093 _stat_float_times = newval;
2094 Py_INCREF(Py_None);
2095 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002096}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002097
Larry Hastings6fe20b32012-04-19 15:07:49 -07002098static PyObject *billion = NULL;
2099
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002100static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002101fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002102{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002103 PyObject *s = _PyLong_FromTime_t(sec);
2104 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2105 PyObject *s_in_ns = NULL;
2106 PyObject *ns_total = NULL;
2107 PyObject *float_s = NULL;
2108
2109 if (!(s && ns_fractional))
2110 goto exit;
2111
2112 s_in_ns = PyNumber_Multiply(s, billion);
2113 if (!s_in_ns)
2114 goto exit;
2115
2116 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2117 if (!ns_total)
2118 goto exit;
2119
Victor Stinner4195b5c2012-02-08 23:03:19 +01002120 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002121 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2122 if (!float_s)
2123 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002124 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002125 else {
2126 float_s = s;
2127 Py_INCREF(float_s);
2128 }
2129
2130 PyStructSequence_SET_ITEM(v, index, s);
2131 PyStructSequence_SET_ITEM(v, index+3, float_s);
2132 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2133 s = NULL;
2134 float_s = NULL;
2135 ns_total = NULL;
2136exit:
2137 Py_XDECREF(s);
2138 Py_XDECREF(ns_fractional);
2139 Py_XDECREF(s_in_ns);
2140 Py_XDECREF(ns_total);
2141 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002142}
2143
Tim Peters5aa91602002-01-30 05:46:57 +00002144/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002145 (used by posix_stat() and posix_fstat()) */
2146static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002147_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002148{
Victor Stinner8c62be82010-05-06 00:08:46 +00002149 unsigned long ansec, mnsec, cnsec;
2150 PyObject *v = PyStructSequence_New(&StatResultType);
2151 if (v == NULL)
2152 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002153
Victor Stinner8c62be82010-05-06 00:08:46 +00002154 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002155#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002156 PyStructSequence_SET_ITEM(v, 1,
2157 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002158#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002159 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002160#endif
2161#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 PyStructSequence_SET_ITEM(v, 2,
2163 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002164#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002165 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002166#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2168 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2169 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002170#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 PyStructSequence_SET_ITEM(v, 6,
2172 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002173#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002174 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002175#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002176
Martin v. Löwis14694662006-02-03 12:54:16 +00002177#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002178 ansec = st->st_atim.tv_nsec;
2179 mnsec = st->st_mtim.tv_nsec;
2180 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002181#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002182 ansec = st->st_atimespec.tv_nsec;
2183 mnsec = st->st_mtimespec.tv_nsec;
2184 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002185#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002186 ansec = st->st_atime_nsec;
2187 mnsec = st->st_mtime_nsec;
2188 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002189#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002191#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002192 fill_time(v, 7, st->st_atime, ansec);
2193 fill_time(v, 8, st->st_mtime, mnsec);
2194 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002195
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002196#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2198 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002199#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002200#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2202 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002203#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002204#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2206 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002207#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002208#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2210 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002211#endif
2212#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002213 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002214 PyObject *val;
2215 unsigned long bsec,bnsec;
2216 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002217#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002218 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002219#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002220 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002221#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002222 if (_stat_float_times) {
2223 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2224 } else {
2225 val = PyLong_FromLong((long)bsec);
2226 }
2227 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2228 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002229 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002230#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002231#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002232 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2233 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002234#endif
Fred Drake699f3522000-06-29 21:12:41 +00002235
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 if (PyErr_Occurred()) {
2237 Py_DECREF(v);
2238 return NULL;
2239 }
Fred Drake699f3522000-06-29 21:12:41 +00002240
Victor Stinner8c62be82010-05-06 00:08:46 +00002241 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002242}
2243
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002244/* POSIX methods */
2245
Guido van Rossum94f6f721999-01-06 18:42:14 +00002246
2247static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002248posix_do_stat(char *function_name, path_t *path,
2249 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002250{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002251 STRUCT_STAT st;
2252 int result;
2253
2254#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2255 if (follow_symlinks_specified(function_name, follow_symlinks))
2256 return NULL;
2257#endif
2258
2259 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2260 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2261 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2262 return NULL;
2263
2264 Py_BEGIN_ALLOW_THREADS
2265 if (path->fd != -1)
2266 result = FSTAT(path->fd, &st);
2267 else
2268#ifdef MS_WINDOWS
2269 if (path->wide) {
2270 if (follow_symlinks)
2271 result = win32_stat_w(path->wide, &st);
2272 else
2273 result = win32_lstat_w(path->wide, &st);
2274 }
2275 else
2276#endif
2277#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2278 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2279 result = LSTAT(path->narrow, &st);
2280 else
2281#endif
2282#ifdef HAVE_FSTATAT
2283 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2284 result = fstatat(dir_fd, path->narrow, &st,
2285 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2286 else
2287#endif
2288 result = STAT(path->narrow, &st);
2289 Py_END_ALLOW_THREADS
2290
2291 if (result != 0)
2292 return path_error("stat", path);
2293
2294 return _pystat_fromstructstat(&st);
2295}
2296
2297PyDoc_STRVAR(posix_stat__doc__,
2298"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2299Perform a stat system call on the given path.\n\
2300\n\
2301path may be specified as either a string or as an open file descriptor.\n\
2302\n\
2303If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2304 and path should be relative; path will then be relative to that directory.\n\
2305 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2306 it will raise a NotImplementedError.\n\
2307If follow_symlinks is False, and the last element of the path is a symbolic\n\
2308 link, stat will examine the symbolic link itself instead of the file the\n\
2309 link points to.\n\
2310It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2311 an open file descriptor.");
2312
2313static PyObject *
2314posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2315{
2316 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2317 path_t path;
2318 int dir_fd = DEFAULT_DIR_FD;
2319 int follow_symlinks = 1;
2320 PyObject *return_value;
2321
2322 memset(&path, 0, sizeof(path));
2323 path.allow_fd = 1;
2324 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2325 path_converter, &path,
2326#ifdef HAVE_FSTATAT
2327 dir_fd_converter, &dir_fd,
2328#else
2329 dir_fd_unavailable, &dir_fd,
2330#endif
2331 &follow_symlinks))
2332 return NULL;
2333 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2334 path_cleanup(&path);
2335 return return_value;
2336}
2337
2338PyDoc_STRVAR(posix_lstat__doc__,
2339"lstat(path, *, dir_fd=None) -> stat result\n\n\
2340Like stat(), but do not follow symbolic links.\n\
2341Equivalent to stat(path, follow_symlinks=False).");
2342
2343static PyObject *
2344posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2345{
2346 static char *keywords[] = {"path", "dir_fd", NULL};
2347 path_t path;
2348 int dir_fd = DEFAULT_DIR_FD;
2349 int follow_symlinks = 0;
2350 PyObject *return_value;
2351
2352 memset(&path, 0, sizeof(path));
2353 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2354 path_converter, &path,
2355#ifdef HAVE_FSTATAT
2356 dir_fd_converter, &dir_fd
2357#else
2358 dir_fd_unavailable, &dir_fd
2359#endif
2360 ))
2361 return NULL;
2362 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2363 path_cleanup(&path);
2364 return return_value;
2365}
2366
2367PyDoc_STRVAR(posix_access__doc__,
2368"access(path, mode, *, dir_fd=None, effective_ids=False,\
2369 follow_symlinks=True)\n\n\
2370Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2371False otherwise.\n\
2372\n\
2373If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2374 and path should be relative; path will then be relative to that directory.\n\
2375If effective_ids is True, access will use the effective uid/gid instead of\n\
2376 the real uid/gid.\n\
2377If follow_symlinks is False, and the last element of the path is a symbolic\n\
2378 link, access will examine the symbolic link itself instead of the file the\n\
2379 link points to.\n\
2380dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2381 on your platform. If they are unavailable, using them will raise a\n\
2382 NotImplementedError.\n\
2383\n\
2384Note that most operations will use the effective uid/gid, therefore this\n\
2385 routine can be used in a suid/sgid environment to test if the invoking user\n\
2386 has the specified access to the path.\n\
2387The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2388 of R_OK, W_OK, and X_OK.");
2389
2390static PyObject *
2391posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2392{
2393 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2394 "follow_symlinks", NULL};
2395 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002396 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002397 int dir_fd = DEFAULT_DIR_FD;
2398 int effective_ids = 0;
2399 int follow_symlinks = 1;
2400 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002401
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002402#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002404#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002405 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002407
2408 memset(&path, 0, sizeof(path));
2409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2410 path_converter, &path, &mode,
2411#ifdef HAVE_FACCESSAT
2412 dir_fd_converter, &dir_fd,
2413#else
2414 dir_fd_unavailable, &dir_fd,
2415#endif
2416 &effective_ids, &follow_symlinks))
2417 return NULL;
2418
2419#ifndef HAVE_FACCESSAT
2420 if (follow_symlinks_specified("access", follow_symlinks))
2421 goto exit;
2422
2423 if (effective_ids) {
2424 argument_unavailable_error("access", "effective_ids");
2425 goto exit;
2426 }
2427#endif
2428
2429#ifdef MS_WINDOWS
2430 Py_BEGIN_ALLOW_THREADS
2431 if (path.wide != NULL)
2432 attr = GetFileAttributesW(path.wide);
2433 else
2434 attr = GetFileAttributesA(path.narrow);
2435 Py_END_ALLOW_THREADS
2436
2437 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002438 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002439 * * we didn't get a -1, and
2440 * * write access wasn't requested,
2441 * * or the file isn't read-only,
2442 * * or it's a directory.
2443 * (Directories cannot be read-only on Windows.)
2444 */
2445 return_value = PyBool_FromLong(
2446 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002447 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002448 !(attr & FILE_ATTRIBUTE_READONLY) ||
2449 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2450#else
2451
2452 Py_BEGIN_ALLOW_THREADS
2453#ifdef HAVE_FACCESSAT
2454 if ((dir_fd != DEFAULT_DIR_FD) ||
2455 effective_ids ||
2456 !follow_symlinks) {
2457 int flags = 0;
2458 if (!follow_symlinks)
2459 flags |= AT_SYMLINK_NOFOLLOW;
2460 if (effective_ids)
2461 flags |= AT_EACCESS;
2462 result = faccessat(dir_fd, path.narrow, mode, flags);
2463 }
2464 else
2465#endif
2466 result = access(path.narrow, mode);
2467 Py_END_ALLOW_THREADS
2468 return_value = PyBool_FromLong(!result);
2469#endif
2470
2471#ifndef HAVE_FACCESSAT
2472exit:
2473#endif
2474 path_cleanup(&path);
2475 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002476}
2477
Guido van Rossumd371ff11999-01-25 16:12:23 +00002478#ifndef F_OK
2479#define F_OK 0
2480#endif
2481#ifndef R_OK
2482#define R_OK 4
2483#endif
2484#ifndef W_OK
2485#define W_OK 2
2486#endif
2487#ifndef X_OK
2488#define X_OK 1
2489#endif
2490
2491#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002492PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002493"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002494Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002495
2496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002497posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002498{
Victor Stinner8c62be82010-05-06 00:08:46 +00002499 int id;
2500 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002501
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2503 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002504
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002505#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002506 /* file descriptor 0 only, the default input device (stdin) */
2507 if (id == 0) {
2508 ret = ttyname();
2509 }
2510 else {
2511 ret = NULL;
2512 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002513#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002514 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002515#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 if (ret == NULL)
2517 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002518 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002519}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002520#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002521
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002522#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002523PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002524"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002525Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002526
2527static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002528posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002529{
Victor Stinner8c62be82010-05-06 00:08:46 +00002530 char *ret;
2531 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002532
Greg Wardb48bc172000-03-01 21:51:56 +00002533#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002534 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002535#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002536 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002537#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002538 if (ret == NULL)
2539 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002540 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002541}
2542#endif
2543
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002544PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002545"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002546Change the current working directory to the specified path.\n\
2547\n\
2548path may always be specified as a string.\n\
2549On some platforms, path may also be specified as an open file descriptor.\n\
2550 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002551
Barry Warsaw53699e91996-12-10 23:23:01 +00002552static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002554{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002555 path_t path;
2556 int result;
2557 PyObject *return_value = NULL;
2558 static char *keywords[] = {"path", NULL};
2559
2560 memset(&path, 0, sizeof(path));
2561#ifdef HAVE_FCHDIR
2562 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002563#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002564 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2565 path_converter, &path
2566 ))
2567 return NULL;
2568
2569 Py_BEGIN_ALLOW_THREADS
2570#ifdef MS_WINDOWS
2571 if (path.wide)
2572 result = win32_wchdir(path.wide);
2573 else
2574 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002575 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2577 result = _chdir2(path.narrow);
2578#else
2579#ifdef HAVE_FCHDIR
2580 if (path.fd != -1)
2581 result = fchdir(path.fd);
2582 else
2583#endif
2584 result = chdir(path.narrow);
2585#endif
2586 Py_END_ALLOW_THREADS
2587
2588 if (result) {
2589 return_value = path_error("chdir", &path);
2590 goto exit;
2591 }
2592
2593 return_value = Py_None;
2594 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002595
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596exit:
2597 path_cleanup(&path);
2598 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002599}
2600
Fred Drake4d1e64b2002-04-15 19:40:07 +00002601#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603"fchdir(fd)\n\n\
2604Change to the directory of the given file descriptor. fd must be\n\
2605opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002606
2607static PyObject *
2608posix_fchdir(PyObject *self, PyObject *fdobj)
2609{
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002611}
2612#endif /* HAVE_FCHDIR */
2613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002615PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2617Change the access permissions of a file.\n\
2618\n\
2619path may always be specified as a string.\n\
2620On some platforms, path may also be specified as an open file descriptor.\n\
2621 If this functionality is unavailable, using it raises an exception.\n\
2622If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2623 and path should be relative; path will then be relative to that directory.\n\
2624If follow_symlinks is False, and the last element of the path is a symbolic\n\
2625 link, chmod will modify the symbolic link itself instead of the file the\n\
2626 link points to.\n\
2627It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2628 an open file descriptor.\n\
2629dir_fd and follow_symlinks may not be implemented on your platform.\n\
2630 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Barry Warsaw53699e91996-12-10 23:23:01 +00002632static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002634{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002635 path_t path;
2636 int mode;
2637 int dir_fd = DEFAULT_DIR_FD;
2638 int follow_symlinks = 1;
2639 int result;
2640 PyObject *return_value = NULL;
2641 static char *keywords[] = {"path", "mode", "dir_fd",
2642 "follow_symlinks", NULL};
2643
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002644#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002645 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002647
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648#ifdef HAVE_FCHMODAT
2649 int fchmodat_nofollow_unsupported = 0;
2650#endif
2651
2652 memset(&path, 0, sizeof(path));
2653#ifdef HAVE_FCHMOD
2654 path.allow_fd = 1;
2655#endif
2656 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2657 path_converter, &path,
2658 &mode,
2659#ifdef HAVE_FCHMODAT
2660 dir_fd_converter, &dir_fd,
2661#else
2662 dir_fd_unavailable, &dir_fd,
2663#endif
2664 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002665 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002666
2667#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2668 if (follow_symlinks_specified("chmod", follow_symlinks))
2669 goto exit;
2670#endif
2671
2672#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002673 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 if (path.wide)
2675 attr = GetFileAttributesW(path.wide);
2676 else
2677 attr = GetFileAttributesA(path.narrow);
2678 if (attr == 0xFFFFFFFF)
2679 result = 0;
2680 else {
2681 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002682 attr &= ~FILE_ATTRIBUTE_READONLY;
2683 else
2684 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685 if (path.wide)
2686 result = SetFileAttributesW(path.wide, attr);
2687 else
2688 result = SetFileAttributesA(path.narrow, attr);
2689 }
2690 Py_END_ALLOW_THREADS
2691
2692 if (!result) {
2693 return_value = win32_error_object("chmod", path.object);
2694 goto exit;
2695 }
2696#else /* MS_WINDOWS */
2697 Py_BEGIN_ALLOW_THREADS
2698#ifdef HAVE_FCHMOD
2699 if (path.fd != -1)
2700 result = fchmod(path.fd, mode);
2701 else
2702#endif
2703#ifdef HAVE_LCHMOD
2704 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2705 result = lchmod(path.narrow, mode);
2706 else
2707#endif
2708#ifdef HAVE_FCHMODAT
2709 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2710 /*
2711 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2712 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002713 * and then says it isn't implemented yet.
2714 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715 *
2716 * Once it is supported, os.chmod will automatically
2717 * support dir_fd and follow_symlinks=False. (Hopefully.)
2718 * Until then, we need to be careful what exception we raise.
2719 */
2720 result = fchmodat(dir_fd, path.narrow, mode,
2721 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2722 /*
2723 * But wait! We can't throw the exception without allowing threads,
2724 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2725 */
2726 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002727 result &&
2728 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2729 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002730 }
2731 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002732#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 result = chmod(path.narrow, mode);
2734 Py_END_ALLOW_THREADS
2735
2736 if (result) {
2737#ifdef HAVE_FCHMODAT
2738 if (fchmodat_nofollow_unsupported) {
2739 if (dir_fd != DEFAULT_DIR_FD)
2740 dir_fd_and_follow_symlinks_invalid("chmod",
2741 dir_fd, follow_symlinks);
2742 else
2743 follow_symlinks_specified("chmod", follow_symlinks);
2744 }
2745 else
2746#endif
2747 return_value = path_error("chmod", &path);
2748 goto exit;
2749 }
2750#endif
2751
2752 Py_INCREF(Py_None);
2753 return_value = Py_None;
2754exit:
2755 path_cleanup(&path);
2756 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002757}
2758
Larry Hastings9cf065c2012-06-22 16:30:09 -07002759
Christian Heimes4e30a842007-11-30 22:12:06 +00002760#ifdef HAVE_FCHMOD
2761PyDoc_STRVAR(posix_fchmod__doc__,
2762"fchmod(fd, mode)\n\n\
2763Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002764descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002765
2766static PyObject *
2767posix_fchmod(PyObject *self, PyObject *args)
2768{
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 int fd, mode, res;
2770 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2771 return NULL;
2772 Py_BEGIN_ALLOW_THREADS
2773 res = fchmod(fd, mode);
2774 Py_END_ALLOW_THREADS
2775 if (res < 0)
2776 return posix_error();
2777 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002778}
2779#endif /* HAVE_FCHMOD */
2780
2781#ifdef HAVE_LCHMOD
2782PyDoc_STRVAR(posix_lchmod__doc__,
2783"lchmod(path, mode)\n\n\
2784Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002785affects the link itself rather than the target.\n\
2786Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002787
2788static PyObject *
2789posix_lchmod(PyObject *self, PyObject *args)
2790{
Victor Stinner8c62be82010-05-06 00:08:46 +00002791 PyObject *opath;
2792 char *path;
2793 int i;
2794 int res;
2795 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2796 &opath, &i))
2797 return NULL;
2798 path = PyBytes_AsString(opath);
2799 Py_BEGIN_ALLOW_THREADS
2800 res = lchmod(path, i);
2801 Py_END_ALLOW_THREADS
2802 if (res < 0)
2803 return posix_error_with_allocated_filename(opath);
2804 Py_DECREF(opath);
2805 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002806}
2807#endif /* HAVE_LCHMOD */
2808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002809
Thomas Wouterscf297e42007-02-23 15:07:44 +00002810#ifdef HAVE_CHFLAGS
2811PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812"chflags(path, flags, *, follow_symlinks=True)\n\n\
2813Set file flags.\n\
2814\n\
2815If follow_symlinks is False, and the last element of the path is a symbolic\n\
2816 link, chflags will change flags on the symbolic link itself instead of the\n\
2817 file the link points to.\n\
2818follow_symlinks may not be implemented on your platform. If it is\n\
2819unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002820
2821static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002823{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 int follow_symlinks = 1;
2827 int result;
2828 PyObject *return_value;
2829 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2830
2831 memset(&path, 0, sizeof(path));
2832 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2833 path_converter, &path,
2834 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002835 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836
2837#ifndef HAVE_LCHFLAGS
2838 if (follow_symlinks_specified("chflags", follow_symlinks))
2839 goto exit;
2840#endif
2841
Victor Stinner8c62be82010-05-06 00:08:46 +00002842 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843#ifdef HAVE_LCHFLAGS
2844 if (!follow_symlinks)
2845 result = lchflags(path.narrow, flags);
2846 else
2847#endif
2848 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850
2851 if (result) {
2852 return_value = path_posix_error("chflags", &path);
2853 goto exit;
2854 }
2855
2856 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858
2859exit:
2860 path_cleanup(&path);
2861 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002862}
2863#endif /* HAVE_CHFLAGS */
2864
2865#ifdef HAVE_LCHFLAGS
2866PyDoc_STRVAR(posix_lchflags__doc__,
2867"lchflags(path, flags)\n\n\
2868Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869This function will not follow symbolic links.\n\
2870Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002871
2872static PyObject *
2873posix_lchflags(PyObject *self, PyObject *args)
2874{
Victor Stinner8c62be82010-05-06 00:08:46 +00002875 PyObject *opath;
2876 char *path;
2877 unsigned long flags;
2878 int res;
2879 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2880 PyUnicode_FSConverter, &opath, &flags))
2881 return NULL;
2882 path = PyBytes_AsString(opath);
2883 Py_BEGIN_ALLOW_THREADS
2884 res = lchflags(path, flags);
2885 Py_END_ALLOW_THREADS
2886 if (res < 0)
2887 return posix_error_with_allocated_filename(opath);
2888 Py_DECREF(opath);
2889 Py_INCREF(Py_None);
2890 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002891}
2892#endif /* HAVE_LCHFLAGS */
2893
Martin v. Löwis244edc82001-10-04 22:44:26 +00002894#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002896"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002897Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002898
2899static PyObject *
2900posix_chroot(PyObject *self, PyObject *args)
2901{
Victor Stinner8c62be82010-05-06 00:08:46 +00002902 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002903}
2904#endif
2905
Guido van Rossum21142a01999-01-08 21:05:37 +00002906#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002907PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002908"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002910
2911static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002912posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002913{
Stefan Krah0e803b32010-11-26 16:16:47 +00002914 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002915}
2916#endif /* HAVE_FSYNC */
2917
Ross Lagerwall7807c352011-03-17 20:20:30 +02002918#ifdef HAVE_SYNC
2919PyDoc_STRVAR(posix_sync__doc__,
2920"sync()\n\n\
2921Force write of everything to disk.");
2922
2923static PyObject *
2924posix_sync(PyObject *self, PyObject *noargs)
2925{
2926 Py_BEGIN_ALLOW_THREADS
2927 sync();
2928 Py_END_ALLOW_THREADS
2929 Py_RETURN_NONE;
2930}
2931#endif
2932
Guido van Rossum21142a01999-01-08 21:05:37 +00002933#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002934
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002935#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002936extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2937#endif
2938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002940"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002941force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002942 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002943
2944static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002945posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002946{
Stefan Krah0e803b32010-11-26 16:16:47 +00002947 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002948}
2949#endif /* HAVE_FDATASYNC */
2950
2951
Fredrik Lundh10723342000-07-10 16:38:09 +00002952#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002953PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002954"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2955Change the owner and group id of path to the numeric uid and gid.\n\
2956\n\
2957path may always be specified as a string.\n\
2958On some platforms, path may also be specified as an open file descriptor.\n\
2959 If this functionality is unavailable, using it raises an exception.\n\
2960If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2961 and path should be relative; path will then be relative to that directory.\n\
2962If follow_symlinks is False, and the last element of the path is a symbolic\n\
2963 link, chown will modify the symbolic link itself instead of the file the\n\
2964 link points to.\n\
2965It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2966 an open file descriptor.\n\
2967dir_fd and follow_symlinks may not be implemented on your platform.\n\
2968 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Barry Warsaw53699e91996-12-10 23:23:01 +00002970static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002971posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002972{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002973 path_t path;
2974 long uid_l, gid_l;
2975 uid_t uid;
2976 gid_t gid;
2977 int dir_fd = DEFAULT_DIR_FD;
2978 int follow_symlinks = 1;
2979 int result;
2980 PyObject *return_value = NULL;
2981 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2982 "follow_symlinks", NULL};
2983
2984 memset(&path, 0, sizeof(path));
2985#ifdef HAVE_FCHOWN
2986 path.allow_fd = 1;
2987#endif
2988 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2989 path_converter, &path,
2990 &uid_l, &gid_l,
2991#ifdef HAVE_FCHOWNAT
2992 dir_fd_converter, &dir_fd,
2993#else
2994 dir_fd_unavailable, &dir_fd,
2995#endif
2996 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998
2999#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3000 if (follow_symlinks_specified("chown", follow_symlinks))
3001 goto exit;
3002#endif
3003 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3004 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3005 goto exit;
3006
3007#ifdef __APPLE__
3008 /*
3009 * This is for Mac OS X 10.3, which doesn't have lchown.
3010 * (But we still have an lchown symbol because of weak-linking.)
3011 * It doesn't have fchownat either. So there's no possibility
3012 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003013 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003014 if ((!follow_symlinks) && (lchown == NULL)) {
3015 follow_symlinks_specified("chown", follow_symlinks);
3016 goto exit;
3017 }
3018#endif
3019
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021 uid = (uid_t)uid_l;
3022 gid = (uid_t)gid_l;
3023#ifdef HAVE_FCHOWN
3024 if (path.fd != -1)
3025 result = fchown(path.fd, uid, gid);
3026 else
3027#endif
3028#ifdef HAVE_LCHOWN
3029 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3030 result = lchown(path.narrow, uid, gid);
3031 else
3032#endif
3033#ifdef HAVE_FCHOWNAT
3034 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3035 result = fchownat(dir_fd, path.narrow, uid, gid,
3036 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3037 else
3038#endif
3039 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003040 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003041
3042 if (result) {
3043 return_value = path_posix_error("chown", &path);
3044 goto exit;
3045 }
3046
3047 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049
3050exit:
3051 path_cleanup(&path);
3052 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003053}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003054#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003055
Christian Heimes4e30a842007-11-30 22:12:06 +00003056#ifdef HAVE_FCHOWN
3057PyDoc_STRVAR(posix_fchown__doc__,
3058"fchown(fd, uid, gid)\n\n\
3059Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003061
3062static PyObject *
3063posix_fchown(PyObject *self, PyObject *args)
3064{
Victor Stinner8c62be82010-05-06 00:08:46 +00003065 int fd;
3066 long uid, gid;
3067 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003068 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003069 return NULL;
3070 Py_BEGIN_ALLOW_THREADS
3071 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3072 Py_END_ALLOW_THREADS
3073 if (res < 0)
3074 return posix_error();
3075 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003076}
3077#endif /* HAVE_FCHOWN */
3078
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003079#ifdef HAVE_LCHOWN
3080PyDoc_STRVAR(posix_lchown__doc__,
3081"lchown(path, uid, gid)\n\n\
3082Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083This function will not follow symbolic links.\n\
3084Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003085
3086static PyObject *
3087posix_lchown(PyObject *self, PyObject *args)
3088{
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 PyObject *opath;
3090 char *path;
3091 long uid, gid;
3092 int res;
3093 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3094 PyUnicode_FSConverter, &opath,
3095 &uid, &gid))
3096 return NULL;
3097 path = PyBytes_AsString(opath);
3098 Py_BEGIN_ALLOW_THREADS
3099 res = lchown(path, (uid_t) uid, (gid_t) gid);
3100 Py_END_ALLOW_THREADS
3101 if (res < 0)
3102 return posix_error_with_allocated_filename(opath);
3103 Py_DECREF(opath);
3104 Py_INCREF(Py_None);
3105 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003106}
3107#endif /* HAVE_LCHOWN */
3108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003109
Guido van Rossum36bc6801995-06-14 22:54:23 +00003110#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003111static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003112posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003113{
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 char buf[1026];
3115 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003116
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003117#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003118 if (!use_bytes) {
3119 wchar_t wbuf[1026];
3120 wchar_t *wbuf2 = wbuf;
3121 PyObject *resobj;
3122 DWORD len;
3123 Py_BEGIN_ALLOW_THREADS
3124 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3125 /* If the buffer is large enough, len does not include the
3126 terminating \0. If the buffer is too small, len includes
3127 the space needed for the terminator. */
3128 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3129 wbuf2 = malloc(len * sizeof(wchar_t));
3130 if (wbuf2)
3131 len = GetCurrentDirectoryW(len, wbuf2);
3132 }
3133 Py_END_ALLOW_THREADS
3134 if (!wbuf2) {
3135 PyErr_NoMemory();
3136 return NULL;
3137 }
3138 if (!len) {
3139 if (wbuf2 != wbuf) free(wbuf2);
3140 return win32_error("getcwdu", NULL);
3141 }
3142 resobj = PyUnicode_FromWideChar(wbuf2, len);
3143 if (wbuf2 != wbuf) free(wbuf2);
3144 return resobj;
3145 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003146
3147 if (win32_warn_bytes_api())
3148 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003149#endif
3150
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003152#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003153 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003154#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003156#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003157 Py_END_ALLOW_THREADS
3158 if (res == NULL)
3159 return posix_error();
3160 if (use_bytes)
3161 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003162 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003163}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003164
3165PyDoc_STRVAR(posix_getcwd__doc__,
3166"getcwd() -> path\n\n\
3167Return a unicode string representing the current working directory.");
3168
3169static PyObject *
3170posix_getcwd_unicode(PyObject *self)
3171{
3172 return posix_getcwd(0);
3173}
3174
3175PyDoc_STRVAR(posix_getcwdb__doc__,
3176"getcwdb() -> path\n\n\
3177Return a bytes string representing the current working directory.");
3178
3179static PyObject *
3180posix_getcwd_bytes(PyObject *self)
3181{
3182 return posix_getcwd(1);
3183}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003184#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003185
Larry Hastings9cf065c2012-06-22 16:30:09 -07003186#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3187#define HAVE_LINK 1
3188#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003189
Guido van Rossumb6775db1994-08-01 11:34:53 +00003190#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003191PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3193Create a hard link to a file.\n\
3194\n\
3195If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3196 descriptor open to a directory, and the respective path string (src or dst)\n\
3197 should be relative; the path will then be relative to that directory.\n\
3198If follow_symlinks is False, and the last element of src is a symbolic\n\
3199 link, link will create a link to the symbolic link itself instead of the\n\
3200 file the link points to.\n\
3201src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3202 platform. If they are unavailable, using them will raise a\n\
3203 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003204
Barry Warsaw53699e91996-12-10 23:23:01 +00003205static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208 path_t src, dst;
3209 int src_dir_fd = DEFAULT_DIR_FD;
3210 int dst_dir_fd = DEFAULT_DIR_FD;
3211 int follow_symlinks = 1;
3212 PyObject *return_value = NULL;
3213 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3214 "follow_symlinks", NULL};
3215#ifdef MS_WINDOWS
3216 BOOL result;
3217#else
3218 int result;
3219#endif
3220
3221 memset(&src, 0, sizeof(src));
3222 memset(&dst, 0, sizeof(dst));
3223 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3224 path_converter, &src,
3225 path_converter, &dst,
3226 dir_fd_converter, &src_dir_fd,
3227 dir_fd_converter, &dst_dir_fd,
3228 &follow_symlinks))
3229 return NULL;
3230
3231#ifndef HAVE_LINKAT
3232 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3233 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3234 goto exit;
3235 }
3236#endif
3237
3238 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3239 PyErr_SetString(PyExc_NotImplementedError,
3240 "link: src and dst must be the same type");
3241 goto exit;
3242 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003243
Brian Curtin1b9df392010-11-24 20:24:31 +00003244#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 Py_BEGIN_ALLOW_THREADS
3246 if (src.wide)
3247 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3248 else
3249 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3250 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003251
Larry Hastings9cf065c2012-06-22 16:30:09 -07003252 if (!result) {
3253 return_value = win32_error_object("link", dst.object);
3254 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003255 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256#else
3257 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003258#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003259 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3260 (dst_dir_fd != DEFAULT_DIR_FD) ||
3261 (!follow_symlinks))
3262 result = linkat(src_dir_fd, src.narrow,
3263 dst_dir_fd, dst.narrow,
3264 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3265 else
3266#endif
3267 result = link(src.narrow, dst.narrow);
3268 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003269
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270 if (result) {
3271 return_value = path_error("link", &dst);
3272 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003273 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274#endif
3275
3276 return_value = Py_None;
3277 Py_INCREF(Py_None);
3278
3279exit:
3280 path_cleanup(&src);
3281 path_cleanup(&dst);
3282 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003283}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003284#endif
3285
Brian Curtin1b9df392010-11-24 20:24:31 +00003286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003287
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003288PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003289"listdir(path='.') -> list_of_filenames\n\n\
3290Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003291The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292entries '.' and '..' even if they are present in the directory.\n\
3293\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003294path can be specified as either str or bytes. If path is bytes,\n\
3295 the filenames returned will also be bytes; in all other circumstances\n\
3296 the filenames returned will be str.\n\
3297On some platforms, path may also be specified as an open file descriptor;\n\
3298 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003299 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
Barry Warsaw53699e91996-12-10 23:23:01 +00003301static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003302posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003303{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 path_t path;
3305 PyObject *list = NULL;
3306 static char *keywords[] = {"path", NULL};
3307 int fd = -1;
3308
3309#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3310 PyObject *v;
3311 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3312 BOOL result;
3313 WIN32_FIND_DATA FileData;
3314 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3315 char *bufptr = namebuf;
3316 /* only claim to have space for MAX_PATH */
3317 Py_ssize_t len = sizeof(namebuf)-5;
3318 PyObject *po = NULL;
3319 wchar_t *wnamebuf = NULL;
3320#elif defined(PYOS_OS2)
3321#ifndef MAX_PATH
3322#define MAX_PATH CCHMAXPATH
3323#endif
3324 char *pt;
3325 PyObject *v;
3326 char namebuf[MAX_PATH+5];
3327 HDIR hdir = 1;
3328 ULONG srchcnt = 1;
3329 FILEFINDBUF3 ep;
3330 APIRET rc;
3331#else
3332 PyObject *v;
3333 DIR *dirp = NULL;
3334 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003335 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336#endif
3337
3338 memset(&path, 0, sizeof(path));
3339 path.nullable = 1;
3340#ifdef HAVE_FDOPENDIR
3341 path.allow_fd = 1;
3342 path.fd = -1;
3343#endif
3344 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3345 path_converter, &path
3346 ))
3347 return NULL;
3348
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 /* XXX Should redo this putting the (now four) versions of opendir
3350 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003351#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003355
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003357 po_wchars = L".";
3358 len = 1;
3359 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 po_wchars = path.wide;
3361 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003362 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003363 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3365 if (!wnamebuf) {
3366 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003367 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003369 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003371 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 if (wch != L'/' && wch != L'\\' && wch != L':')
3373 wnamebuf[len++] = L'\\';
3374 wcscpy(wnamebuf + len, L"*.*");
3375 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376 if ((list = PyList_New(0)) == NULL) {
3377 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003379 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003381 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 if (hFindFile == INVALID_HANDLE_VALUE) {
3383 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 if (error == ERROR_FILE_NOT_FOUND)
3385 goto exit;
3386 Py_DECREF(list);
3387 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 }
3391 do {
3392 /* Skip over . and .. */
3393 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3394 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395 v = PyUnicode_FromWideChar(wFileData.cFileName,
3396 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 Py_DECREF(list);
3399 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 break;
3401 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 Py_DECREF(list);
3405 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 break;
3407 }
3408 Py_DECREF(v);
3409 }
3410 Py_BEGIN_ALLOW_THREADS
3411 result = FindNextFileW(hFindFile, &wFileData);
3412 Py_END_ALLOW_THREADS
3413 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3414 it got to the end of the directory. */
3415 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 Py_DECREF(list);
3417 list = win32_error_unicode("FindNextFileW", wnamebuf);
3418 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 }
3420 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003421
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 strcpy(namebuf, path.narrow);
3425 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 if (len > 0) {
3427 char ch = namebuf[len-1];
3428 if (ch != SEP && ch != ALTSEP && ch != ':')
3429 namebuf[len++] = '/';
3430 strcpy(namebuf + len, "*.*");
3431 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003432
Larry Hastings9cf065c2012-06-22 16:30:09 -07003433 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003435
Antoine Pitroub73caab2010-08-09 23:39:31 +00003436 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003438 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 if (hFindFile == INVALID_HANDLE_VALUE) {
3440 int error = GetLastError();
3441 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 goto exit;
3443 Py_DECREF(list);
3444 list = win32_error("FindFirstFile", namebuf);
3445 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 }
3447 do {
3448 /* Skip over . and .. */
3449 if (strcmp(FileData.cFileName, ".") != 0 &&
3450 strcmp(FileData.cFileName, "..") != 0) {
3451 v = PyBytes_FromString(FileData.cFileName);
3452 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 Py_DECREF(list);
3454 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 break;
3456 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 Py_DECREF(list);
3460 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 break;
3462 }
3463 Py_DECREF(v);
3464 }
3465 Py_BEGIN_ALLOW_THREADS
3466 result = FindNextFile(hFindFile, &FileData);
3467 Py_END_ALLOW_THREADS
3468 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3469 it got to the end of the directory. */
3470 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 Py_DECREF(list);
3472 list = win32_error("FindNextFile", namebuf);
3473 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 }
3475 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003476
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477exit:
3478 if (hFindFile != INVALID_HANDLE_VALUE) {
3479 if (FindClose(hFindFile) == FALSE) {
3480 if (list != NULL) {
3481 Py_DECREF(list);
3482 list = win32_error_object("FindClose", path.object);
3483 }
3484 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003486 if (wnamebuf)
3487 free(wnamebuf);
3488 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003489
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003491
Tim Peters0bb44a42000-09-15 07:44:49 +00003492#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003494 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003496 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003498 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003499 if (*pt == ALTSEP)
3500 *pt = SEP;
3501 if (namebuf[len-1] != SEP)
3502 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003503 strcpy(namebuf + len, "*.*");
3504
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 if ((list = PyList_New(0)) == NULL) {
3506 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003507 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003509 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3510 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003511 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003512 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3513 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3514 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003515
3516 if (rc != NO_ERROR) {
3517 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_DECREF(list);
3519 list = posix_error_with_filename(path.narrow);
3520 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003521 }
3522
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003523 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524 do {
3525 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003526 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003527 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003528
3529 strcpy(namebuf, ep.achName);
3530
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003531 /* Leave Case of Name Alone -- In Native Form */
3532 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003533
Christian Heimes72b710a2008-05-26 13:28:38 +00003534 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003535 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 Py_DECREF(list);
3537 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538 break;
3539 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003541 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 Py_DECREF(list);
3543 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003544 break;
3545 }
3546 Py_DECREF(v);
3547 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3548 }
3549
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550exit:
3551 path_cleanup(&path);
3552
3553 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003554#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003555
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557#ifdef HAVE_FDOPENDIR
3558 if (path.fd != -1) {
3559 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003560 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003562 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563
3564 if (fd == -1) {
3565 list = posix_error();
3566 goto exit;
3567 }
3568
Larry Hastingsfdaea062012-06-25 04:42:23 -07003569 return_str = 1;
3570
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 Py_BEGIN_ALLOW_THREADS
3572 dirp = fdopendir(fd);
3573 Py_END_ALLOW_THREADS
3574 }
3575 else
3576#endif
3577 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003578 char *name;
3579 if (path.narrow) {
3580 name = path.narrow;
3581 /* only return bytes if they specified a bytes object */
3582 return_str = !(PyBytes_Check(path.object));
3583 }
3584 else {
3585 name = ".";
3586 return_str = 1;
3587 }
3588
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 Py_BEGIN_ALLOW_THREADS
3590 dirp = opendir(name);
3591 Py_END_ALLOW_THREADS
3592 }
3593
3594 if (dirp == NULL) {
3595 list = path_error("listdir", &path);
3596 goto exit;
3597 }
3598 if ((list = PyList_New(0)) == NULL) {
3599 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 }
3601 for (;;) {
3602 errno = 0;
3603 Py_BEGIN_ALLOW_THREADS
3604 ep = readdir(dirp);
3605 Py_END_ALLOW_THREADS
3606 if (ep == NULL) {
3607 if (errno == 0) {
3608 break;
3609 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 Py_DECREF(list);
3611 list = path_error("listdir", &path);
3612 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 }
3614 }
3615 if (ep->d_name[0] == '.' &&
3616 (NAMLEN(ep) == 1 ||
3617 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3618 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003619 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003620 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3621 else
3622 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 break;
3626 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 break;
3631 }
3632 Py_DECREF(v);
3633 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003634
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635exit:
3636 if (dirp != NULL) {
3637 Py_BEGIN_ALLOW_THREADS
3638 if (fd > -1)
3639 rewinddir(dirp);
3640 closedir(dirp);
3641 Py_END_ALLOW_THREADS
3642 }
3643
3644 path_cleanup(&path);
3645
3646 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003647
Tim Peters0bb44a42000-09-15 07:44:49 +00003648#endif /* which OS */
3649} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003650
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003651#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003652/* A helper function for abspath on win32 */
3653static PyObject *
3654posix__getfullpathname(PyObject *self, PyObject *args)
3655{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003656 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 char outbuf[MAX_PATH*2];
3658 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003659 PyObject *po;
3660
3661 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3662 {
3663 wchar_t *wpath;
3664 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3665 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 DWORD result;
3667 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003668
3669 wpath = PyUnicode_AsUnicode(po);
3670 if (wpath == NULL)
3671 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003673 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003674 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003675 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003676 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (!woutbufp)
3678 return PyErr_NoMemory();
3679 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3680 }
3681 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003682 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003684 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 if (woutbufp != woutbuf)
3686 free(woutbufp);
3687 return v;
3688 }
3689 /* Drop the argument parsing error as narrow strings
3690 are also valid. */
3691 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003692
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003693 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3694 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003696 if (win32_warn_bytes_api())
3697 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003698 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 outbuf, &temp)) {
3700 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 return NULL;
3702 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3704 return PyUnicode_Decode(outbuf, strlen(outbuf),
3705 Py_FileSystemDefaultEncoding, NULL);
3706 }
3707 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003708} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003709
Brian Curtind25aef52011-06-13 15:16:04 -05003710
Brian Curtinf5e76d02010-11-24 13:14:05 +00003711
Brian Curtind40e6f72010-07-08 21:39:08 +00003712/* A helper function for samepath on windows */
3713static PyObject *
3714posix__getfinalpathname(PyObject *self, PyObject *args)
3715{
3716 HANDLE hFile;
3717 int buf_size;
3718 wchar_t *target_path;
3719 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003720 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003721 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003722
Victor Stinnereb5657a2011-09-30 01:44:27 +02003723 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003724 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003725 path = PyUnicode_AsUnicode(po);
3726 if (path == NULL)
3727 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003728
3729 if(!check_GetFinalPathNameByHandle()) {
3730 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3731 NotImplementedError. */
3732 return PyErr_Format(PyExc_NotImplementedError,
3733 "GetFinalPathNameByHandle not available on this platform");
3734 }
3735
3736 hFile = CreateFileW(
3737 path,
3738 0, /* desired access */
3739 0, /* share mode */
3740 NULL, /* security attributes */
3741 OPEN_EXISTING,
3742 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3743 FILE_FLAG_BACKUP_SEMANTICS,
3744 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003745
Victor Stinnereb5657a2011-09-30 01:44:27 +02003746 if(hFile == INVALID_HANDLE_VALUE)
3747 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003748
3749 /* We have a good handle to the target, use it to determine the
3750 target path name. */
3751 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3752
3753 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003754 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003755
3756 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3757 if(!target_path)
3758 return PyErr_NoMemory();
3759
3760 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3761 buf_size, VOLUME_NAME_DOS);
3762 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003763 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003764
3765 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003766 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003767
3768 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003769 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003770 free(target_path);
3771 return result;
3772
3773} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003774
3775static PyObject *
3776posix__getfileinformation(PyObject *self, PyObject *args)
3777{
3778 HANDLE hFile;
3779 BY_HANDLE_FILE_INFORMATION info;
3780 int fd;
3781
3782 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3783 return NULL;
3784
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003785 if (!_PyVerify_fd(fd))
3786 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003787
3788 hFile = (HANDLE)_get_osfhandle(fd);
3789 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003790 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003791
3792 if (!GetFileInformationByHandle(hFile, &info))
3793 return win32_error("_getfileinformation", NULL);
3794
3795 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3796 info.nFileIndexHigh,
3797 info.nFileIndexLow);
3798}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003799
Brian Curtin95d028f2011-06-09 09:10:38 -05003800PyDoc_STRVAR(posix__isdir__doc__,
3801"Return true if the pathname refers to an existing directory.");
3802
Brian Curtin9c669cc2011-06-08 18:17:18 -05003803static PyObject *
3804posix__isdir(PyObject *self, PyObject *args)
3805{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003806 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003808 DWORD attributes;
3809
3810 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003811 wchar_t *wpath = PyUnicode_AsUnicode(po);
3812 if (wpath == NULL)
3813 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814
3815 attributes = GetFileAttributesW(wpath);
3816 if (attributes == INVALID_FILE_ATTRIBUTES)
3817 Py_RETURN_FALSE;
3818 goto check;
3819 }
3820 /* Drop the argument parsing error as narrow strings
3821 are also valid. */
3822 PyErr_Clear();
3823
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003824 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003825 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003826 if (win32_warn_bytes_api())
3827 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003828 attributes = GetFileAttributesA(path);
3829 if (attributes == INVALID_FILE_ATTRIBUTES)
3830 Py_RETURN_FALSE;
3831
3832check:
3833 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3834 Py_RETURN_TRUE;
3835 else
3836 Py_RETURN_FALSE;
3837}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003838#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003839
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003840PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3842Create a directory.\n\
3843\n\
3844If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3845 and path should be relative; path will then be relative to that directory.\n\
3846dir_fd may not be implemented on your platform.\n\
3847 If it is unavailable, using it will raise a NotImplementedError.\n\
3848\n\
3849The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003850
Barry Warsaw53699e91996-12-10 23:23:01 +00003851static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003852posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003853{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003854 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003856 int dir_fd = DEFAULT_DIR_FD;
3857 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3858 PyObject *return_value = NULL;
3859 int result;
3860
3861 memset(&path, 0, sizeof(path));
3862 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3863 path_converter, &path, &mode,
3864#ifdef HAVE_MKDIRAT
3865 dir_fd_converter, &dir_fd
3866#else
3867 dir_fd_unavailable, &dir_fd
3868#endif
3869 ))
3870 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003871
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003872#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003874 if (path.wide)
3875 result = CreateDirectoryW(path.wide, NULL);
3876 else
3877 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003879
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880 if (!result) {
3881 return_value = win32_error_object("mkdir", path.object);
3882 goto exit;
3883 }
3884#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003886#if HAVE_MKDIRAT
3887 if (dir_fd != DEFAULT_DIR_FD)
3888 result = mkdirat(dir_fd, path.narrow, mode);
3889 else
3890#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003891#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003892 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003893#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003894 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003895#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003897 if (result < 0) {
3898 return_value = path_error("mkdir", &path);
3899 goto exit;
3900 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003901#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902 return_value = Py_None;
3903 Py_INCREF(Py_None);
3904exit:
3905 path_cleanup(&path);
3906 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003907}
3908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003909
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003910/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3911#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003912#include <sys/resource.h>
3913#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003914
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003915
3916#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003918"nice(inc) -> new_priority\n\n\
3919Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003920
Barry Warsaw53699e91996-12-10 23:23:01 +00003921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003922posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003923{
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003925
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3927 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003928
Victor Stinner8c62be82010-05-06 00:08:46 +00003929 /* There are two flavours of 'nice': one that returns the new
3930 priority (as required by almost all standards out there) and the
3931 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3932 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003933
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 If we are of the nice family that returns the new priority, we
3935 need to clear errno before the call, and check if errno is filled
3936 before calling posix_error() on a returnvalue of -1, because the
3937 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003938
Victor Stinner8c62be82010-05-06 00:08:46 +00003939 errno = 0;
3940 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003941#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003942 if (value == 0)
3943 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003945 if (value == -1 && errno != 0)
3946 /* either nice() or getpriority() returned an error */
3947 return posix_error();
3948 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003949}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003950#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003951
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003952
3953#ifdef HAVE_GETPRIORITY
3954PyDoc_STRVAR(posix_getpriority__doc__,
3955"getpriority(which, who) -> current_priority\n\n\
3956Get program scheduling priority.");
3957
3958static PyObject *
3959posix_getpriority(PyObject *self, PyObject *args)
3960{
3961 int which, who, retval;
3962
3963 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3964 return NULL;
3965 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003966 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003967 if (errno != 0)
3968 return posix_error();
3969 return PyLong_FromLong((long)retval);
3970}
3971#endif /* HAVE_GETPRIORITY */
3972
3973
3974#ifdef HAVE_SETPRIORITY
3975PyDoc_STRVAR(posix_setpriority__doc__,
3976"setpriority(which, who, prio) -> None\n\n\
3977Set program scheduling priority.");
3978
3979static PyObject *
3980posix_setpriority(PyObject *self, PyObject *args)
3981{
3982 int which, who, prio, retval;
3983
3984 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3985 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003986 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003987 if (retval == -1)
3988 return posix_error();
3989 Py_RETURN_NONE;
3990}
3991#endif /* HAVE_SETPRIORITY */
3992
3993
Barry Warsaw53699e91996-12-10 23:23:01 +00003994static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003996{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 char *function_name = is_replace ? "replace" : "rename";
3998 path_t src;
3999 path_t dst;
4000 int src_dir_fd = DEFAULT_DIR_FD;
4001 int dst_dir_fd = DEFAULT_DIR_FD;
4002 int dir_fd_specified;
4003 PyObject *return_value = NULL;
4004 char format[24];
4005 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4006
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004007#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004009 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004010#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004011 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004012#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013
4014 memset(&src, 0, sizeof(src));
4015 memset(&dst, 0, sizeof(dst));
4016 strcpy(format, "O&O&|$O&O&:");
4017 strcat(format, function_name);
4018 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4019 path_converter, &src,
4020 path_converter, &dst,
4021 dir_fd_converter, &src_dir_fd,
4022 dir_fd_converter, &dst_dir_fd))
4023 return NULL;
4024
4025 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4026 (dst_dir_fd != DEFAULT_DIR_FD);
4027#ifndef HAVE_RENAMEAT
4028 if (dir_fd_specified) {
4029 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4030 goto exit;
4031 }
4032#endif
4033
4034 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4035 PyErr_Format(PyExc_ValueError,
4036 "%s: src and dst must be the same type", function_name);
4037 goto exit;
4038 }
4039
4040#ifdef MS_WINDOWS
4041 Py_BEGIN_ALLOW_THREADS
4042 if (src.wide)
4043 result = MoveFileExW(src.wide, dst.wide, flags);
4044 else
4045 result = MoveFileExA(src.narrow, dst.narrow, flags);
4046 Py_END_ALLOW_THREADS
4047
4048 if (!result) {
4049 return_value = win32_error_object(function_name, dst.object);
4050 goto exit;
4051 }
4052
4053#else
4054 Py_BEGIN_ALLOW_THREADS
4055#ifdef HAVE_RENAMEAT
4056 if (dir_fd_specified)
4057 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4058 else
4059#endif
4060 result = rename(src.narrow, dst.narrow);
4061 Py_END_ALLOW_THREADS
4062
4063 if (result) {
4064 return_value = path_error(function_name, &dst);
4065 goto exit;
4066 }
4067#endif
4068
4069 Py_INCREF(Py_None);
4070 return_value = Py_None;
4071exit:
4072 path_cleanup(&src);
4073 path_cleanup(&dst);
4074 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004075}
4076
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004077PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4079Rename a file or directory.\n\
4080\n\
4081If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4082 descriptor open to a directory, and the respective path string (src or dst)\n\
4083 should be relative; the path will then be relative to that directory.\n\
4084src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4085 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004086
4087static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004089{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004091}
4092
4093PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4095Rename a file or directory, overwriting the destination.\n\
4096\n\
4097If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4098 descriptor open to a directory, and the respective path string (src or dst)\n\
4099 should be relative; the path will then be relative to that directory.\n\
4100src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4101 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004102
4103static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004108
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110"rmdir(path, *, dir_fd=None)\n\n\
4111Remove a directory.\n\
4112\n\
4113If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4114 and path should be relative; path will then be relative to that directory.\n\
4115dir_fd may not be implemented on your platform.\n\
4116 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004117
Barry Warsaw53699e91996-12-10 23:23:01 +00004118static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004119posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004120{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004121 path_t path;
4122 int dir_fd = DEFAULT_DIR_FD;
4123 static char *keywords[] = {"path", "dir_fd", NULL};
4124 int result;
4125 PyObject *return_value = NULL;
4126
4127 memset(&path, 0, sizeof(path));
4128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4129 path_converter, &path,
4130#ifdef HAVE_UNLINKAT
4131 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004132#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004133 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004134#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004135 ))
4136 return NULL;
4137
4138 Py_BEGIN_ALLOW_THREADS
4139#ifdef MS_WINDOWS
4140 if (path.wide)
4141 result = RemoveDirectoryW(path.wide);
4142 else
4143 result = RemoveDirectoryA(path.narrow);
4144 result = !result; /* Windows, success=1, UNIX, success=0 */
4145#else
4146#ifdef HAVE_UNLINKAT
4147 if (dir_fd != DEFAULT_DIR_FD)
4148 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4149 else
4150#endif
4151 result = rmdir(path.narrow);
4152#endif
4153 Py_END_ALLOW_THREADS
4154
4155 if (result) {
4156 return_value = path_error("rmdir", &path);
4157 goto exit;
4158 }
4159
4160 return_value = Py_None;
4161 Py_INCREF(Py_None);
4162
4163exit:
4164 path_cleanup(&path);
4165 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004166}
4167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004168
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004169#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004170PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004171"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004172Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004173
Barry Warsaw53699e91996-12-10 23:23:01 +00004174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004175posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004176{
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004178#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004179 wchar_t *command;
4180 if (!PyArg_ParseTuple(args, "u:system", &command))
4181 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004182
Victor Stinner8c62be82010-05-06 00:08:46 +00004183 Py_BEGIN_ALLOW_THREADS
4184 sts = _wsystem(command);
4185 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004186#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 PyObject *command_obj;
4188 char *command;
4189 if (!PyArg_ParseTuple(args, "O&:system",
4190 PyUnicode_FSConverter, &command_obj))
4191 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004192
Victor Stinner8c62be82010-05-06 00:08:46 +00004193 command = PyBytes_AsString(command_obj);
4194 Py_BEGIN_ALLOW_THREADS
4195 sts = system(command);
4196 Py_END_ALLOW_THREADS
4197 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004198#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004200}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004201#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004204PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004205"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004206Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Barry Warsaw53699e91996-12-10 23:23:01 +00004208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004209posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004210{
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 int i;
4212 if (!PyArg_ParseTuple(args, "i:umask", &i))
4213 return NULL;
4214 i = (int)umask(i);
4215 if (i < 0)
4216 return posix_error();
4217 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004218}
4219
Brian Curtind40e6f72010-07-08 21:39:08 +00004220#ifdef MS_WINDOWS
4221
4222/* override the default DeleteFileW behavior so that directory
4223symlinks can be removed with this function, the same as with
4224Unix symlinks */
4225BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4226{
4227 WIN32_FILE_ATTRIBUTE_DATA info;
4228 WIN32_FIND_DATAW find_data;
4229 HANDLE find_data_handle;
4230 int is_directory = 0;
4231 int is_link = 0;
4232
4233 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4234 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004235
Brian Curtind40e6f72010-07-08 21:39:08 +00004236 /* Get WIN32_FIND_DATA structure for the path to determine if
4237 it is a symlink */
4238 if(is_directory &&
4239 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4240 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4241
4242 if(find_data_handle != INVALID_HANDLE_VALUE) {
4243 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4244 FindClose(find_data_handle);
4245 }
4246 }
4247 }
4248
4249 if (is_directory && is_link)
4250 return RemoveDirectoryW(lpFileName);
4251
4252 return DeleteFileW(lpFileName);
4253}
4254#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004256PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004257"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004258Remove a file (same as remove()).\n\
4259\n\
4260If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4261 and path should be relative; path will then be relative to that directory.\n\
4262dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004263 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004265PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004266"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004267Remove a file (same as unlink()).\n\
4268\n\
4269If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4270 and path should be relative; path will then be relative to that directory.\n\
4271dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004272 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004273
Barry Warsaw53699e91996-12-10 23:23:01 +00004274static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004275posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004276{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277 path_t path;
4278 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004279 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004280 int result;
4281 PyObject *return_value = NULL;
4282
4283 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004284 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004285 path_converter, &path,
4286#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004287 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004288#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004289 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004290#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004291 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004292 return NULL;
4293
4294 Py_BEGIN_ALLOW_THREADS
4295#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004296 if (path.wide)
4297 result = Py_DeleteFileW(path.wide);
4298 else
4299 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004300 result = !result; /* Windows, success=1, UNIX, success=0 */
4301#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302#ifdef HAVE_UNLINKAT
4303 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004304 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305 else
4306#endif /* HAVE_UNLINKAT */
4307 result = unlink(path.narrow);
4308#endif
4309 Py_END_ALLOW_THREADS
4310
4311 if (result) {
4312 return_value = path_error("unlink", &path);
4313 goto exit;
4314 }
4315
4316 return_value = Py_None;
4317 Py_INCREF(Py_None);
4318
4319exit:
4320 path_cleanup(&path);
4321 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004322}
4323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004326"uname() -> uname_result\n\n\
4327Return an object identifying the current operating system.\n\
4328The object behaves like a named tuple with the following fields:\n\
4329 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Larry Hastings605a62d2012-06-24 04:33:36 -07004331static PyStructSequence_Field uname_result_fields[] = {
4332 {"sysname", "operating system name"},
4333 {"nodename", "name of machine on network (implementation-defined)"},
4334 {"release", "operating system release"},
4335 {"version", "operating system version"},
4336 {"machine", "hardware identifier"},
4337 {NULL}
4338};
4339
4340PyDoc_STRVAR(uname_result__doc__,
4341"uname_result: Result from os.uname().\n\n\
4342This object may be accessed either as a tuple of\n\
4343 (sysname, nodename, release, version, machine),\n\
4344or via the attributes sysname, nodename, release, version, and machine.\n\
4345\n\
4346See os.uname for more information.");
4347
4348static PyStructSequence_Desc uname_result_desc = {
4349 "uname_result", /* name */
4350 uname_result__doc__, /* doc */
4351 uname_result_fields,
4352 5
4353};
4354
4355static PyTypeObject UnameResultType;
4356
4357
4358#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004360posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004361{
Victor Stinner8c62be82010-05-06 00:08:46 +00004362 struct utsname u;
4363 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004364 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004365
Victor Stinner8c62be82010-05-06 00:08:46 +00004366 Py_BEGIN_ALLOW_THREADS
4367 res = uname(&u);
4368 Py_END_ALLOW_THREADS
4369 if (res < 0)
4370 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004371
4372 value = PyStructSequence_New(&UnameResultType);
4373 if (value == NULL)
4374 return NULL;
4375
4376#define SET(i, field) \
4377 { \
4378 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4379 if (!o) { \
4380 Py_DECREF(value); \
4381 return NULL; \
4382 } \
4383 PyStructSequence_SET_ITEM(value, i, o); \
4384 } \
4385
4386 SET(0, u.sysname);
4387 SET(1, u.nodename);
4388 SET(2, u.release);
4389 SET(3, u.version);
4390 SET(4, u.machine);
4391
4392#undef SET
4393
4394 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004395}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004396#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004397
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004398
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399PyDoc_STRVAR(posix_utime__doc__,
4400"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4401Set the access and modified time of path.\n\
4402\n\
4403path may always be specified as a string.\n\
4404On some platforms, path may also be specified as an open file descriptor.\n\
4405 If this functionality is unavailable, using it raises an exception.\n\
4406\n\
4407If times is not None, it must be a tuple (atime, mtime);\n\
4408 atime and mtime should be expressed as float seconds since the epoch.\n\
4409If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4410 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4411 since the epoch.\n\
4412If both times and ns are None, utime uses the current time.\n\
4413Specifying tuples for both times and ns is an error.\n\
4414\n\
4415If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4416 and path should be relative; path will then be relative to that directory.\n\
4417If follow_symlinks is False, and the last element of the path is a symbolic\n\
4418 link, utime will modify the symbolic link itself instead of the file the\n\
4419 link points to.\n\
4420It is an error to use dir_fd or follow_symlinks when specifying path\n\
4421 as an open file descriptor.\n\
4422dir_fd and follow_symlinks may not be available on your platform.\n\
4423 If they are unavailable, using them will raise a NotImplementedError.");
4424
4425typedef struct {
4426 int now;
4427 time_t atime_s;
4428 long atime_ns;
4429 time_t mtime_s;
4430 long mtime_ns;
4431} utime_t;
4432
4433/*
4434 * these macros assume that "utime" is a pointer to a utime_t
4435 * they also intentionally leak the declaration of a pointer named "time"
4436 */
4437#define UTIME_TO_TIMESPEC \
4438 struct timespec ts[2]; \
4439 struct timespec *time; \
4440 if (utime->now) \
4441 time = NULL; \
4442 else { \
4443 ts[0].tv_sec = utime->atime_s; \
4444 ts[0].tv_nsec = utime->atime_ns; \
4445 ts[1].tv_sec = utime->mtime_s; \
4446 ts[1].tv_nsec = utime->mtime_ns; \
4447 time = ts; \
4448 } \
4449
4450#define UTIME_TO_TIMEVAL \
4451 struct timeval tv[2]; \
4452 struct timeval *time; \
4453 if (utime->now) \
4454 time = NULL; \
4455 else { \
4456 tv[0].tv_sec = utime->atime_s; \
4457 tv[0].tv_usec = utime->atime_ns / 1000; \
4458 tv[1].tv_sec = utime->mtime_s; \
4459 tv[1].tv_usec = utime->mtime_ns / 1000; \
4460 time = tv; \
4461 } \
4462
4463#define UTIME_TO_UTIMBUF \
4464 struct utimbuf u[2]; \
4465 struct utimbuf *time; \
4466 if (utime->now) \
4467 time = NULL; \
4468 else { \
4469 u.actime = utime->atime_s; \
4470 u.modtime = utime->mtime_s; \
4471 time = u; \
4472 }
4473
4474#define UTIME_TO_TIME_T \
4475 time_t timet[2]; \
4476 struct timet time; \
4477 if (utime->now) \
4478 time = NULL; \
4479 else { \
4480 timet[0] = utime->atime_s; \
4481 timet[1] = utime->mtime_s; \
4482 time = &timet; \
4483 } \
4484
4485
4486#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4487
4488#if UTIME_HAVE_DIR_FD
4489
4490static int
4491utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4492{
4493#ifdef HAVE_UTIMENSAT
4494 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4495 UTIME_TO_TIMESPEC;
4496 return utimensat(dir_fd, path, time, flags);
4497#elif defined(HAVE_FUTIMESAT)
4498 UTIME_TO_TIMEVAL;
4499 /*
4500 * follow_symlinks will never be false here;
4501 * we only allow !follow_symlinks and dir_fd together
4502 * if we have utimensat()
4503 */
4504 assert(follow_symlinks);
4505 return futimesat(dir_fd, path, time);
4506#endif
4507}
4508
4509#endif
4510
4511#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4512
4513#if UTIME_HAVE_FD
4514
4515static int
4516utime_fd(utime_t *utime, int fd)
4517{
4518#ifdef HAVE_FUTIMENS
4519 UTIME_TO_TIMESPEC;
4520 return futimens(fd, time);
4521#else
4522 UTIME_TO_TIMEVAL;
4523 return futimes(fd, time);
4524#endif
4525}
4526
4527#endif
4528
4529
4530#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4531 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4532
4533#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4534
4535static int
4536utime_nofollow_symlinks(utime_t *utime, char *path)
4537{
4538#ifdef HAVE_UTIMENSAT
4539 UTIME_TO_TIMESPEC;
4540 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4541#else
4542 UTIME_TO_TIMEVAL;
4543 return lutimes(path, time);
4544#endif
4545}
4546
4547#endif
4548
4549#ifndef MS_WINDOWS
4550
4551static int
4552utime_default(utime_t *utime, char *path)
4553{
4554#ifdef HAVE_UTIMENSAT
4555 UTIME_TO_TIMESPEC;
4556 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4557#elif defined(HAVE_UTIMES)
4558 UTIME_TO_TIMEVAL;
4559 return utimes(path, time);
4560#elif defined(HAVE_UTIME_H)
4561 UTIME_TO_UTIMBUF;
4562 return utime(path, time);
4563#else
4564 UTIME_TO_TIME_T;
4565 return utime(path, time);
4566#endif
4567}
4568
4569#endif
4570
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571static int
4572split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4573{
4574 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004575 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004576 divmod = PyNumber_Divmod(py_long, billion);
4577 if (!divmod)
4578 goto exit;
4579 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4580 if ((*s == -1) && PyErr_Occurred())
4581 goto exit;
4582 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004583 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004584 goto exit;
4585
4586 result = 1;
4587exit:
4588 Py_XDECREF(divmod);
4589 return result;
4590}
4591
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592static PyObject *
4593posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004594{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004596 PyObject *times = NULL;
4597 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 int dir_fd = DEFAULT_DIR_FD;
4599 int follow_symlinks = 1;
4600 char *keywords[] = {"path", "times", "ns", "dir_fd",
4601 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004602
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004604
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605#ifdef MS_WINDOWS
4606 HANDLE hFile;
4607 FILETIME atime, mtime;
4608#else
4609 int result;
4610#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004611
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004613
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614 memset(&path, 0, sizeof(path));
4615#if UTIME_HAVE_FD
4616 path.allow_fd = 1;
4617#endif
4618 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4619 "O&|O$OO&p:utime", keywords,
4620 path_converter, &path,
4621 &times, &ns,
4622#if UTIME_HAVE_DIR_FD
4623 dir_fd_converter, &dir_fd,
4624#else
4625 dir_fd_unavailable, &dir_fd,
4626#endif
4627 &follow_symlinks
4628 ))
4629 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004630
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 if (times && (times != Py_None) && ns) {
4632 PyErr_SetString(PyExc_ValueError,
4633 "utime: you may specify either 'times'"
4634 " or 'ns' but not both");
4635 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004636 }
4637
4638 if (times && (times != Py_None)) {
4639 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 PyErr_SetString(PyExc_TypeError,
4641 "utime: 'times' must be either"
4642 " a tuple of two ints or None");
4643 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004644 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004646 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004648 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 &utime.mtime_s, &utime.mtime_ns) == -1) {
4650 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004651 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004652 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004654 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 PyErr_SetString(PyExc_TypeError,
4656 "utime: 'ns' must be a tuple of two ints");
4657 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004660 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004662 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 &utime.mtime_s, &utime.mtime_ns)) {
4664 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004665 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 }
4667 else {
4668 /* times and ns are both None/unspecified. use "now". */
4669 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670 }
4671
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4673 if (follow_symlinks_specified("utime", follow_symlinks))
4674 goto exit;
4675#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004676
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4678 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4679 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4680 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682#if !defined(HAVE_UTIMENSAT)
4683 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004684 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685 "utime: cannot use dir_fd and follow_symlinks "
4686 "together on this platform");
4687 goto exit;
4688 }
4689#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004690
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004691#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 Py_BEGIN_ALLOW_THREADS
4693 if (path.wide)
4694 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004695 NULL, OPEN_EXISTING,
4696 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 else
4698 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004699 NULL, OPEN_EXISTING,
4700 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 Py_END_ALLOW_THREADS
4702 if (hFile == INVALID_HANDLE_VALUE) {
4703 win32_error_object("utime", path.object);
4704 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004705 }
4706
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 SYSTEMTIME now;
4709 GetSystemTime(&now);
4710 if (!SystemTimeToFileTime(&now, &mtime) ||
4711 !SystemTimeToFileTime(&now, &atime)) {
4712 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004714 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004716 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4718 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004719 }
4720 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4721 /* Avoid putting the file name into the error here,
4722 as that may confuse the user into believing that
4723 something is wrong with the file, when it also
4724 could be the time stamp that gives a problem. */
4725 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004728#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4732 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4733 result = utime_nofollow_symlinks(&utime, path.narrow);
4734 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004735#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736
4737#if UTIME_HAVE_DIR_FD
4738 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4739 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4740 else
4741#endif
4742
4743#if UTIME_HAVE_FD
4744 if (path.fd != -1)
4745 result = utime_fd(&utime, path.fd);
4746 else
4747#endif
4748
4749 result = utime_default(&utime, path.narrow);
4750
4751 Py_END_ALLOW_THREADS
4752
4753 if (result < 0) {
4754 /* see previous comment about not putting filename in error here */
4755 return_value = posix_error();
4756 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004759#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760
4761 Py_INCREF(Py_None);
4762 return_value = Py_None;
4763
4764exit:
4765 path_cleanup(&path);
4766#ifdef MS_WINDOWS
4767 if (hFile != INVALID_HANDLE_VALUE)
4768 CloseHandle(hFile);
4769#endif
4770 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004771}
4772
Guido van Rossum3b066191991-06-04 19:40:25 +00004773/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004774
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004778
Barry Warsaw53699e91996-12-10 23:23:01 +00004779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004780posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004781{
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 int sts;
4783 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4784 return NULL;
4785 _exit(sts);
4786 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004787}
4788
Martin v. Löwis114619e2002-10-07 06:44:21 +00004789#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4790static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004791free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004792{
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 Py_ssize_t i;
4794 for (i = 0; i < count; i++)
4795 PyMem_Free(array[i]);
4796 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004797}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004798
Antoine Pitrou69f71142009-05-24 21:25:49 +00004799static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004800int fsconvert_strdup(PyObject *o, char**out)
4801{
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 PyObject *bytes;
4803 Py_ssize_t size;
4804 if (!PyUnicode_FSConverter(o, &bytes))
4805 return 0;
4806 size = PyBytes_GET_SIZE(bytes);
4807 *out = PyMem_Malloc(size+1);
4808 if (!*out)
4809 return 0;
4810 memcpy(*out, PyBytes_AsString(bytes), size+1);
4811 Py_DECREF(bytes);
4812 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004813}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004814#endif
4815
Ross Lagerwall7807c352011-03-17 20:20:30 +02004816#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004817static char**
4818parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4819{
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 char **envlist;
4821 Py_ssize_t i, pos, envc;
4822 PyObject *keys=NULL, *vals=NULL;
4823 PyObject *key, *val, *key2, *val2;
4824 char *p, *k, *v;
4825 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004826
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 i = PyMapping_Size(env);
4828 if (i < 0)
4829 return NULL;
4830 envlist = PyMem_NEW(char *, i + 1);
4831 if (envlist == NULL) {
4832 PyErr_NoMemory();
4833 return NULL;
4834 }
4835 envc = 0;
4836 keys = PyMapping_Keys(env);
4837 vals = PyMapping_Values(env);
4838 if (!keys || !vals)
4839 goto error;
4840 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4841 PyErr_Format(PyExc_TypeError,
4842 "env.keys() or env.values() is not a list");
4843 goto error;
4844 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004845
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 for (pos = 0; pos < i; pos++) {
4847 key = PyList_GetItem(keys, pos);
4848 val = PyList_GetItem(vals, pos);
4849 if (!key || !val)
4850 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004851
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 if (PyUnicode_FSConverter(key, &key2) == 0)
4853 goto error;
4854 if (PyUnicode_FSConverter(val, &val2) == 0) {
4855 Py_DECREF(key2);
4856 goto error;
4857 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004858
4859#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4861 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004862#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 k = PyBytes_AsString(key2);
4864 v = PyBytes_AsString(val2);
4865 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004866
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 p = PyMem_NEW(char, len);
4868 if (p == NULL) {
4869 PyErr_NoMemory();
4870 Py_DECREF(key2);
4871 Py_DECREF(val2);
4872 goto error;
4873 }
4874 PyOS_snprintf(p, len, "%s=%s", k, v);
4875 envlist[envc++] = p;
4876 Py_DECREF(key2);
4877 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004878#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004879 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004880#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 }
4882 Py_DECREF(vals);
4883 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004884
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 envlist[envc] = 0;
4886 *envc_ptr = envc;
4887 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004888
4889error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 Py_XDECREF(keys);
4891 Py_XDECREF(vals);
4892 while (--envc >= 0)
4893 PyMem_DEL(envlist[envc]);
4894 PyMem_DEL(envlist);
4895 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004896}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004897
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898static char**
4899parse_arglist(PyObject* argv, Py_ssize_t *argc)
4900{
4901 int i;
4902 char **argvlist = PyMem_NEW(char *, *argc+1);
4903 if (argvlist == NULL) {
4904 PyErr_NoMemory();
4905 return NULL;
4906 }
4907 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004908 PyObject* item = PySequence_ITEM(argv, i);
4909 if (item == NULL)
4910 goto fail;
4911 if (!fsconvert_strdup(item, &argvlist[i])) {
4912 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004913 goto fail;
4914 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004915 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004916 }
4917 argvlist[*argc] = NULL;
4918 return argvlist;
4919fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004920 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004921 free_string_array(argvlist, *argc);
4922 return NULL;
4923}
4924#endif
4925
4926#ifdef HAVE_EXECV
4927PyDoc_STRVAR(posix_execv__doc__,
4928"execv(path, args)\n\n\
4929Execute an executable path with arguments, replacing current process.\n\
4930\n\
4931 path: path of executable file\n\
4932 args: tuple or list of strings");
4933
4934static PyObject *
4935posix_execv(PyObject *self, PyObject *args)
4936{
4937 PyObject *opath;
4938 char *path;
4939 PyObject *argv;
4940 char **argvlist;
4941 Py_ssize_t argc;
4942
4943 /* execv has two arguments: (path, argv), where
4944 argv is a list or tuple of strings. */
4945
4946 if (!PyArg_ParseTuple(args, "O&O:execv",
4947 PyUnicode_FSConverter,
4948 &opath, &argv))
4949 return NULL;
4950 path = PyBytes_AsString(opath);
4951 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4952 PyErr_SetString(PyExc_TypeError,
4953 "execv() arg 2 must be a tuple or list");
4954 Py_DECREF(opath);
4955 return NULL;
4956 }
4957 argc = PySequence_Size(argv);
4958 if (argc < 1) {
4959 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4960 Py_DECREF(opath);
4961 return NULL;
4962 }
4963
4964 argvlist = parse_arglist(argv, &argc);
4965 if (argvlist == NULL) {
4966 Py_DECREF(opath);
4967 return NULL;
4968 }
4969
4970 execv(path, argvlist);
4971
4972 /* If we get here it's definitely an error */
4973
4974 free_string_array(argvlist, argc);
4975 Py_DECREF(opath);
4976 return posix_error();
4977}
4978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004979PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004980"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004981Execute a path with arguments and environment, replacing current process.\n\
4982\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 path: path of executable file\n\
4984 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 env: dictionary of strings mapping to strings\n\
4986\n\
4987On some platforms, you may specify an open file descriptor for path;\n\
4988 execve will execute the program the file descriptor is open to.\n\
4989 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004990
Barry Warsaw53699e91996-12-10 23:23:01 +00004991static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004993{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004996 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004999 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 /* execve has three arguments: (path, argv, env), where
5002 argv is a list or tuple of strings and env is a dictionary
5003 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005004
Larry Hastings9cf065c2012-06-22 16:30:09 -07005005 memset(&path, 0, sizeof(path));
5006#ifdef HAVE_FEXECVE
5007 path.allow_fd = 1;
5008#endif
5009 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5010 path_converter, &path,
5011 &argv, &env
5012 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005014
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005017 "execve: argv must be a tuple or list");
5018 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005020 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 if (!PyMapping_Check(env)) {
5022 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005023 "execve: environment must be a mapping object");
5024 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005026
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 envlist = parse_envlist(env, &envc);
5033 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005034 goto fail;
5035
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036#ifdef HAVE_FEXECVE
5037 if (path.fd > -1)
5038 fexecve(path.fd, argvlist, envlist);
5039 else
5040#endif
5041 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042
5043 /* If we get here it's definitely an error */
5044
Larry Hastings9cf065c2012-06-22 16:30:09 -07005045 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046
5047 while (--envc >= 0)
5048 PyMem_DEL(envlist[envc]);
5049 PyMem_DEL(envlist);
5050 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005051 if (argvlist)
5052 free_string_array(argvlist, argc);
5053 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 return NULL;
5055}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005056#endif /* HAVE_EXECV */
5057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005058
Guido van Rossuma1065681999-01-25 23:20:23 +00005059#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005060PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005061"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005062Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005063\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 mode: mode of process creation\n\
5065 path: path of executable file\n\
5066 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005067
5068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005069posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005070{
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 PyObject *opath;
5072 char *path;
5073 PyObject *argv;
5074 char **argvlist;
5075 int mode, i;
5076 Py_ssize_t argc;
5077 Py_intptr_t spawnval;
5078 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005079
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 /* spawnv has three arguments: (mode, path, argv), where
5081 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005082
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5084 PyUnicode_FSConverter,
5085 &opath, &argv))
5086 return NULL;
5087 path = PyBytes_AsString(opath);
5088 if (PyList_Check(argv)) {
5089 argc = PyList_Size(argv);
5090 getitem = PyList_GetItem;
5091 }
5092 else if (PyTuple_Check(argv)) {
5093 argc = PyTuple_Size(argv);
5094 getitem = PyTuple_GetItem;
5095 }
5096 else {
5097 PyErr_SetString(PyExc_TypeError,
5098 "spawnv() arg 2 must be a tuple or list");
5099 Py_DECREF(opath);
5100 return NULL;
5101 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 argvlist = PyMem_NEW(char *, argc+1);
5104 if (argvlist == NULL) {
5105 Py_DECREF(opath);
5106 return PyErr_NoMemory();
5107 }
5108 for (i = 0; i < argc; i++) {
5109 if (!fsconvert_strdup((*getitem)(argv, i),
5110 &argvlist[i])) {
5111 free_string_array(argvlist, i);
5112 PyErr_SetString(
5113 PyExc_TypeError,
5114 "spawnv() arg 2 must contain only strings");
5115 Py_DECREF(opath);
5116 return NULL;
5117 }
5118 }
5119 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005120
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005121#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 Py_BEGIN_ALLOW_THREADS
5123 spawnval = spawnv(mode, path, argvlist);
5124 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005125#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 if (mode == _OLD_P_OVERLAY)
5127 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005128
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 Py_BEGIN_ALLOW_THREADS
5130 spawnval = _spawnv(mode, path, argvlist);
5131 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005132#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005133
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 free_string_array(argvlist, argc);
5135 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 if (spawnval == -1)
5138 return posix_error();
5139 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005140#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005142#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005144#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005145}
5146
5147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005149"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005150Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005151\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 mode: mode of process creation\n\
5153 path: path of executable file\n\
5154 args: tuple or list of arguments\n\
5155 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005156
5157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005158posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005159{
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 PyObject *opath;
5161 char *path;
5162 PyObject *argv, *env;
5163 char **argvlist;
5164 char **envlist;
5165 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005166 int mode;
5167 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 Py_intptr_t spawnval;
5169 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5170 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 /* spawnve has four arguments: (mode, path, argv, env), where
5173 argv is a list or tuple of strings and env is a dictionary
5174 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005175
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5177 PyUnicode_FSConverter,
5178 &opath, &argv, &env))
5179 return NULL;
5180 path = PyBytes_AsString(opath);
5181 if (PyList_Check(argv)) {
5182 argc = PyList_Size(argv);
5183 getitem = PyList_GetItem;
5184 }
5185 else if (PyTuple_Check(argv)) {
5186 argc = PyTuple_Size(argv);
5187 getitem = PyTuple_GetItem;
5188 }
5189 else {
5190 PyErr_SetString(PyExc_TypeError,
5191 "spawnve() arg 2 must be a tuple or list");
5192 goto fail_0;
5193 }
5194 if (!PyMapping_Check(env)) {
5195 PyErr_SetString(PyExc_TypeError,
5196 "spawnve() arg 3 must be a mapping object");
5197 goto fail_0;
5198 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 argvlist = PyMem_NEW(char *, argc+1);
5201 if (argvlist == NULL) {
5202 PyErr_NoMemory();
5203 goto fail_0;
5204 }
5205 for (i = 0; i < argc; i++) {
5206 if (!fsconvert_strdup((*getitem)(argv, i),
5207 &argvlist[i]))
5208 {
5209 lastarg = i;
5210 goto fail_1;
5211 }
5212 }
5213 lastarg = argc;
5214 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 envlist = parse_envlist(env, &envc);
5217 if (envlist == NULL)
5218 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005219
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005220#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 Py_BEGIN_ALLOW_THREADS
5222 spawnval = spawnve(mode, path, argvlist, envlist);
5223 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005224#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 if (mode == _OLD_P_OVERLAY)
5226 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 Py_BEGIN_ALLOW_THREADS
5229 spawnval = _spawnve(mode, path, argvlist, envlist);
5230 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005231#endif
Tim Peters25059d32001-12-07 20:35:43 +00005232
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 if (spawnval == -1)
5234 (void) posix_error();
5235 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005236#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005239 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005240#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005241
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 while (--envc >= 0)
5243 PyMem_DEL(envlist[envc]);
5244 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005245 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005247 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 Py_DECREF(opath);
5249 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005250}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005251
5252/* OS/2 supports spawnvp & spawnvpe natively */
5253#if defined(PYOS_OS2)
5254PyDoc_STRVAR(posix_spawnvp__doc__,
5255"spawnvp(mode, file, args)\n\n\
5256Execute the program 'file' in a new process, using the environment\n\
5257search path to find the file.\n\
5258\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 mode: mode of process creation\n\
5260 file: executable file name\n\
5261 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005262
5263static PyObject *
5264posix_spawnvp(PyObject *self, PyObject *args)
5265{
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 PyObject *opath;
5267 char *path;
5268 PyObject *argv;
5269 char **argvlist;
5270 int mode, i, argc;
5271 Py_intptr_t spawnval;
5272 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 /* spawnvp has three arguments: (mode, path, argv), where
5275 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005276
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5278 PyUnicode_FSConverter,
5279 &opath, &argv))
5280 return NULL;
5281 path = PyBytes_AsString(opath);
5282 if (PyList_Check(argv)) {
5283 argc = PyList_Size(argv);
5284 getitem = PyList_GetItem;
5285 }
5286 else if (PyTuple_Check(argv)) {
5287 argc = PyTuple_Size(argv);
5288 getitem = PyTuple_GetItem;
5289 }
5290 else {
5291 PyErr_SetString(PyExc_TypeError,
5292 "spawnvp() arg 2 must be a tuple or list");
5293 Py_DECREF(opath);
5294 return NULL;
5295 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 argvlist = PyMem_NEW(char *, argc+1);
5298 if (argvlist == NULL) {
5299 Py_DECREF(opath);
5300 return PyErr_NoMemory();
5301 }
5302 for (i = 0; i < argc; i++) {
5303 if (!fsconvert_strdup((*getitem)(argv, i),
5304 &argvlist[i])) {
5305 free_string_array(argvlist, i);
5306 PyErr_SetString(
5307 PyExc_TypeError,
5308 "spawnvp() arg 2 must contain only strings");
5309 Py_DECREF(opath);
5310 return NULL;
5311 }
5312 }
5313 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005318#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005320#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005322
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 free_string_array(argvlist, argc);
5324 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005325
Victor Stinner8c62be82010-05-06 00:08:46 +00005326 if (spawnval == -1)
5327 return posix_error();
5328 else
5329 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005330}
5331
5332
5333PyDoc_STRVAR(posix_spawnvpe__doc__,
5334"spawnvpe(mode, file, args, env)\n\n\
5335Execute the program 'file' in a new process, using the environment\n\
5336search path to find the file.\n\
5337\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005338 mode: mode of process creation\n\
5339 file: executable file name\n\
5340 args: tuple or list of arguments\n\
5341 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005342
5343static PyObject *
5344posix_spawnvpe(PyObject *self, PyObject *args)
5345{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005346 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005347 char *path;
5348 PyObject *argv, *env;
5349 char **argvlist;
5350 char **envlist;
5351 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005352 int mode;
5353 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 Py_intptr_t spawnval;
5355 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5356 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 /* spawnvpe has four arguments: (mode, path, argv, env), where
5359 argv is a list or tuple of strings and env is a dictionary
5360 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005361
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5363 PyUnicode_FSConverter,
5364 &opath, &argv, &env))
5365 return NULL;
5366 path = PyBytes_AsString(opath);
5367 if (PyList_Check(argv)) {
5368 argc = PyList_Size(argv);
5369 getitem = PyList_GetItem;
5370 }
5371 else if (PyTuple_Check(argv)) {
5372 argc = PyTuple_Size(argv);
5373 getitem = PyTuple_GetItem;
5374 }
5375 else {
5376 PyErr_SetString(PyExc_TypeError,
5377 "spawnvpe() arg 2 must be a tuple or list");
5378 goto fail_0;
5379 }
5380 if (!PyMapping_Check(env)) {
5381 PyErr_SetString(PyExc_TypeError,
5382 "spawnvpe() arg 3 must be a mapping object");
5383 goto fail_0;
5384 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005385
Victor Stinner8c62be82010-05-06 00:08:46 +00005386 argvlist = PyMem_NEW(char *, argc+1);
5387 if (argvlist == NULL) {
5388 PyErr_NoMemory();
5389 goto fail_0;
5390 }
5391 for (i = 0; i < argc; i++) {
5392 if (!fsconvert_strdup((*getitem)(argv, i),
5393 &argvlist[i]))
5394 {
5395 lastarg = i;
5396 goto fail_1;
5397 }
5398 }
5399 lastarg = argc;
5400 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005401
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 envlist = parse_envlist(env, &envc);
5403 if (envlist == NULL)
5404 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005405
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005407#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005409#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005411#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005413
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 if (spawnval == -1)
5415 (void) posix_error();
5416 else
5417 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005418
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 while (--envc >= 0)
5420 PyMem_DEL(envlist[envc]);
5421 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005422 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005424 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005425 Py_DECREF(opath);
5426 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005427}
5428#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005429#endif /* HAVE_SPAWNV */
5430
5431
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005432#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005434"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005435Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5436\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005437Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005438
5439static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005440posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005441{
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 pid_t pid;
5443 int result = 0;
5444 _PyImport_AcquireLock();
5445 pid = fork1();
5446 if (pid == 0) {
5447 /* child: this clobbers and resets the import lock. */
5448 PyOS_AfterFork();
5449 } else {
5450 /* parent: release the import lock. */
5451 result = _PyImport_ReleaseLock();
5452 }
5453 if (pid == -1)
5454 return posix_error();
5455 if (result < 0) {
5456 /* Don't clobber the OSError if the fork failed. */
5457 PyErr_SetString(PyExc_RuntimeError,
5458 "not holding the import lock");
5459 return NULL;
5460 }
5461 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005462}
5463#endif
5464
5465
Guido van Rossumad0ee831995-03-01 10:34:45 +00005466#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005468"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005469Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Barry Warsaw53699e91996-12-10 23:23:01 +00005472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005473posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005474{
Victor Stinner8c62be82010-05-06 00:08:46 +00005475 pid_t pid;
5476 int result = 0;
5477 _PyImport_AcquireLock();
5478 pid = fork();
5479 if (pid == 0) {
5480 /* child: this clobbers and resets the import lock. */
5481 PyOS_AfterFork();
5482 } else {
5483 /* parent: release the import lock. */
5484 result = _PyImport_ReleaseLock();
5485 }
5486 if (pid == -1)
5487 return posix_error();
5488 if (result < 0) {
5489 /* Don't clobber the OSError if the fork failed. */
5490 PyErr_SetString(PyExc_RuntimeError,
5491 "not holding the import lock");
5492 return NULL;
5493 }
5494 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005495}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005496#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005497
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005498#ifdef HAVE_SCHED_H
5499
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005500#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5501
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5503"sched_get_priority_max(policy)\n\n\
5504Get the maximum scheduling priority for *policy*.");
5505
5506static PyObject *
5507posix_sched_get_priority_max(PyObject *self, PyObject *args)
5508{
5509 int policy, max;
5510
5511 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5512 return NULL;
5513 max = sched_get_priority_max(policy);
5514 if (max < 0)
5515 return posix_error();
5516 return PyLong_FromLong(max);
5517}
5518
5519PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5520"sched_get_priority_min(policy)\n\n\
5521Get the minimum scheduling priority for *policy*.");
5522
5523static PyObject *
5524posix_sched_get_priority_min(PyObject *self, PyObject *args)
5525{
5526 int policy, min;
5527
5528 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5529 return NULL;
5530 min = sched_get_priority_min(policy);
5531 if (min < 0)
5532 return posix_error();
5533 return PyLong_FromLong(min);
5534}
5535
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005536#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5537
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005538#ifdef HAVE_SCHED_SETSCHEDULER
5539
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5541"sched_getscheduler(pid)\n\n\
5542Get the scheduling policy for the process with a PID of *pid*.\n\
5543Passing a PID of 0 returns the scheduling policy for the calling process.");
5544
5545static PyObject *
5546posix_sched_getscheduler(PyObject *self, PyObject *args)
5547{
5548 pid_t pid;
5549 int policy;
5550
5551 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5552 return NULL;
5553 policy = sched_getscheduler(pid);
5554 if (policy < 0)
5555 return posix_error();
5556 return PyLong_FromLong(policy);
5557}
5558
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005559#endif
5560
5561#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5562
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005563static PyObject *
5564sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5565{
5566 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005567 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005568
5569 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5570 return NULL;
5571 res = PyStructSequence_New(type);
5572 if (!res)
5573 return NULL;
5574 Py_INCREF(priority);
5575 PyStructSequence_SET_ITEM(res, 0, priority);
5576 return res;
5577}
5578
5579PyDoc_STRVAR(sched_param__doc__,
5580"sched_param(sched_priority): A scheduling parameter.\n\n\
5581Current has only one field: sched_priority");
5582
5583static PyStructSequence_Field sched_param_fields[] = {
5584 {"sched_priority", "the scheduling priority"},
5585 {0}
5586};
5587
5588static PyStructSequence_Desc sched_param_desc = {
5589 "sched_param", /* name */
5590 sched_param__doc__, /* doc */
5591 sched_param_fields,
5592 1
5593};
5594
5595static int
5596convert_sched_param(PyObject *param, struct sched_param *res)
5597{
5598 long priority;
5599
5600 if (Py_TYPE(param) != &SchedParamType) {
5601 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5602 return 0;
5603 }
5604 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5605 if (priority == -1 && PyErr_Occurred())
5606 return 0;
5607 if (priority > INT_MAX || priority < INT_MIN) {
5608 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5609 return 0;
5610 }
5611 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5612 return 1;
5613}
5614
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005615#endif
5616
5617#ifdef HAVE_SCHED_SETSCHEDULER
5618
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005619PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5620"sched_setscheduler(pid, policy, param)\n\n\
5621Set the scheduling policy, *policy*, for *pid*.\n\
5622If *pid* is 0, the calling process is changed.\n\
5623*param* is an instance of sched_param.");
5624
5625static PyObject *
5626posix_sched_setscheduler(PyObject *self, PyObject *args)
5627{
5628 pid_t pid;
5629 int policy;
5630 struct sched_param param;
5631
5632 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5633 &pid, &policy, &convert_sched_param, &param))
5634 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005635
5636 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005637 ** sched_setscheduler() returns 0 in Linux, but the previous
5638 ** scheduling policy under Solaris/Illumos, and others.
5639 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005640 */
5641 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005642 return posix_error();
5643 Py_RETURN_NONE;
5644}
5645
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005646#endif
5647
5648#ifdef HAVE_SCHED_SETPARAM
5649
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005650PyDoc_STRVAR(posix_sched_getparam__doc__,
5651"sched_getparam(pid) -> sched_param\n\n\
5652Returns scheduling parameters for the process with *pid* as an instance of the\n\
5653sched_param class. A PID of 0 means the calling process.");
5654
5655static PyObject *
5656posix_sched_getparam(PyObject *self, PyObject *args)
5657{
5658 pid_t pid;
5659 struct sched_param param;
5660 PyObject *res, *priority;
5661
5662 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5663 return NULL;
5664 if (sched_getparam(pid, &param))
5665 return posix_error();
5666 res = PyStructSequence_New(&SchedParamType);
5667 if (!res)
5668 return NULL;
5669 priority = PyLong_FromLong(param.sched_priority);
5670 if (!priority) {
5671 Py_DECREF(res);
5672 return NULL;
5673 }
5674 PyStructSequence_SET_ITEM(res, 0, priority);
5675 return res;
5676}
5677
5678PyDoc_STRVAR(posix_sched_setparam__doc__,
5679"sched_setparam(pid, param)\n\n\
5680Set scheduling parameters for a process with PID *pid*.\n\
5681A PID of 0 means the calling process.");
5682
5683static PyObject *
5684posix_sched_setparam(PyObject *self, PyObject *args)
5685{
5686 pid_t pid;
5687 struct sched_param param;
5688
5689 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5690 &pid, &convert_sched_param, &param))
5691 return NULL;
5692 if (sched_setparam(pid, &param))
5693 return posix_error();
5694 Py_RETURN_NONE;
5695}
5696
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005697#endif
5698
5699#ifdef HAVE_SCHED_RR_GET_INTERVAL
5700
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005701PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5702"sched_rr_get_interval(pid) -> float\n\n\
5703Return the round-robin quantum for the process with PID *pid* in seconds.");
5704
5705static PyObject *
5706posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5707{
5708 pid_t pid;
5709 struct timespec interval;
5710
5711 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5712 return NULL;
5713 if (sched_rr_get_interval(pid, &interval))
5714 return posix_error();
5715 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5716}
5717
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005718#endif
5719
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005720PyDoc_STRVAR(posix_sched_yield__doc__,
5721"sched_yield()\n\n\
5722Voluntarily relinquish the CPU.");
5723
5724static PyObject *
5725posix_sched_yield(PyObject *self, PyObject *noargs)
5726{
5727 if (sched_yield())
5728 return posix_error();
5729 Py_RETURN_NONE;
5730}
5731
Benjamin Peterson2740af82011-08-02 17:41:34 -05005732#ifdef HAVE_SCHED_SETAFFINITY
5733
Antoine Pitrou84869872012-08-04 16:16:35 +02005734/* The minimum number of CPUs allocated in a cpu_set_t */
5735static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005736
5737PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5738"sched_setaffinity(pid, cpu_set)\n\n\
5739Set the affinity of the process with PID *pid* to *cpu_set*.");
5740
5741static PyObject *
5742posix_sched_setaffinity(PyObject *self, PyObject *args)
5743{
5744 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005745 int ncpus;
5746 size_t setsize;
5747 cpu_set_t *mask = NULL;
5748 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749
Antoine Pitrou84869872012-08-04 16:16:35 +02005750 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5751 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005752 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005753
5754 iterator = PyObject_GetIter(iterable);
5755 if (iterator == NULL)
5756 return NULL;
5757
5758 ncpus = NCPUS_START;
5759 setsize = CPU_ALLOC_SIZE(ncpus);
5760 mask = CPU_ALLOC(ncpus);
5761 if (mask == NULL) {
5762 PyErr_NoMemory();
5763 goto error;
5764 }
5765 CPU_ZERO_S(setsize, mask);
5766
5767 while ((item = PyIter_Next(iterator))) {
5768 long cpu;
5769 if (!PyLong_Check(item)) {
5770 PyErr_Format(PyExc_TypeError,
5771 "expected an iterator of ints, "
5772 "but iterator yielded %R",
5773 Py_TYPE(item));
5774 Py_DECREF(item);
5775 goto error;
5776 }
5777 cpu = PyLong_AsLong(item);
5778 Py_DECREF(item);
5779 if (cpu < 0) {
5780 if (!PyErr_Occurred())
5781 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5782 goto error;
5783 }
5784 if (cpu > INT_MAX - 1) {
5785 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5786 goto error;
5787 }
5788 if (cpu >= ncpus) {
5789 /* Grow CPU mask to fit the CPU number */
5790 int newncpus = ncpus;
5791 cpu_set_t *newmask;
5792 size_t newsetsize;
5793 while (newncpus <= cpu) {
5794 if (newncpus > INT_MAX / 2)
5795 newncpus = cpu + 1;
5796 else
5797 newncpus = newncpus * 2;
5798 }
5799 newmask = CPU_ALLOC(newncpus);
5800 if (newmask == NULL) {
5801 PyErr_NoMemory();
5802 goto error;
5803 }
5804 newsetsize = CPU_ALLOC_SIZE(newncpus);
5805 CPU_ZERO_S(newsetsize, newmask);
5806 memcpy(newmask, mask, setsize);
5807 CPU_FREE(mask);
5808 setsize = newsetsize;
5809 mask = newmask;
5810 ncpus = newncpus;
5811 }
5812 CPU_SET_S(cpu, setsize, mask);
5813 }
5814 Py_CLEAR(iterator);
5815
5816 if (sched_setaffinity(pid, setsize, mask)) {
5817 posix_error();
5818 goto error;
5819 }
5820 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005821 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005822
5823error:
5824 if (mask)
5825 CPU_FREE(mask);
5826 Py_XDECREF(iterator);
5827 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005828}
5829
5830PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5831"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5832Return the affinity of the process with PID *pid*.\n\
5833The returned cpu_set will be of size *ncpus*.");
5834
5835static PyObject *
5836posix_sched_getaffinity(PyObject *self, PyObject *args)
5837{
5838 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005839 int cpu, ncpus, count;
5840 size_t setsize;
5841 cpu_set_t *mask = NULL;
5842 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005843
Antoine Pitrou84869872012-08-04 16:16:35 +02005844 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5845 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005846 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005847
5848 ncpus = NCPUS_START;
5849 while (1) {
5850 setsize = CPU_ALLOC_SIZE(ncpus);
5851 mask = CPU_ALLOC(ncpus);
5852 if (mask == NULL)
5853 return PyErr_NoMemory();
5854 if (sched_getaffinity(pid, setsize, mask) == 0)
5855 break;
5856 CPU_FREE(mask);
5857 if (errno != EINVAL)
5858 return posix_error();
5859 if (ncpus > INT_MAX / 2) {
5860 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5861 "a large enough CPU set");
5862 return NULL;
5863 }
5864 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005865 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005866
5867 res = PySet_New(NULL);
5868 if (res == NULL)
5869 goto error;
5870 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5871 if (CPU_ISSET_S(cpu, setsize, mask)) {
5872 PyObject *cpu_num = PyLong_FromLong(cpu);
5873 --count;
5874 if (cpu_num == NULL)
5875 goto error;
5876 if (PySet_Add(res, cpu_num)) {
5877 Py_DECREF(cpu_num);
5878 goto error;
5879 }
5880 Py_DECREF(cpu_num);
5881 }
5882 }
5883 CPU_FREE(mask);
5884 return res;
5885
5886error:
5887 if (mask)
5888 CPU_FREE(mask);
5889 Py_XDECREF(res);
5890 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005891}
5892
Benjamin Peterson2740af82011-08-02 17:41:34 -05005893#endif /* HAVE_SCHED_SETAFFINITY */
5894
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005895#endif /* HAVE_SCHED_H */
5896
Neal Norwitzb59798b2003-03-21 01:43:31 +00005897/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005898/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5899#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005900#define DEV_PTY_FILE "/dev/ptc"
5901#define HAVE_DEV_PTMX
5902#else
5903#define DEV_PTY_FILE "/dev/ptmx"
5904#endif
5905
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005906#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005907#ifdef HAVE_PTY_H
5908#include <pty.h>
5909#else
5910#ifdef HAVE_LIBUTIL_H
5911#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005912#else
5913#ifdef HAVE_UTIL_H
5914#include <util.h>
5915#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005916#endif /* HAVE_LIBUTIL_H */
5917#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005918#ifdef HAVE_STROPTS_H
5919#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005920#endif
5921#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005922
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005923#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005924PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005925"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005926Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005927
5928static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005929posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005930{
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005932#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005934#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005935#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005937#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005939#endif
5940#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941
Thomas Wouters70c21a12000-07-14 14:28:33 +00005942#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5944 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005945#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5947 if (slave_name == NULL)
5948 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005949
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 slave_fd = open(slave_name, O_RDWR);
5951 if (slave_fd < 0)
5952 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5955 if (master_fd < 0)
5956 return posix_error();
5957 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5958 /* change permission of slave */
5959 if (grantpt(master_fd) < 0) {
5960 PyOS_setsig(SIGCHLD, sig_saved);
5961 return posix_error();
5962 }
5963 /* unlock slave */
5964 if (unlockpt(master_fd) < 0) {
5965 PyOS_setsig(SIGCHLD, sig_saved);
5966 return posix_error();
5967 }
5968 PyOS_setsig(SIGCHLD, sig_saved);
5969 slave_name = ptsname(master_fd); /* get name of slave */
5970 if (slave_name == NULL)
5971 return posix_error();
5972 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5973 if (slave_fd < 0)
5974 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005975#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5977 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005978#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005980#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005981#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005982#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005983
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005985
Fred Drake8cef4cf2000-06-28 16:40:38 +00005986}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005987#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005988
5989#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005990PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005991"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005992Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5993Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005995
5996static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005997posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005998{
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 int master_fd = -1, result = 0;
6000 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 _PyImport_AcquireLock();
6003 pid = forkpty(&master_fd, NULL, NULL, NULL);
6004 if (pid == 0) {
6005 /* child: this clobbers and resets the import lock. */
6006 PyOS_AfterFork();
6007 } else {
6008 /* parent: release the import lock. */
6009 result = _PyImport_ReleaseLock();
6010 }
6011 if (pid == -1)
6012 return posix_error();
6013 if (result < 0) {
6014 /* Don't clobber the OSError if the fork failed. */
6015 PyErr_SetString(PyExc_RuntimeError,
6016 "not holding the import lock");
6017 return NULL;
6018 }
6019 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020}
6021#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006022
Ross Lagerwall7807c352011-03-17 20:20:30 +02006023
Guido van Rossumad0ee831995-03-01 10:34:45 +00006024#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006026"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006027Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006028
Barry Warsaw53699e91996-12-10 23:23:01 +00006029static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006030posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006031{
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006033}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006034#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006036
Guido van Rossumad0ee831995-03-01 10:34:45 +00006037#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006039"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006041
Barry Warsaw53699e91996-12-10 23:23:01 +00006042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006043posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006044{
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006046}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006047#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Guido van Rossumad0ee831995-03-01 10:34:45 +00006050#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006052"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006054
Barry Warsaw53699e91996-12-10 23:23:01 +00006055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006056posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006057{
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006059}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006060#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006064"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006066
Barry Warsaw53699e91996-12-10 23:23:01 +00006067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006068posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006069{
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006071}
6072
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006073#ifdef HAVE_GETGROUPLIST
6074PyDoc_STRVAR(posix_getgrouplist__doc__,
6075"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6076Returns a list of groups to which a user belongs.\n\n\
6077 user: username to lookup\n\
6078 group: base group id of the user");
6079
6080static PyObject *
6081posix_getgrouplist(PyObject *self, PyObject *args)
6082{
6083#ifdef NGROUPS_MAX
6084#define MAX_GROUPS NGROUPS_MAX
6085#else
6086 /* defined to be 16 on Solaris7, so this should be a small number */
6087#define MAX_GROUPS 64
6088#endif
6089
6090 const char *user;
6091 int i, ngroups;
6092 PyObject *list;
6093#ifdef __APPLE__
6094 int *groups, basegid;
6095#else
6096 gid_t *groups, basegid;
6097#endif
6098 ngroups = MAX_GROUPS;
6099
6100 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6101 return NULL;
6102
6103#ifdef __APPLE__
6104 groups = PyMem_Malloc(ngroups * sizeof(int));
6105#else
6106 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6107#endif
6108 if (groups == NULL)
6109 return PyErr_NoMemory();
6110
6111 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6112 PyMem_Del(groups);
6113 return posix_error();
6114 }
6115
6116 list = PyList_New(ngroups);
6117 if (list == NULL) {
6118 PyMem_Del(groups);
6119 return NULL;
6120 }
6121
6122 for (i = 0; i < ngroups; i++) {
6123 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6124 if (o == NULL) {
6125 Py_DECREF(list);
6126 PyMem_Del(groups);
6127 return NULL;
6128 }
6129 PyList_SET_ITEM(list, i, o);
6130 }
6131
6132 PyMem_Del(groups);
6133
6134 return list;
6135}
6136#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006137
Fred Drakec9680921999-12-13 16:37:25 +00006138#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006140"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006141Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006142
6143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006144posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006145{
6146 PyObject *result = NULL;
6147
Fred Drakec9680921999-12-13 16:37:25 +00006148#ifdef NGROUPS_MAX
6149#define MAX_GROUPS NGROUPS_MAX
6150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006152#define MAX_GROUPS 64
6153#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006155
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006156 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006157 * This is a helper variable to store the intermediate result when
6158 * that happens.
6159 *
6160 * To keep the code readable the OSX behaviour is unconditional,
6161 * according to the POSIX spec this should be safe on all unix-y
6162 * systems.
6163 */
6164 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006168 if (n < 0) {
6169 if (errno == EINVAL) {
6170 n = getgroups(0, NULL);
6171 if (n == -1) {
6172 return posix_error();
6173 }
6174 if (n == 0) {
6175 /* Avoid malloc(0) */
6176 alt_grouplist = grouplist;
6177 } else {
6178 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6179 if (alt_grouplist == NULL) {
6180 errno = EINVAL;
6181 return posix_error();
6182 }
6183 n = getgroups(n, alt_grouplist);
6184 if (n == -1) {
6185 PyMem_Free(alt_grouplist);
6186 return posix_error();
6187 }
6188 }
6189 } else {
6190 return posix_error();
6191 }
6192 }
6193 result = PyList_New(n);
6194 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 int i;
6196 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006197 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006199 Py_DECREF(result);
6200 result = NULL;
6201 break;
Fred Drakec9680921999-12-13 16:37:25 +00006202 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006204 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006205 }
6206
6207 if (alt_grouplist != grouplist) {
6208 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006210
Fred Drakec9680921999-12-13 16:37:25 +00006211 return result;
6212}
6213#endif
6214
Antoine Pitroub7572f02009-12-02 20:46:48 +00006215#ifdef HAVE_INITGROUPS
6216PyDoc_STRVAR(posix_initgroups__doc__,
6217"initgroups(username, gid) -> None\n\n\
6218Call the system initgroups() to initialize the group access list with all of\n\
6219the groups of which the specified username is a member, plus the specified\n\
6220group id.");
6221
6222static PyObject *
6223posix_initgroups(PyObject *self, PyObject *args)
6224{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006225 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006227 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006229
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006230 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6231 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006233 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006234
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006235 res = initgroups(username, (gid_t) gid);
6236 Py_DECREF(oname);
6237 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006239
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 Py_INCREF(Py_None);
6241 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006242}
6243#endif
6244
Martin v. Löwis606edc12002-06-13 21:09:11 +00006245#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006246PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006248Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006249
6250static PyObject *
6251posix_getpgid(PyObject *self, PyObject *args)
6252{
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 pid_t pid, pgid;
6254 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6255 return NULL;
6256 pgid = getpgid(pid);
6257 if (pgid < 0)
6258 return posix_error();
6259 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006260}
6261#endif /* HAVE_GETPGID */
6262
6263
Guido van Rossumb6775db1994-08-01 11:34:53 +00006264#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006266"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006268
Barry Warsaw53699e91996-12-10 23:23:01 +00006269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006270posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006271{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006272#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006274#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006276#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006277}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006278#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006280
Guido van Rossumb6775db1994-08-01 11:34:53 +00006281#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006284Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006285
Barry Warsaw53699e91996-12-10 23:23:01 +00006286static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006287posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006288{
Guido van Rossum64933891994-10-20 21:56:42 +00006289#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006291#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006293#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 return posix_error();
6295 Py_INCREF(Py_None);
6296 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006297}
6298
Guido van Rossumb6775db1994-08-01 11:34:53 +00006299#endif /* HAVE_SETPGRP */
6300
Guido van Rossumad0ee831995-03-01 10:34:45 +00006301#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006302
6303#ifdef MS_WINDOWS
6304#include <tlhelp32.h>
6305
6306static PyObject*
6307win32_getppid()
6308{
6309 HANDLE snapshot;
6310 pid_t mypid;
6311 PyObject* result = NULL;
6312 BOOL have_record;
6313 PROCESSENTRY32 pe;
6314
6315 mypid = getpid(); /* This function never fails */
6316
6317 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6318 if (snapshot == INVALID_HANDLE_VALUE)
6319 return PyErr_SetFromWindowsErr(GetLastError());
6320
6321 pe.dwSize = sizeof(pe);
6322 have_record = Process32First(snapshot, &pe);
6323 while (have_record) {
6324 if (mypid == (pid_t)pe.th32ProcessID) {
6325 /* We could cache the ulong value in a static variable. */
6326 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6327 break;
6328 }
6329
6330 have_record = Process32Next(snapshot, &pe);
6331 }
6332
6333 /* If our loop exits and our pid was not found (result will be NULL)
6334 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6335 * error anyway, so let's raise it. */
6336 if (!result)
6337 result = PyErr_SetFromWindowsErr(GetLastError());
6338
6339 CloseHandle(snapshot);
6340
6341 return result;
6342}
6343#endif /*MS_WINDOWS*/
6344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006346"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006347Return the parent's process id. If the parent process has already exited,\n\
6348Windows machines will still return its id; others systems will return the id\n\
6349of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006350
Barry Warsaw53699e91996-12-10 23:23:01 +00006351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006352posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006353{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006354#ifdef MS_WINDOWS
6355 return win32_getppid();
6356#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006358#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006359}
6360#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006362
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006365"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006366Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006367
6368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006369posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006370{
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006372#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006373 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006374 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006375
6376 if (GetUserNameW(user_name, &num_chars)) {
6377 /* num_chars is the number of unicode chars plus null terminator */
6378 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006379 }
6380 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006381 result = PyErr_SetFromWindowsErr(GetLastError());
6382#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 char *name;
6384 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 errno = 0;
6387 name = getlogin();
6388 if (name == NULL) {
6389 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006390 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006391 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006392 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 }
6394 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006395 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006397#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006398 return result;
6399}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006400#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006401
Guido van Rossumad0ee831995-03-01 10:34:45 +00006402#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006403PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006404"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006405Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006406
Barry Warsaw53699e91996-12-10 23:23:01 +00006407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006408posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006409{
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006411}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006412#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Guido van Rossumad0ee831995-03-01 10:34:45 +00006415#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006416PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006417"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006419
Barry Warsaw53699e91996-12-10 23:23:01 +00006420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006421posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006422{
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 pid_t pid;
6424 int sig;
6425 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6426 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006427#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006428 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6429 APIRET rc;
6430 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006431 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006432
6433 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6434 APIRET rc;
6435 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006436 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006437
6438 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006439 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006440#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 if (kill(pid, sig) == -1)
6442 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006443#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 Py_INCREF(Py_None);
6445 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006446}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006447#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006448
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006449#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006450PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006451"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006452Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006453
6454static PyObject *
6455posix_killpg(PyObject *self, PyObject *args)
6456{
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 int sig;
6458 pid_t pgid;
6459 /* XXX some man pages make the `pgid` parameter an int, others
6460 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6461 take the same type. Moreover, pid_t is always at least as wide as
6462 int (else compilation of this module fails), which is safe. */
6463 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6464 return NULL;
6465 if (killpg(pgid, sig) == -1)
6466 return posix_error();
6467 Py_INCREF(Py_None);
6468 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006469}
6470#endif
6471
Brian Curtineb24d742010-04-12 17:16:38 +00006472#ifdef MS_WINDOWS
6473PyDoc_STRVAR(win32_kill__doc__,
6474"kill(pid, sig)\n\n\
6475Kill a process with a signal.");
6476
6477static PyObject *
6478win32_kill(PyObject *self, PyObject *args)
6479{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006480 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 DWORD pid, sig, err;
6482 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6485 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 /* Console processes which share a common console can be sent CTRL+C or
6488 CTRL+BREAK events, provided they handle said events. */
6489 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6490 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6491 err = GetLastError();
6492 PyErr_SetFromWindowsErr(err);
6493 }
6494 else
6495 Py_RETURN_NONE;
6496 }
Brian Curtineb24d742010-04-12 17:16:38 +00006497
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6499 attempt to open and terminate the process. */
6500 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6501 if (handle == NULL) {
6502 err = GetLastError();
6503 return PyErr_SetFromWindowsErr(err);
6504 }
Brian Curtineb24d742010-04-12 17:16:38 +00006505
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 if (TerminateProcess(handle, sig) == 0) {
6507 err = GetLastError();
6508 result = PyErr_SetFromWindowsErr(err);
6509 } else {
6510 Py_INCREF(Py_None);
6511 result = Py_None;
6512 }
Brian Curtineb24d742010-04-12 17:16:38 +00006513
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 CloseHandle(handle);
6515 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006516}
6517#endif /* MS_WINDOWS */
6518
Guido van Rossumc0125471996-06-28 18:55:32 +00006519#ifdef HAVE_PLOCK
6520
6521#ifdef HAVE_SYS_LOCK_H
6522#include <sys/lock.h>
6523#endif
6524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006526"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Barry Warsaw53699e91996-12-10 23:23:01 +00006529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006530posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006531{
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 int op;
6533 if (!PyArg_ParseTuple(args, "i:plock", &op))
6534 return NULL;
6535 if (plock(op) == -1)
6536 return posix_error();
6537 Py_INCREF(Py_None);
6538 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006539}
6540#endif
6541
Guido van Rossumb6775db1994-08-01 11:34:53 +00006542#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006543PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006544"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545Set the current process's user id.");
6546
Barry Warsaw53699e91996-12-10 23:23:01 +00006547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006548posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006549{
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 long uid_arg;
6551 uid_t uid;
6552 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6553 return NULL;
6554 uid = uid_arg;
6555 if (uid != uid_arg) {
6556 PyErr_SetString(PyExc_OverflowError, "user id too big");
6557 return NULL;
6558 }
6559 if (setuid(uid) < 0)
6560 return posix_error();
6561 Py_INCREF(Py_None);
6562 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006563}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006564#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006567#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006568PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006569"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006570Set the current process's effective user id.");
6571
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006572static PyObject *
6573posix_seteuid (PyObject *self, PyObject *args)
6574{
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 long euid_arg;
6576 uid_t euid;
6577 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6578 return NULL;
6579 euid = euid_arg;
6580 if (euid != euid_arg) {
6581 PyErr_SetString(PyExc_OverflowError, "user id too big");
6582 return NULL;
6583 }
6584 if (seteuid(euid) < 0) {
6585 return posix_error();
6586 } else {
6587 Py_INCREF(Py_None);
6588 return Py_None;
6589 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006590}
6591#endif /* HAVE_SETEUID */
6592
6593#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006595"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596Set the current process's effective group id.");
6597
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006598static PyObject *
6599posix_setegid (PyObject *self, PyObject *args)
6600{
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 long egid_arg;
6602 gid_t egid;
6603 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6604 return NULL;
6605 egid = egid_arg;
6606 if (egid != egid_arg) {
6607 PyErr_SetString(PyExc_OverflowError, "group id too big");
6608 return NULL;
6609 }
6610 if (setegid(egid) < 0) {
6611 return posix_error();
6612 } else {
6613 Py_INCREF(Py_None);
6614 return Py_None;
6615 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006616}
6617#endif /* HAVE_SETEGID */
6618
6619#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006620PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006621"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006622Set the current process's real and effective user ids.");
6623
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006624static PyObject *
6625posix_setreuid (PyObject *self, PyObject *args)
6626{
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 long ruid_arg, euid_arg;
6628 uid_t ruid, euid;
6629 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6630 return NULL;
6631 if (ruid_arg == -1)
6632 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6633 else
6634 ruid = ruid_arg; /* otherwise, assign from our long */
6635 if (euid_arg == -1)
6636 euid = (uid_t)-1;
6637 else
6638 euid = euid_arg;
6639 if ((euid_arg != -1 && euid != euid_arg) ||
6640 (ruid_arg != -1 && ruid != ruid_arg)) {
6641 PyErr_SetString(PyExc_OverflowError, "user id too big");
6642 return NULL;
6643 }
6644 if (setreuid(ruid, euid) < 0) {
6645 return posix_error();
6646 } else {
6647 Py_INCREF(Py_None);
6648 return Py_None;
6649 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006650}
6651#endif /* HAVE_SETREUID */
6652
6653#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006654PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006655"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006656Set the current process's real and effective group ids.");
6657
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006658static PyObject *
6659posix_setregid (PyObject *self, PyObject *args)
6660{
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 long rgid_arg, egid_arg;
6662 gid_t rgid, egid;
6663 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6664 return NULL;
6665 if (rgid_arg == -1)
6666 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6667 else
6668 rgid = rgid_arg; /* otherwise, assign from our long */
6669 if (egid_arg == -1)
6670 egid = (gid_t)-1;
6671 else
6672 egid = egid_arg;
6673 if ((egid_arg != -1 && egid != egid_arg) ||
6674 (rgid_arg != -1 && rgid != rgid_arg)) {
6675 PyErr_SetString(PyExc_OverflowError, "group id too big");
6676 return NULL;
6677 }
6678 if (setregid(rgid, egid) < 0) {
6679 return posix_error();
6680 } else {
6681 Py_INCREF(Py_None);
6682 return Py_None;
6683 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006684}
6685#endif /* HAVE_SETREGID */
6686
Guido van Rossumb6775db1994-08-01 11:34:53 +00006687#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006688PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006689"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006690Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006691
Barry Warsaw53699e91996-12-10 23:23:01 +00006692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006693posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006694{
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 long gid_arg;
6696 gid_t gid;
6697 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6698 return NULL;
6699 gid = gid_arg;
6700 if (gid != gid_arg) {
6701 PyErr_SetString(PyExc_OverflowError, "group id too big");
6702 return NULL;
6703 }
6704 if (setgid(gid) < 0)
6705 return posix_error();
6706 Py_INCREF(Py_None);
6707 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006708}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006709#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006710
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006711#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006713"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006714Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006715
6716static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006717posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006718{
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 int i, len;
6720 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006721
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 if (!PySequence_Check(groups)) {
6723 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6724 return NULL;
6725 }
6726 len = PySequence_Size(groups);
6727 if (len > MAX_GROUPS) {
6728 PyErr_SetString(PyExc_ValueError, "too many groups");
6729 return NULL;
6730 }
6731 for(i = 0; i < len; i++) {
6732 PyObject *elem;
6733 elem = PySequence_GetItem(groups, i);
6734 if (!elem)
6735 return NULL;
6736 if (!PyLong_Check(elem)) {
6737 PyErr_SetString(PyExc_TypeError,
6738 "groups must be integers");
6739 Py_DECREF(elem);
6740 return NULL;
6741 } else {
6742 unsigned long x = PyLong_AsUnsignedLong(elem);
6743 if (PyErr_Occurred()) {
6744 PyErr_SetString(PyExc_TypeError,
6745 "group id too big");
6746 Py_DECREF(elem);
6747 return NULL;
6748 }
6749 grouplist[i] = x;
6750 /* read back the value to see if it fitted in gid_t */
6751 if (grouplist[i] != x) {
6752 PyErr_SetString(PyExc_TypeError,
6753 "group id too big");
6754 Py_DECREF(elem);
6755 return NULL;
6756 }
6757 }
6758 Py_DECREF(elem);
6759 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006760
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (setgroups(len, grouplist) < 0)
6762 return posix_error();
6763 Py_INCREF(Py_None);
6764 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006765}
6766#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006767
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006768#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6769static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006770wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006771{
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 PyObject *result;
6773 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006774 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006775
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 if (pid == -1)
6777 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 if (struct_rusage == NULL) {
6780 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6781 if (m == NULL)
6782 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006783 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 Py_DECREF(m);
6785 if (struct_rusage == NULL)
6786 return NULL;
6787 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006788
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6790 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6791 if (!result)
6792 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006793
6794#ifndef doubletime
6795#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6796#endif
6797
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006799 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006801 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006802#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6804 SET_INT(result, 2, ru->ru_maxrss);
6805 SET_INT(result, 3, ru->ru_ixrss);
6806 SET_INT(result, 4, ru->ru_idrss);
6807 SET_INT(result, 5, ru->ru_isrss);
6808 SET_INT(result, 6, ru->ru_minflt);
6809 SET_INT(result, 7, ru->ru_majflt);
6810 SET_INT(result, 8, ru->ru_nswap);
6811 SET_INT(result, 9, ru->ru_inblock);
6812 SET_INT(result, 10, ru->ru_oublock);
6813 SET_INT(result, 11, ru->ru_msgsnd);
6814 SET_INT(result, 12, ru->ru_msgrcv);
6815 SET_INT(result, 13, ru->ru_nsignals);
6816 SET_INT(result, 14, ru->ru_nvcsw);
6817 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818#undef SET_INT
6819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (PyErr_Occurred()) {
6821 Py_DECREF(result);
6822 return NULL;
6823 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006824
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006826}
6827#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6828
6829#ifdef HAVE_WAIT3
6830PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006831"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832Wait for completion of a child process.");
6833
6834static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006835posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836{
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 pid_t pid;
6838 int options;
6839 struct rusage ru;
6840 WAIT_TYPE status;
6841 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842
Victor Stinner4195b5c2012-02-08 23:03:19 +01006843 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 Py_BEGIN_ALLOW_THREADS
6847 pid = wait3(&status, options, &ru);
6848 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849
Victor Stinner4195b5c2012-02-08 23:03:19 +01006850 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006851}
6852#endif /* HAVE_WAIT3 */
6853
6854#ifdef HAVE_WAIT4
6855PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006856"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857Wait for completion of a given child process.");
6858
6859static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006860posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006861{
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 pid_t pid;
6863 int options;
6864 struct rusage ru;
6865 WAIT_TYPE status;
6866 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867
Victor Stinner4195b5c2012-02-08 23:03:19 +01006868 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 Py_BEGIN_ALLOW_THREADS
6872 pid = wait4(pid, &status, options, &ru);
6873 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Victor Stinner4195b5c2012-02-08 23:03:19 +01006875 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876}
6877#endif /* HAVE_WAIT4 */
6878
Ross Lagerwall7807c352011-03-17 20:20:30 +02006879#if defined(HAVE_WAITID) && !defined(__APPLE__)
6880PyDoc_STRVAR(posix_waitid__doc__,
6881"waitid(idtype, id, options) -> waitid_result\n\n\
6882Wait for the completion of one or more child processes.\n\n\
6883idtype can be P_PID, P_PGID or P_ALL.\n\
6884id specifies the pid to wait on.\n\
6885options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6886or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6887Returns either waitid_result or None if WNOHANG is specified and there are\n\
6888no children in a waitable state.");
6889
6890static PyObject *
6891posix_waitid(PyObject *self, PyObject *args)
6892{
6893 PyObject *result;
6894 idtype_t idtype;
6895 id_t id;
6896 int options, res;
6897 siginfo_t si;
6898 si.si_pid = 0;
6899 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6900 return NULL;
6901 Py_BEGIN_ALLOW_THREADS
6902 res = waitid(idtype, id, &si, options);
6903 Py_END_ALLOW_THREADS
6904 if (res == -1)
6905 return posix_error();
6906
6907 if (si.si_pid == 0)
6908 Py_RETURN_NONE;
6909
6910 result = PyStructSequence_New(&WaitidResultType);
6911 if (!result)
6912 return NULL;
6913
6914 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6915 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6916 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6917 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6918 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6919 if (PyErr_Occurred()) {
6920 Py_DECREF(result);
6921 return NULL;
6922 }
6923
6924 return result;
6925}
6926#endif
6927
Guido van Rossumb6775db1994-08-01 11:34:53 +00006928#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006929PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006930"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006931Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006932
Barry Warsaw53699e91996-12-10 23:23:01 +00006933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006934posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006935{
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 pid_t pid;
6937 int options;
6938 WAIT_TYPE status;
6939 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006940
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6942 return NULL;
6943 Py_BEGIN_ALLOW_THREADS
6944 pid = waitpid(pid, &status, options);
6945 Py_END_ALLOW_THREADS
6946 if (pid == -1)
6947 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006950}
6951
Tim Petersab034fa2002-02-01 11:27:43 +00006952#elif defined(HAVE_CWAIT)
6953
6954/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006956"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006957"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006958
6959static PyObject *
6960posix_waitpid(PyObject *self, PyObject *args)
6961{
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 Py_intptr_t pid;
6963 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006964
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6966 return NULL;
6967 Py_BEGIN_ALLOW_THREADS
6968 pid = _cwait(&status, pid, options);
6969 Py_END_ALLOW_THREADS
6970 if (pid == -1)
6971 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 /* shift the status left a byte so this is more like the POSIX waitpid */
6974 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006975}
6976#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006977
Guido van Rossumad0ee831995-03-01 10:34:45 +00006978#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006979PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006980"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006981Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Barry Warsaw53699e91996-12-10 23:23:01 +00006983static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006984posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006985{
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 pid_t pid;
6987 WAIT_TYPE status;
6988 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006989
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 Py_BEGIN_ALLOW_THREADS
6991 pid = wait(&status);
6992 Py_END_ALLOW_THREADS
6993 if (pid == -1)
6994 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006995
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006997}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006998#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007000
Larry Hastings9cf065c2012-06-22 16:30:09 -07007001#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7002PyDoc_STRVAR(readlink__doc__,
7003"readlink(path, *, dir_fd=None) -> path\n\n\
7004Return a string representing the path to which the symbolic link points.\n\
7005\n\
7006If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7007 and path should be relative; path will then be relative to that directory.\n\
7008dir_fd may not be implemented on your platform.\n\
7009 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007010#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007011
Guido van Rossumb6775db1994-08-01 11:34:53 +00007012#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007013
Barry Warsaw53699e91996-12-10 23:23:01 +00007014static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007015posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007016{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007017 path_t path;
7018 int dir_fd = DEFAULT_DIR_FD;
7019 char buffer[MAXPATHLEN];
7020 ssize_t length;
7021 PyObject *return_value = NULL;
7022 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007023
Larry Hastings9cf065c2012-06-22 16:30:09 -07007024 memset(&path, 0, sizeof(path));
7025 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7026 path_converter, &path,
7027#ifdef HAVE_READLINKAT
7028 dir_fd_converter, &dir_fd
7029#else
7030 dir_fd_unavailable, &dir_fd
7031#endif
7032 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007034
Victor Stinner8c62be82010-05-06 00:08:46 +00007035 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007036#ifdef HAVE_READLINKAT
7037 if (dir_fd != DEFAULT_DIR_FD)
7038 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007039 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007040#endif
7041 length = readlink(path.narrow, buffer, sizeof(buffer));
7042 Py_END_ALLOW_THREADS
7043
7044 if (length < 0) {
7045 return_value = path_posix_error("readlink", &path);
7046 goto exit;
7047 }
7048
7049 if (PyUnicode_Check(path.object))
7050 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7051 else
7052 return_value = PyBytes_FromStringAndSize(buffer, length);
7053exit:
7054 path_cleanup(&path);
7055 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007056}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007057
7058
Guido van Rossumb6775db1994-08-01 11:34:53 +00007059#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Larry Hastings9cf065c2012-06-22 16:30:09 -07007062#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007063PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007064"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7065Create a symbolic link pointing to src named dst.\n\n\
7066target_is_directory is required on Windows if the target is to be\n\
7067 interpreted as a directory. (On Windows, symlink requires\n\
7068 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7069 target_is_directory is ignored on non-Windows platforms.\n\
7070\n\
7071If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7072 and path should be relative; path will then be relative to that directory.\n\
7073dir_fd may not be implemented on your platform.\n\
7074 If it is unavailable, using it will raise a NotImplementedError.");
7075
7076#if defined(MS_WINDOWS)
7077
7078/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7079static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7080static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7081static int
7082check_CreateSymbolicLink()
7083{
7084 HINSTANCE hKernel32;
7085 /* only recheck */
7086 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7087 return 1;
7088 hKernel32 = GetModuleHandleW(L"KERNEL32");
7089 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7090 "CreateSymbolicLinkW");
7091 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7092 "CreateSymbolicLinkA");
7093 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7094}
7095
7096#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007097
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007098static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007100{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101 path_t src;
7102 path_t dst;
7103 int dir_fd = DEFAULT_DIR_FD;
7104 int target_is_directory = 0;
7105 static char *keywords[] = {"src", "dst", "target_is_directory",
7106 "dir_fd", NULL};
7107 PyObject *return_value;
7108#ifdef MS_WINDOWS
7109 DWORD result;
7110#else
7111 int result;
7112#endif
7113
7114 memset(&src, 0, sizeof(src));
7115 src.argument_name = "src";
7116 memset(&dst, 0, sizeof(dst));
7117 dst.argument_name = "dst";
7118
7119#ifdef MS_WINDOWS
7120 if (!check_CreateSymbolicLink()) {
7121 PyErr_SetString(PyExc_NotImplementedError,
7122 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007123 return NULL;
7124 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125 if (!win32_can_symlink) {
7126 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007127 return NULL;
7128 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129#endif
7130
7131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7132 keywords,
7133 path_converter, &src,
7134 path_converter, &dst,
7135 &target_is_directory,
7136#ifdef HAVE_SYMLINKAT
7137 dir_fd_converter, &dir_fd
7138#else
7139 dir_fd_unavailable, &dir_fd
7140#endif
7141 ))
7142 return NULL;
7143
7144 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7145 PyErr_SetString(PyExc_ValueError,
7146 "symlink: src and dst must be the same type");
7147 return_value = NULL;
7148 goto exit;
7149 }
7150
7151#ifdef MS_WINDOWS
7152 Py_BEGIN_ALLOW_THREADS
7153 if (dst.wide)
7154 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7155 target_is_directory);
7156 else
7157 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7158 target_is_directory);
7159 Py_END_ALLOW_THREADS
7160
7161 if (!result) {
7162 return_value = win32_error_object("symlink", src.object);
7163 goto exit;
7164 }
7165
7166#else
7167
7168 Py_BEGIN_ALLOW_THREADS
7169#if HAVE_SYMLINKAT
7170 if (dir_fd != DEFAULT_DIR_FD)
7171 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7172 else
7173#endif
7174 result = symlink(src.narrow, dst.narrow);
7175 Py_END_ALLOW_THREADS
7176
7177 if (result) {
7178 return_value = path_error("symlink", &dst);
7179 goto exit;
7180 }
7181#endif
7182
7183 return_value = Py_None;
7184 Py_INCREF(Py_None);
7185 goto exit; /* silence "unused label" warning */
7186exit:
7187 path_cleanup(&src);
7188 path_cleanup(&dst);
7189 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007190}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007191
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007192#endif /* HAVE_SYMLINK */
7193
Larry Hastings9cf065c2012-06-22 16:30:09 -07007194
Brian Curtind40e6f72010-07-08 21:39:08 +00007195#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7196
Brian Curtind40e6f72010-07-08 21:39:08 +00007197static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007198win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007199{
7200 wchar_t *path;
7201 DWORD n_bytes_returned;
7202 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007203 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007204 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007205 HANDLE reparse_point_handle;
7206
7207 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7208 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7209 wchar_t *print_name;
7210
Larry Hastings9cf065c2012-06-22 16:30:09 -07007211 static char *keywords[] = {"path", "dir_fd", NULL};
7212
7213 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7214 &po,
7215 dir_fd_unavailable, &dir_fd
7216 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007217 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007218
Victor Stinnereb5657a2011-09-30 01:44:27 +02007219 path = PyUnicode_AsUnicode(po);
7220 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007221 return NULL;
7222
7223 /* First get a handle to the reparse point */
7224 Py_BEGIN_ALLOW_THREADS
7225 reparse_point_handle = CreateFileW(
7226 path,
7227 0,
7228 0,
7229 0,
7230 OPEN_EXISTING,
7231 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7232 0);
7233 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007234
Brian Curtind40e6f72010-07-08 21:39:08 +00007235 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007236 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007237
Brian Curtind40e6f72010-07-08 21:39:08 +00007238 Py_BEGIN_ALLOW_THREADS
7239 /* New call DeviceIoControl to read the reparse point */
7240 io_result = DeviceIoControl(
7241 reparse_point_handle,
7242 FSCTL_GET_REPARSE_POINT,
7243 0, 0, /* in buffer */
7244 target_buffer, sizeof(target_buffer),
7245 &n_bytes_returned,
7246 0 /* we're not using OVERLAPPED_IO */
7247 );
7248 CloseHandle(reparse_point_handle);
7249 Py_END_ALLOW_THREADS
7250
7251 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007252 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007253
7254 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7255 {
7256 PyErr_SetString(PyExc_ValueError,
7257 "not a symbolic link");
7258 return NULL;
7259 }
Brian Curtin74e45612010-07-09 15:58:59 +00007260 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7261 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7262
7263 result = PyUnicode_FromWideChar(print_name,
7264 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007265 return result;
7266}
7267
7268#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7269
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007270
Larry Hastings605a62d2012-06-24 04:33:36 -07007271static PyStructSequence_Field times_result_fields[] = {
7272 {"user", "user time"},
7273 {"system", "system time"},
7274 {"children_user", "user time of children"},
7275 {"children_system", "system time of children"},
7276 {"elapsed", "elapsed time since an arbitrary point in the past"},
7277 {NULL}
7278};
7279
7280PyDoc_STRVAR(times_result__doc__,
7281"times_result: Result from os.times().\n\n\
7282This object may be accessed either as a tuple of\n\
7283 (user, system, children_user, children_system, elapsed),\n\
7284or via the attributes user, system, children_user, children_system,\n\
7285and elapsed.\n\
7286\n\
7287See os.times for more information.");
7288
7289static PyStructSequence_Desc times_result_desc = {
7290 "times_result", /* name */
7291 times_result__doc__, /* doc */
7292 times_result_fields,
7293 5
7294};
7295
7296static PyTypeObject TimesResultType;
7297
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007298#ifdef MS_WINDOWS
7299#define HAVE_TIMES /* mandatory, for the method table */
7300#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007301
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007302#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007303
7304static PyObject *
7305build_times_result(double user, double system,
7306 double children_user, double children_system,
7307 double elapsed)
7308{
7309 PyObject *value = PyStructSequence_New(&TimesResultType);
7310 if (value == NULL)
7311 return NULL;
7312
7313#define SET(i, field) \
7314 { \
7315 PyObject *o = PyFloat_FromDouble(field); \
7316 if (!o) { \
7317 Py_DECREF(value); \
7318 return NULL; \
7319 } \
7320 PyStructSequence_SET_ITEM(value, i, o); \
7321 } \
7322
7323 SET(0, user);
7324 SET(1, system);
7325 SET(2, children_user);
7326 SET(3, children_system);
7327 SET(4, elapsed);
7328
7329#undef SET
7330
7331 return value;
7332}
7333
7334PyDoc_STRVAR(posix_times__doc__,
7335"times() -> times_result\n\n\
7336Return an object containing floating point numbers indicating process\n\
7337times. The object behaves like a named tuple with these fields:\n\
7338 (utime, stime, cutime, cstime, elapsed_time)");
7339
Guido van Rossumd48f2521997-12-05 22:19:34 +00007340#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7341static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007342system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007343{
7344 ULONG value = 0;
7345
7346 Py_BEGIN_ALLOW_THREADS
7347 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7348 Py_END_ALLOW_THREADS
7349
7350 return value;
7351}
7352
7353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007354posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007355{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007356 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007357 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007358 (double)0 /* t.tms_utime / HZ */,
7359 (double)0 /* t.tms_stime / HZ */,
7360 (double)0 /* t.tms_cutime / HZ */,
7361 (double)0 /* t.tms_cstime / HZ */,
7362 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007363}
Larry Hastings605a62d2012-06-24 04:33:36 -07007364#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007366posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007367{
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 FILETIME create, exit, kernel, user;
7369 HANDLE hProc;
7370 hProc = GetCurrentProcess();
7371 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7372 /* The fields of a FILETIME structure are the hi and lo part
7373 of a 64-bit value expressed in 100 nanosecond units.
7374 1e7 is one second in such units; 1e-7 the inverse.
7375 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7376 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007377 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 (double)(user.dwHighDateTime*429.4967296 +
7379 user.dwLowDateTime*1e-7),
7380 (double)(kernel.dwHighDateTime*429.4967296 +
7381 kernel.dwLowDateTime*1e-7),
7382 (double)0,
7383 (double)0,
7384 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007385}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007386#else /* Neither Windows nor OS/2 */
7387#define NEED_TICKS_PER_SECOND
7388static long ticks_per_second = -1;
7389static PyObject *
7390posix_times(PyObject *self, PyObject *noargs)
7391{
7392 struct tms t;
7393 clock_t c;
7394 errno = 0;
7395 c = times(&t);
7396 if (c == (clock_t) -1)
7397 return posix_error();
7398 return build_times_result(
7399 (double)t.tms_utime / ticks_per_second,
7400 (double)t.tms_stime / ticks_per_second,
7401 (double)t.tms_cutime / ticks_per_second,
7402 (double)t.tms_cstime / ticks_per_second,
7403 (double)c / ticks_per_second);
7404}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007405#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007406
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007407#endif /* HAVE_TIMES */
7408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007409
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007410#ifdef HAVE_GETSID
7411PyDoc_STRVAR(posix_getsid__doc__,
7412"getsid(pid) -> sid\n\n\
7413Call the system call getsid().");
7414
7415static PyObject *
7416posix_getsid(PyObject *self, PyObject *args)
7417{
Victor Stinner8c62be82010-05-06 00:08:46 +00007418 pid_t pid;
7419 int sid;
7420 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7421 return NULL;
7422 sid = getsid(pid);
7423 if (sid < 0)
7424 return posix_error();
7425 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007426}
7427#endif /* HAVE_GETSID */
7428
7429
Guido van Rossumb6775db1994-08-01 11:34:53 +00007430#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007431PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007432"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007433Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007434
Barry Warsaw53699e91996-12-10 23:23:01 +00007435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007436posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007437{
Victor Stinner8c62be82010-05-06 00:08:46 +00007438 if (setsid() < 0)
7439 return posix_error();
7440 Py_INCREF(Py_None);
7441 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007442}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007443#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007444
Guido van Rossumb6775db1994-08-01 11:34:53 +00007445#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007446PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007447"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007448Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007449
Barry Warsaw53699e91996-12-10 23:23:01 +00007450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007451posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007452{
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 pid_t pid;
7454 int pgrp;
7455 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7456 return NULL;
7457 if (setpgid(pid, pgrp) < 0)
7458 return posix_error();
7459 Py_INCREF(Py_None);
7460 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007461}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007462#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007463
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007464
Guido van Rossumb6775db1994-08-01 11:34:53 +00007465#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007466PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007467"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007468Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007469
Barry Warsaw53699e91996-12-10 23:23:01 +00007470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007471posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007472{
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 int fd;
7474 pid_t pgid;
7475 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7476 return NULL;
7477 pgid = tcgetpgrp(fd);
7478 if (pgid < 0)
7479 return posix_error();
7480 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007481}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007482#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007484
Guido van Rossumb6775db1994-08-01 11:34:53 +00007485#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007486PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007487"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007488Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007489
Barry Warsaw53699e91996-12-10 23:23:01 +00007490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007491posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007492{
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 int fd;
7494 pid_t pgid;
7495 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7496 return NULL;
7497 if (tcsetpgrp(fd, pgid) < 0)
7498 return posix_error();
7499 Py_INCREF(Py_None);
7500 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007501}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007502#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007503
Guido van Rossum687dd131993-05-17 08:34:16 +00007504/* Functions acting on file descriptors */
7505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007506PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007507"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7508Open a file for low level IO. Returns a file handle (integer).\n\
7509\n\
7510If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7511 and path should be relative; path will then be relative to that directory.\n\
7512dir_fd may not be implemented on your platform.\n\
7513 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007514
Barry Warsaw53699e91996-12-10 23:23:01 +00007515static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007516posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007517{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007518 path_t path;
7519 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007520 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007521 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007522 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007523 PyObject *return_value = NULL;
7524 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007525
Larry Hastings9cf065c2012-06-22 16:30:09 -07007526 memset(&path, 0, sizeof(path));
7527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7528 path_converter, &path,
7529 &flags, &mode,
7530#ifdef HAVE_OPENAT
7531 dir_fd_converter, &dir_fd
7532#else
7533 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007534#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007535 ))
7536 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007537
Victor Stinner8c62be82010-05-06 00:08:46 +00007538 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007539#ifdef MS_WINDOWS
7540 if (path.wide)
7541 fd = _wopen(path.wide, flags, mode);
7542 else
7543#endif
7544#ifdef HAVE_OPENAT
7545 if (dir_fd != DEFAULT_DIR_FD)
7546 fd = openat(dir_fd, path.narrow, flags, mode);
7547 else
7548#endif
7549 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007550 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007551
Larry Hastings9cf065c2012-06-22 16:30:09 -07007552 if (fd == -1) {
7553#ifdef MS_WINDOWS
7554 /* force use of posix_error here for exact backwards compatibility */
7555 if (path.wide)
7556 return_value = posix_error();
7557 else
7558#endif
7559 return_value = path_error("open", &path);
7560 goto exit;
7561 }
7562
7563 return_value = PyLong_FromLong((long)fd);
7564
7565exit:
7566 path_cleanup(&path);
7567 return return_value;
7568}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007570PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007571"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007572Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007573
Barry Warsaw53699e91996-12-10 23:23:01 +00007574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007575posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 int fd, res;
7578 if (!PyArg_ParseTuple(args, "i:close", &fd))
7579 return NULL;
7580 if (!_PyVerify_fd(fd))
7581 return posix_error();
7582 Py_BEGIN_ALLOW_THREADS
7583 res = close(fd);
7584 Py_END_ALLOW_THREADS
7585 if (res < 0)
7586 return posix_error();
7587 Py_INCREF(Py_None);
7588 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007589}
7590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007591
Victor Stinner8c62be82010-05-06 00:08:46 +00007592PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007593"closerange(fd_low, fd_high)\n\n\
7594Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7595
7596static PyObject *
7597posix_closerange(PyObject *self, PyObject *args)
7598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 int fd_from, fd_to, i;
7600 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7601 return NULL;
7602 Py_BEGIN_ALLOW_THREADS
7603 for (i = fd_from; i < fd_to; i++)
7604 if (_PyVerify_fd(i))
7605 close(i);
7606 Py_END_ALLOW_THREADS
7607 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007608}
7609
7610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007611PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007612"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007613Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007614
Barry Warsaw53699e91996-12-10 23:23:01 +00007615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007616posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007617{
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 int fd;
7619 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7620 return NULL;
7621 if (!_PyVerify_fd(fd))
7622 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007623 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 if (fd < 0)
7625 return posix_error();
7626 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007627}
7628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007630PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007631"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007632Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007633
Barry Warsaw53699e91996-12-10 23:23:01 +00007634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007635posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007636{
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 int fd, fd2, res;
7638 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7639 return NULL;
7640 if (!_PyVerify_fd_dup2(fd, fd2))
7641 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 if (res < 0)
7644 return posix_error();
7645 Py_INCREF(Py_None);
7646 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007647}
7648
Ross Lagerwall7807c352011-03-17 20:20:30 +02007649#ifdef HAVE_LOCKF
7650PyDoc_STRVAR(posix_lockf__doc__,
7651"lockf(fd, cmd, len)\n\n\
7652Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7653fd is an open file descriptor.\n\
7654cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7655F_TEST.\n\
7656len specifies the section of the file to lock.");
7657
7658static PyObject *
7659posix_lockf(PyObject *self, PyObject *args)
7660{
7661 int fd, cmd, res;
7662 off_t len;
7663 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7664 &fd, &cmd, _parse_off_t, &len))
7665 return NULL;
7666
7667 Py_BEGIN_ALLOW_THREADS
7668 res = lockf(fd, cmd, len);
7669 Py_END_ALLOW_THREADS
7670
7671 if (res < 0)
7672 return posix_error();
7673
7674 Py_RETURN_NONE;
7675}
7676#endif
7677
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007678
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007679PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007680"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007681Set the current position of a file descriptor.\n\
7682Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007683
Barry Warsaw53699e91996-12-10 23:23:01 +00007684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007685posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007686{
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007688#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007690#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007691 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007692#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007693 PyObject *posobj;
7694 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007696#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007697 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7698 switch (how) {
7699 case 0: how = SEEK_SET; break;
7700 case 1: how = SEEK_CUR; break;
7701 case 2: how = SEEK_END; break;
7702 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007703#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007704
Ross Lagerwall8e749672011-03-17 21:54:07 +02007705#if !defined(HAVE_LARGEFILE_SUPPORT)
7706 pos = PyLong_AsLong(posobj);
7707#else
7708 pos = PyLong_AsLongLong(posobj);
7709#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 if (PyErr_Occurred())
7711 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007712
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 if (!_PyVerify_fd(fd))
7714 return posix_error();
7715 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007716#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007718#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007720#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 Py_END_ALLOW_THREADS
7722 if (res < 0)
7723 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007724
7725#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007727#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007729#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007730}
7731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007733PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007734"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007735Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007736
Barry Warsaw53699e91996-12-10 23:23:01 +00007737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007738posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007739{
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 int fd, size;
7741 Py_ssize_t n;
7742 PyObject *buffer;
7743 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7744 return NULL;
7745 if (size < 0) {
7746 errno = EINVAL;
7747 return posix_error();
7748 }
7749 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7750 if (buffer == NULL)
7751 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007752 if (!_PyVerify_fd(fd)) {
7753 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007755 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 Py_BEGIN_ALLOW_THREADS
7757 n = read(fd, PyBytes_AS_STRING(buffer), size);
7758 Py_END_ALLOW_THREADS
7759 if (n < 0) {
7760 Py_DECREF(buffer);
7761 return posix_error();
7762 }
7763 if (n != size)
7764 _PyBytes_Resize(&buffer, n);
7765 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007766}
7767
Ross Lagerwall7807c352011-03-17 20:20:30 +02007768#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7769 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007770static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007771iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7772{
7773 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007774 Py_ssize_t blen, total = 0;
7775
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007776 *iov = PyMem_New(struct iovec, cnt);
7777 if (*iov == NULL) {
7778 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007779 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007780 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007781
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007782 *buf = PyMem_New(Py_buffer, cnt);
7783 if (*buf == NULL) {
7784 PyMem_Del(*iov);
7785 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007786 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007787 }
7788
7789 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007790 PyObject *item = PySequence_GetItem(seq, i);
7791 if (item == NULL)
7792 goto fail;
7793 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7794 Py_DECREF(item);
7795 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007796 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007797 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007798 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007799 blen = (*buf)[i].len;
7800 (*iov)[i].iov_len = blen;
7801 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007802 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007803 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007804
7805fail:
7806 PyMem_Del(*iov);
7807 for (j = 0; j < i; j++) {
7808 PyBuffer_Release(&(*buf)[j]);
7809 }
7810 PyMem_Del(*buf);
7811 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007812}
7813
7814static void
7815iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7816{
7817 int i;
7818 PyMem_Del(iov);
7819 for (i = 0; i < cnt; i++) {
7820 PyBuffer_Release(&buf[i]);
7821 }
7822 PyMem_Del(buf);
7823}
7824#endif
7825
Ross Lagerwall7807c352011-03-17 20:20:30 +02007826#ifdef HAVE_READV
7827PyDoc_STRVAR(posix_readv__doc__,
7828"readv(fd, buffers) -> bytesread\n\n\
7829Read from a file descriptor into a number of writable buffers. buffers\n\
7830is an arbitrary sequence of writable buffers.\n\
7831Returns the total number of bytes read.");
7832
7833static PyObject *
7834posix_readv(PyObject *self, PyObject *args)
7835{
7836 int fd, cnt;
7837 Py_ssize_t n;
7838 PyObject *seq;
7839 struct iovec *iov;
7840 Py_buffer *buf;
7841
7842 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7843 return NULL;
7844 if (!PySequence_Check(seq)) {
7845 PyErr_SetString(PyExc_TypeError,
7846 "readv() arg 2 must be a sequence");
7847 return NULL;
7848 }
7849 cnt = PySequence_Size(seq);
7850
7851 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7852 return NULL;
7853
7854 Py_BEGIN_ALLOW_THREADS
7855 n = readv(fd, iov, cnt);
7856 Py_END_ALLOW_THREADS
7857
7858 iov_cleanup(iov, buf, cnt);
7859 return PyLong_FromSsize_t(n);
7860}
7861#endif
7862
7863#ifdef HAVE_PREAD
7864PyDoc_STRVAR(posix_pread__doc__,
7865"pread(fd, buffersize, offset) -> string\n\n\
7866Read from a file descriptor, fd, at a position of offset. It will read up\n\
7867to buffersize number of bytes. The file offset remains unchanged.");
7868
7869static PyObject *
7870posix_pread(PyObject *self, PyObject *args)
7871{
7872 int fd, size;
7873 off_t offset;
7874 Py_ssize_t n;
7875 PyObject *buffer;
7876 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7877 return NULL;
7878
7879 if (size < 0) {
7880 errno = EINVAL;
7881 return posix_error();
7882 }
7883 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7884 if (buffer == NULL)
7885 return NULL;
7886 if (!_PyVerify_fd(fd)) {
7887 Py_DECREF(buffer);
7888 return posix_error();
7889 }
7890 Py_BEGIN_ALLOW_THREADS
7891 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7892 Py_END_ALLOW_THREADS
7893 if (n < 0) {
7894 Py_DECREF(buffer);
7895 return posix_error();
7896 }
7897 if (n != size)
7898 _PyBytes_Resize(&buffer, n);
7899 return buffer;
7900}
7901#endif
7902
7903PyDoc_STRVAR(posix_write__doc__,
7904"write(fd, string) -> byteswritten\n\n\
7905Write a string to a file descriptor.");
7906
7907static PyObject *
7908posix_write(PyObject *self, PyObject *args)
7909{
7910 Py_buffer pbuf;
7911 int fd;
7912 Py_ssize_t size, len;
7913
7914 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7915 return NULL;
7916 if (!_PyVerify_fd(fd)) {
7917 PyBuffer_Release(&pbuf);
7918 return posix_error();
7919 }
7920 len = pbuf.len;
7921 Py_BEGIN_ALLOW_THREADS
7922#if defined(MS_WIN64) || defined(MS_WINDOWS)
7923 if (len > INT_MAX)
7924 len = INT_MAX;
7925 size = write(fd, pbuf.buf, (int)len);
7926#else
7927 size = write(fd, pbuf.buf, len);
7928#endif
7929 Py_END_ALLOW_THREADS
7930 PyBuffer_Release(&pbuf);
7931 if (size < 0)
7932 return posix_error();
7933 return PyLong_FromSsize_t(size);
7934}
7935
7936#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007937PyDoc_STRVAR(posix_sendfile__doc__,
7938"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7939sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7940 -> byteswritten\n\
7941Copy nbytes bytes from file descriptor in to file descriptor out.");
7942
7943static PyObject *
7944posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7945{
7946 int in, out;
7947 Py_ssize_t ret;
7948 off_t offset;
7949
7950#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7951#ifndef __APPLE__
7952 Py_ssize_t len;
7953#endif
7954 PyObject *headers = NULL, *trailers = NULL;
7955 Py_buffer *hbuf, *tbuf;
7956 off_t sbytes;
7957 struct sf_hdtr sf;
7958 int flags = 0;
7959 sf.headers = NULL;
7960 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007961 static char *keywords[] = {"out", "in",
7962 "offset", "count",
7963 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007964
7965#ifdef __APPLE__
7966 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007967 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007968#else
7969 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007970 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007971#endif
7972 &headers, &trailers, &flags))
7973 return NULL;
7974 if (headers != NULL) {
7975 if (!PySequence_Check(headers)) {
7976 PyErr_SetString(PyExc_TypeError,
7977 "sendfile() headers must be a sequence or None");
7978 return NULL;
7979 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007980 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007981 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007982 if (sf.hdr_cnt > 0 &&
7983 !(i = iov_setup(&(sf.headers), &hbuf,
7984 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007985 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007986#ifdef __APPLE__
7987 sbytes += i;
7988#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007989 }
7990 }
7991 if (trailers != NULL) {
7992 if (!PySequence_Check(trailers)) {
7993 PyErr_SetString(PyExc_TypeError,
7994 "sendfile() trailers must be a sequence or None");
7995 return NULL;
7996 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007997 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007998 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007999 if (sf.trl_cnt > 0 &&
8000 !(i = iov_setup(&(sf.trailers), &tbuf,
8001 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008002 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008003#ifdef __APPLE__
8004 sbytes += i;
8005#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008006 }
8007 }
8008
8009 Py_BEGIN_ALLOW_THREADS
8010#ifdef __APPLE__
8011 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8012#else
8013 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8014#endif
8015 Py_END_ALLOW_THREADS
8016
8017 if (sf.headers != NULL)
8018 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8019 if (sf.trailers != NULL)
8020 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8021
8022 if (ret < 0) {
8023 if ((errno == EAGAIN) || (errno == EBUSY)) {
8024 if (sbytes != 0) {
8025 // some data has been sent
8026 goto done;
8027 }
8028 else {
8029 // no data has been sent; upper application is supposed
8030 // to retry on EAGAIN or EBUSY
8031 return posix_error();
8032 }
8033 }
8034 return posix_error();
8035 }
8036 goto done;
8037
8038done:
8039 #if !defined(HAVE_LARGEFILE_SUPPORT)
8040 return Py_BuildValue("l", sbytes);
8041 #else
8042 return Py_BuildValue("L", sbytes);
8043 #endif
8044
8045#else
8046 Py_ssize_t count;
8047 PyObject *offobj;
8048 static char *keywords[] = {"out", "in",
8049 "offset", "count", NULL};
8050 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8051 keywords, &out, &in, &offobj, &count))
8052 return NULL;
8053#ifdef linux
8054 if (offobj == Py_None) {
8055 Py_BEGIN_ALLOW_THREADS
8056 ret = sendfile(out, in, NULL, count);
8057 Py_END_ALLOW_THREADS
8058 if (ret < 0)
8059 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008060 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 }
8062#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008063 if (!_parse_off_t(offobj, &offset))
8064 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065 Py_BEGIN_ALLOW_THREADS
8066 ret = sendfile(out, in, &offset, count);
8067 Py_END_ALLOW_THREADS
8068 if (ret < 0)
8069 return posix_error();
8070 return Py_BuildValue("n", ret);
8071#endif
8072}
8073#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008075PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008076"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008077Like stat(), but for an open file descriptor.\n\
8078Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008079
Barry Warsaw53699e91996-12-10 23:23:01 +00008080static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008081posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008082{
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 int fd;
8084 STRUCT_STAT st;
8085 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008086 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008088#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 /* on OpenVMS we must ensure that all bytes are written to the file */
8090 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008091#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008092 Py_BEGIN_ALLOW_THREADS
8093 res = FSTAT(fd, &st);
8094 Py_END_ALLOW_THREADS
8095 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008096#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008098#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008100#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 }
Tim Peters5aa91602002-01-30 05:46:57 +00008102
Victor Stinner4195b5c2012-02-08 23:03:19 +01008103 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008104}
8105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008106PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008107"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008108Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008109connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008110
8111static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008112posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008113{
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 int fd;
8115 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8116 return NULL;
8117 if (!_PyVerify_fd(fd))
8118 return PyBool_FromLong(0);
8119 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008120}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008121
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008122#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008123PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008124"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008125Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008126
Barry Warsaw53699e91996-12-10 23:23:01 +00008127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008128posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008129{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008130#if defined(PYOS_OS2)
8131 HFILE read, write;
8132 APIRET rc;
8133
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008134 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008135 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008136 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008137
8138 return Py_BuildValue("(ii)", read, write);
8139#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008140#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 int fds[2];
8142 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 if (res != 0)
8145 return posix_error();
8146 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008147#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 HANDLE read, write;
8149 int read_fd, write_fd;
8150 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 if (!ok)
8153 return win32_error("CreatePipe", NULL);
8154 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8155 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8156 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008157#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008158#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008159}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008160#endif /* HAVE_PIPE */
8161
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008162#ifdef HAVE_PIPE2
8163PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008164"pipe2(flags) -> (read_end, write_end)\n\n\
8165Create a pipe with flags set atomically.\n\
8166flags can be constructed by ORing together one or more of these values:\n\
8167O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008168");
8169
8170static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008171posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008172{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008173 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008174 int fds[2];
8175 int res;
8176
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008177 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008178 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008179 return NULL;
8180
8181 res = pipe2(fds, flags);
8182 if (res != 0)
8183 return posix_error();
8184 return Py_BuildValue("(ii)", fds[0], fds[1]);
8185}
8186#endif /* HAVE_PIPE2 */
8187
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188#ifdef HAVE_WRITEV
8189PyDoc_STRVAR(posix_writev__doc__,
8190"writev(fd, buffers) -> byteswritten\n\n\
8191Write the contents of buffers to a file descriptor, where buffers is an\n\
8192arbitrary sequence of buffers.\n\
8193Returns the total bytes written.");
8194
8195static PyObject *
8196posix_writev(PyObject *self, PyObject *args)
8197{
8198 int fd, cnt;
8199 Py_ssize_t res;
8200 PyObject *seq;
8201 struct iovec *iov;
8202 Py_buffer *buf;
8203 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8204 return NULL;
8205 if (!PySequence_Check(seq)) {
8206 PyErr_SetString(PyExc_TypeError,
8207 "writev() arg 2 must be a sequence");
8208 return NULL;
8209 }
8210 cnt = PySequence_Size(seq);
8211
8212 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8213 return NULL;
8214 }
8215
8216 Py_BEGIN_ALLOW_THREADS
8217 res = writev(fd, iov, cnt);
8218 Py_END_ALLOW_THREADS
8219
8220 iov_cleanup(iov, buf, cnt);
8221 return PyLong_FromSsize_t(res);
8222}
8223#endif
8224
8225#ifdef HAVE_PWRITE
8226PyDoc_STRVAR(posix_pwrite__doc__,
8227"pwrite(fd, string, offset) -> byteswritten\n\n\
8228Write string to a file descriptor, fd, from offset, leaving the file\n\
8229offset unchanged.");
8230
8231static PyObject *
8232posix_pwrite(PyObject *self, PyObject *args)
8233{
8234 Py_buffer pbuf;
8235 int fd;
8236 off_t offset;
8237 Py_ssize_t size;
8238
8239 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8240 return NULL;
8241
8242 if (!_PyVerify_fd(fd)) {
8243 PyBuffer_Release(&pbuf);
8244 return posix_error();
8245 }
8246 Py_BEGIN_ALLOW_THREADS
8247 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8248 Py_END_ALLOW_THREADS
8249 PyBuffer_Release(&pbuf);
8250 if (size < 0)
8251 return posix_error();
8252 return PyLong_FromSsize_t(size);
8253}
8254#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008255
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008256#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008257PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008258"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8259Create a FIFO (a POSIX named pipe).\n\
8260\n\
8261If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8262 and path should be relative; path will then be relative to that directory.\n\
8263dir_fd may not be implemented on your platform.\n\
8264 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008265
Barry Warsaw53699e91996-12-10 23:23:01 +00008266static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008267posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008268{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008269 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008271 int dir_fd = DEFAULT_DIR_FD;
8272 int result;
8273 PyObject *return_value = NULL;
8274 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8275
8276 memset(&path, 0, sizeof(path));
8277 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8278 path_converter, &path,
8279 &mode,
8280#ifdef HAVE_MKFIFOAT
8281 dir_fd_converter, &dir_fd
8282#else
8283 dir_fd_unavailable, &dir_fd
8284#endif
8285 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008286 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008287
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008289#ifdef HAVE_MKFIFOAT
8290 if (dir_fd != DEFAULT_DIR_FD)
8291 result = mkfifoat(dir_fd, path.narrow, mode);
8292 else
8293#endif
8294 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008296
8297 if (result < 0) {
8298 return_value = posix_error();
8299 goto exit;
8300 }
8301
8302 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008304
8305exit:
8306 path_cleanup(&path);
8307 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008308}
8309#endif
8310
Neal Norwitz11690112002-07-30 01:08:28 +00008311#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008312PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008313"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008314Create a filesystem node (file, device special file or named pipe)\n\
8315named filename. mode specifies both the permissions to use and the\n\
8316type of node to be created, being combined (bitwise OR) with one of\n\
8317S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008318device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008319os.makedev()), otherwise it is ignored.\n\
8320\n\
8321If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8322 and path should be relative; path will then be relative to that directory.\n\
8323dir_fd may not be implemented on your platform.\n\
8324 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008325
8326
8327static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008328posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008329{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008330 path_t path;
8331 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008333 int dir_fd = DEFAULT_DIR_FD;
8334 int result;
8335 PyObject *return_value = NULL;
8336 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8337
8338 memset(&path, 0, sizeof(path));
8339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8340 path_converter, &path,
8341 &mode, &device,
8342#ifdef HAVE_MKNODAT
8343 dir_fd_converter, &dir_fd
8344#else
8345 dir_fd_unavailable, &dir_fd
8346#endif
8347 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008349
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008351#ifdef HAVE_MKNODAT
8352 if (dir_fd != DEFAULT_DIR_FD)
8353 result = mknodat(dir_fd, path.narrow, mode, device);
8354 else
8355#endif
8356 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008358
8359 if (result < 0) {
8360 return_value = posix_error();
8361 goto exit;
8362 }
8363
8364 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008366
Larry Hastings9cf065c2012-06-22 16:30:09 -07008367exit:
8368 path_cleanup(&path);
8369 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008370}
8371#endif
8372
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008373#ifdef HAVE_DEVICE_MACROS
8374PyDoc_STRVAR(posix_major__doc__,
8375"major(device) -> major number\n\
8376Extracts a device major number from a raw device number.");
8377
8378static PyObject *
8379posix_major(PyObject *self, PyObject *args)
8380{
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 int device;
8382 if (!PyArg_ParseTuple(args, "i:major", &device))
8383 return NULL;
8384 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008385}
8386
8387PyDoc_STRVAR(posix_minor__doc__,
8388"minor(device) -> minor number\n\
8389Extracts a device minor number from a raw device number.");
8390
8391static PyObject *
8392posix_minor(PyObject *self, PyObject *args)
8393{
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 int device;
8395 if (!PyArg_ParseTuple(args, "i:minor", &device))
8396 return NULL;
8397 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008398}
8399
8400PyDoc_STRVAR(posix_makedev__doc__,
8401"makedev(major, minor) -> device number\n\
8402Composes a raw device number from the major and minor device numbers.");
8403
8404static PyObject *
8405posix_makedev(PyObject *self, PyObject *args)
8406{
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 int major, minor;
8408 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8409 return NULL;
8410 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008411}
8412#endif /* device macros */
8413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008414
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008415#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008416PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008417"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008418Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008419
Barry Warsaw53699e91996-12-10 23:23:01 +00008420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008421posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008422{
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 int fd;
8424 off_t length;
8425 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008426
Ross Lagerwall7807c352011-03-17 20:20:30 +02008427 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008429
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 Py_BEGIN_ALLOW_THREADS
8431 res = ftruncate(fd, length);
8432 Py_END_ALLOW_THREADS
8433 if (res < 0)
8434 return posix_error();
8435 Py_INCREF(Py_None);
8436 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008437}
8438#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008439
Ross Lagerwall7807c352011-03-17 20:20:30 +02008440#ifdef HAVE_TRUNCATE
8441PyDoc_STRVAR(posix_truncate__doc__,
8442"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008443Truncate the file given by path to length bytes.\n\
8444On some platforms, path may also be specified as an open file descriptor.\n\
8445 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008446
8447static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008448posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008449{
Georg Brandl306336b2012-06-24 12:55:33 +02008450 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008451 off_t length;
8452 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008453 PyObject *result = NULL;
8454 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008455
Georg Brandl306336b2012-06-24 12:55:33 +02008456 memset(&path, 0, sizeof(path));
8457#ifdef HAVE_FTRUNCATE
8458 path.allow_fd = 1;
8459#endif
8460 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8461 path_converter, &path,
8462 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008463 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008464
8465 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008466#ifdef HAVE_FTRUNCATE
8467 if (path.fd != -1)
8468 res = ftruncate(path.fd, length);
8469 else
8470#endif
8471 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008472 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008473 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008474 result = path_posix_error("truncate", &path);
8475 else {
8476 Py_INCREF(Py_None);
8477 result = Py_None;
8478 }
8479 path_cleanup(&path);
8480 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008481}
8482#endif
8483
8484#ifdef HAVE_POSIX_FALLOCATE
8485PyDoc_STRVAR(posix_posix_fallocate__doc__,
8486"posix_fallocate(fd, offset, len)\n\n\
8487Ensures that enough disk space is allocated for the file specified by fd\n\
8488starting from offset and continuing for len bytes.");
8489
8490static PyObject *
8491posix_posix_fallocate(PyObject *self, PyObject *args)
8492{
8493 off_t len, offset;
8494 int res, fd;
8495
8496 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8497 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8498 return NULL;
8499
8500 Py_BEGIN_ALLOW_THREADS
8501 res = posix_fallocate(fd, offset, len);
8502 Py_END_ALLOW_THREADS
8503 if (res != 0) {
8504 errno = res;
8505 return posix_error();
8506 }
8507 Py_RETURN_NONE;
8508}
8509#endif
8510
8511#ifdef HAVE_POSIX_FADVISE
8512PyDoc_STRVAR(posix_posix_fadvise__doc__,
8513"posix_fadvise(fd, offset, len, advice)\n\n\
8514Announces an intention to access data in a specific pattern thus allowing\n\
8515the kernel to make optimizations.\n\
8516The advice applies to the region of the file specified by fd starting at\n\
8517offset and continuing for len bytes.\n\
8518advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8519POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8520POSIX_FADV_DONTNEED.");
8521
8522static PyObject *
8523posix_posix_fadvise(PyObject *self, PyObject *args)
8524{
8525 off_t len, offset;
8526 int res, fd, advice;
8527
8528 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8529 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8530 return NULL;
8531
8532 Py_BEGIN_ALLOW_THREADS
8533 res = posix_fadvise(fd, offset, len, advice);
8534 Py_END_ALLOW_THREADS
8535 if (res != 0) {
8536 errno = res;
8537 return posix_error();
8538 }
8539 Py_RETURN_NONE;
8540}
8541#endif
8542
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008543#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008544PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008545"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008546Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008547
Fred Drake762e2061999-08-26 17:23:54 +00008548/* Save putenv() parameters as values here, so we can collect them when they
8549 * get re-set with another call for the same key. */
8550static PyObject *posix_putenv_garbage;
8551
Tim Peters5aa91602002-01-30 05:46:57 +00008552static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008553posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008554{
Victor Stinner84ae1182010-05-06 22:05:07 +00008555 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008556#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008557 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008558 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008559
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008561 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008562 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008564
Victor Stinner65170952011-11-22 22:16:17 +01008565 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008566 if (newstr == NULL) {
8567 PyErr_NoMemory();
8568 goto error;
8569 }
Victor Stinner65170952011-11-22 22:16:17 +01008570 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8571 PyErr_Format(PyExc_ValueError,
8572 "the environment variable is longer than %u characters",
8573 _MAX_ENV);
8574 goto error;
8575 }
8576
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008578 if (newenv == NULL)
8579 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008582 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008584#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008585 PyObject *os1, *os2;
8586 char *s1, *s2;
8587 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008588
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008589 if (!PyArg_ParseTuple(args,
8590 "O&O&:putenv",
8591 PyUnicode_FSConverter, &os1,
8592 PyUnicode_FSConverter, &os2))
8593 return NULL;
8594 s1 = PyBytes_AsString(os1);
8595 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008596
Victor Stinner65170952011-11-22 22:16:17 +01008597 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008598 if (newstr == NULL) {
8599 PyErr_NoMemory();
8600 goto error;
8601 }
8602
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008606 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008608#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008609
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 /* Install the first arg and newstr in posix_putenv_garbage;
8611 * this will cause previous value to be collected. This has to
8612 * happen after the real putenv() call because the old value
8613 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008614 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 /* really not much we can do; just leak */
8616 PyErr_Clear();
8617 }
8618 else {
8619 Py_DECREF(newstr);
8620 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008621
Martin v. Löwis011e8422009-05-05 04:43:17 +00008622#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 Py_DECREF(os1);
8624 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008625#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008626 Py_RETURN_NONE;
8627
8628error:
8629#ifndef MS_WINDOWS
8630 Py_DECREF(os1);
8631 Py_DECREF(os2);
8632#endif
8633 Py_XDECREF(newstr);
8634 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008635}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008636#endif /* putenv */
8637
Guido van Rossumc524d952001-10-19 01:31:59 +00008638#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008639PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008640"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008641Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008642
8643static PyObject *
8644posix_unsetenv(PyObject *self, PyObject *args)
8645{
Victor Stinner65170952011-11-22 22:16:17 +01008646 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008647#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008648 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008649#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008650
8651 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008652
Victor Stinner65170952011-11-22 22:16:17 +01008653 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008654 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008655
Victor Stinner984890f2011-11-24 13:53:38 +01008656#ifdef HAVE_BROKEN_UNSETENV
8657 unsetenv(PyBytes_AS_STRING(name));
8658#else
Victor Stinner65170952011-11-22 22:16:17 +01008659 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008660 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008661 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008662 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008663 }
Victor Stinner984890f2011-11-24 13:53:38 +01008664#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008665
Victor Stinner8c62be82010-05-06 00:08:46 +00008666 /* Remove the key from posix_putenv_garbage;
8667 * this will cause it to be collected. This has to
8668 * happen after the real unsetenv() call because the
8669 * old value was still accessible until then.
8670 */
Victor Stinner65170952011-11-22 22:16:17 +01008671 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 /* really not much we can do; just leak */
8673 PyErr_Clear();
8674 }
Victor Stinner65170952011-11-22 22:16:17 +01008675 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008676 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008677}
8678#endif /* unsetenv */
8679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008680PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008681"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008682Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008683
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008685posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008686{
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 int code;
8688 char *message;
8689 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8690 return NULL;
8691 message = strerror(code);
8692 if (message == NULL) {
8693 PyErr_SetString(PyExc_ValueError,
8694 "strerror() argument out of range");
8695 return NULL;
8696 }
Victor Stinner1b579672011-12-17 05:47:23 +01008697 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008698}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008699
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008700
Guido van Rossumc9641791998-08-04 15:26:23 +00008701#ifdef HAVE_SYS_WAIT_H
8702
Fred Drake106c1a02002-04-23 15:58:02 +00008703#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008704PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008705"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008706Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008707
8708static PyObject *
8709posix_WCOREDUMP(PyObject *self, PyObject *args)
8710{
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 WAIT_TYPE status;
8712 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008713
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8715 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008716
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008718}
8719#endif /* WCOREDUMP */
8720
8721#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008722PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008723"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008724Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008725job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008726
8727static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008728posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008729{
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 WAIT_TYPE status;
8731 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008732
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8734 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008735
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008737}
8738#endif /* WIFCONTINUED */
8739
Guido van Rossumc9641791998-08-04 15:26:23 +00008740#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008741PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008742"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008743Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008744
8745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008746posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008747{
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 WAIT_TYPE status;
8749 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008750
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8752 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008753
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008755}
8756#endif /* WIFSTOPPED */
8757
8758#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008759PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008760"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008761Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008762
8763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008764posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008765{
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 WAIT_TYPE status;
8767 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008768
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8770 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008771
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008773}
8774#endif /* WIFSIGNALED */
8775
8776#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008777PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008778"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008779Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008780system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008781
8782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008783posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008784{
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 WAIT_TYPE status;
8786 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008787
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8789 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008790
Victor Stinner8c62be82010-05-06 00:08:46 +00008791 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008792}
8793#endif /* WIFEXITED */
8794
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008795#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008796PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008797"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008798Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008799
8800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008801posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008802{
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 WAIT_TYPE status;
8804 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008805
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8807 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008808
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008810}
8811#endif /* WEXITSTATUS */
8812
8813#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008814PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008815"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008816Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008817value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008818
8819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008820posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008821{
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 WAIT_TYPE status;
8823 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008824
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8826 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008827
Victor Stinner8c62be82010-05-06 00:08:46 +00008828 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008829}
8830#endif /* WTERMSIG */
8831
8832#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008833PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008834"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008835Return the signal that stopped the process that provided\n\
8836the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008837
8838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008839posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008840{
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 WAIT_TYPE status;
8842 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008843
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8845 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008846
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008848}
8849#endif /* WSTOPSIG */
8850
8851#endif /* HAVE_SYS_WAIT_H */
8852
8853
Thomas Wouters477c8d52006-05-27 19:21:47 +00008854#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008855#ifdef _SCO_DS
8856/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8857 needed definitions in sys/statvfs.h */
8858#define _SVID3
8859#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008860#include <sys/statvfs.h>
8861
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008862static PyObject*
8863_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8865 if (v == NULL)
8866 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008867
8868#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8870 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8871 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8872 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8873 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8874 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8875 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8876 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8877 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8878 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008879#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8881 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8882 PyStructSequence_SET_ITEM(v, 2,
8883 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8884 PyStructSequence_SET_ITEM(v, 3,
8885 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8886 PyStructSequence_SET_ITEM(v, 4,
8887 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8888 PyStructSequence_SET_ITEM(v, 5,
8889 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8890 PyStructSequence_SET_ITEM(v, 6,
8891 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8892 PyStructSequence_SET_ITEM(v, 7,
8893 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8894 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8895 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008896#endif
8897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008899}
8900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008901PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008902"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008903Perform an fstatvfs system call on the given fd.\n\
8904Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008905
8906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008907posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008908{
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 int fd, res;
8910 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008911
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8913 return NULL;
8914 Py_BEGIN_ALLOW_THREADS
8915 res = fstatvfs(fd, &st);
8916 Py_END_ALLOW_THREADS
8917 if (res != 0)
8918 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008919
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008921}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008922#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008923
8924
Thomas Wouters477c8d52006-05-27 19:21:47 +00008925#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008926#include <sys/statvfs.h>
8927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008928PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008929"statvfs(path)\n\n\
8930Perform a statvfs system call on the given path.\n\
8931\n\
8932path may always be specified as a string.\n\
8933On some platforms, path may also be specified as an open file descriptor.\n\
8934 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008935
8936static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008937posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008938{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008939 static char *keywords[] = {"path", NULL};
8940 path_t path;
8941 int result;
8942 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008944
Larry Hastings9cf065c2012-06-22 16:30:09 -07008945 memset(&path, 0, sizeof(path));
8946#ifdef HAVE_FSTATVFS
8947 path.allow_fd = 1;
8948#endif
8949 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8950 path_converter, &path
8951 ))
8952 return NULL;
8953
8954 Py_BEGIN_ALLOW_THREADS
8955#ifdef HAVE_FSTATVFS
8956 if (path.fd != -1) {
8957#ifdef __APPLE__
8958 /* handle weak-linking on Mac OS X 10.3 */
8959 if (fstatvfs == NULL) {
8960 fd_specified("statvfs", path.fd);
8961 goto exit;
8962 }
8963#endif
8964 result = fstatvfs(path.fd, &st);
8965 }
8966 else
8967#endif
8968 result = statvfs(path.narrow, &st);
8969 Py_END_ALLOW_THREADS
8970
8971 if (result) {
8972 return_value = path_posix_error("statvfs", &path);
8973 goto exit;
8974 }
8975
8976 return_value = _pystatvfs_fromstructstatvfs(st);
8977
8978exit:
8979 path_cleanup(&path);
8980 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008981}
8982#endif /* HAVE_STATVFS */
8983
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008984#ifdef MS_WINDOWS
8985PyDoc_STRVAR(win32__getdiskusage__doc__,
8986"_getdiskusage(path) -> (total, free)\n\n\
8987Return disk usage statistics about the given path as (total, free) tuple.");
8988
8989static PyObject *
8990win32__getdiskusage(PyObject *self, PyObject *args)
8991{
8992 BOOL retval;
8993 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008994 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008995
Victor Stinner6139c1b2011-11-09 22:14:14 +01008996 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008997 return NULL;
8998
8999 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009000 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009001 Py_END_ALLOW_THREADS
9002 if (retval == 0)
9003 return PyErr_SetFromWindowsErr(0);
9004
9005 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9006}
9007#endif
9008
9009
Fred Drakec9680921999-12-13 16:37:25 +00009010/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9011 * It maps strings representing configuration variable names to
9012 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009013 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009014 * rarely-used constants. There are three separate tables that use
9015 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009016 *
9017 * This code is always included, even if none of the interfaces that
9018 * need it are included. The #if hackery needed to avoid it would be
9019 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009020 */
9021struct constdef {
9022 char *name;
9023 long value;
9024};
9025
Fred Drake12c6e2d1999-12-14 21:25:03 +00009026static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009027conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009028 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009029{
Christian Heimes217cfd12007-12-02 14:31:20 +00009030 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009031 *valuep = PyLong_AS_LONG(arg);
9032 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009033 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009034 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009035 /* look up the value in the table using a binary search */
9036 size_t lo = 0;
9037 size_t mid;
9038 size_t hi = tablesize;
9039 int cmp;
9040 const char *confname;
9041 if (!PyUnicode_Check(arg)) {
9042 PyErr_SetString(PyExc_TypeError,
9043 "configuration names must be strings or integers");
9044 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009046 confname = _PyUnicode_AsString(arg);
9047 if (confname == NULL)
9048 return 0;
9049 while (lo < hi) {
9050 mid = (lo + hi) / 2;
9051 cmp = strcmp(confname, table[mid].name);
9052 if (cmp < 0)
9053 hi = mid;
9054 else if (cmp > 0)
9055 lo = mid + 1;
9056 else {
9057 *valuep = table[mid].value;
9058 return 1;
9059 }
9060 }
9061 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9062 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009064}
9065
9066
9067#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9068static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009069#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009071#endif
9072#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009074#endif
Fred Drakec9680921999-12-13 16:37:25 +00009075#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009077#endif
9078#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009080#endif
9081#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009083#endif
9084#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009086#endif
9087#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009089#endif
9090#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009092#endif
9093#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009095#endif
9096#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009097 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009098#endif
9099#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009100 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009101#endif
9102#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009104#endif
9105#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009107#endif
9108#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009110#endif
9111#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009113#endif
9114#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009116#endif
9117#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009119#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009120#ifdef _PC_ACL_ENABLED
9121 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9122#endif
9123#ifdef _PC_MIN_HOLE_SIZE
9124 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9125#endif
9126#ifdef _PC_ALLOC_SIZE_MIN
9127 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9128#endif
9129#ifdef _PC_REC_INCR_XFER_SIZE
9130 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9131#endif
9132#ifdef _PC_REC_MAX_XFER_SIZE
9133 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9134#endif
9135#ifdef _PC_REC_MIN_XFER_SIZE
9136 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9137#endif
9138#ifdef _PC_REC_XFER_ALIGN
9139 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9140#endif
9141#ifdef _PC_SYMLINK_MAX
9142 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9143#endif
9144#ifdef _PC_XATTR_ENABLED
9145 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9146#endif
9147#ifdef _PC_XATTR_EXISTS
9148 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9149#endif
9150#ifdef _PC_TIMESTAMP_RESOLUTION
9151 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9152#endif
Fred Drakec9680921999-12-13 16:37:25 +00009153};
9154
Fred Drakec9680921999-12-13 16:37:25 +00009155static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009156conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009157{
9158 return conv_confname(arg, valuep, posix_constants_pathconf,
9159 sizeof(posix_constants_pathconf)
9160 / sizeof(struct constdef));
9161}
9162#endif
9163
9164#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009165PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009166"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009167Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009168If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009169
9170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009171posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009172{
9173 PyObject *result = NULL;
9174 int name, fd;
9175
Fred Drake12c6e2d1999-12-14 21:25:03 +00009176 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9177 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009178 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009179
Stefan Krah0e803b32010-11-26 16:16:47 +00009180 errno = 0;
9181 limit = fpathconf(fd, name);
9182 if (limit == -1 && errno != 0)
9183 posix_error();
9184 else
9185 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009186 }
9187 return result;
9188}
9189#endif
9190
9191
9192#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009193PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009194"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009195Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009196If there is no limit, return -1.\n\
9197On some platforms, path may also be specified as an open file descriptor.\n\
9198 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009199
9200static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009201posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009202{
Georg Brandl306336b2012-06-24 12:55:33 +02009203 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009204 PyObject *result = NULL;
9205 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009206 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009207
Georg Brandl306336b2012-06-24 12:55:33 +02009208 memset(&path, 0, sizeof(path));
9209#ifdef HAVE_FPATHCONF
9210 path.allow_fd = 1;
9211#endif
9212 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9213 path_converter, &path,
9214 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009216
Victor Stinner8c62be82010-05-06 00:08:46 +00009217 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009218#ifdef HAVE_FPATHCONF
9219 if (path.fd != -1)
9220 limit = fpathconf(path.fd, name);
9221 else
9222#endif
9223 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 if (limit == -1 && errno != 0) {
9225 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009226 /* could be a path or name problem */
9227 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009228 else
Georg Brandl306336b2012-06-24 12:55:33 +02009229 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 }
9231 else
9232 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009233 }
Georg Brandl306336b2012-06-24 12:55:33 +02009234 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009235 return result;
9236}
9237#endif
9238
9239#ifdef HAVE_CONFSTR
9240static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009241#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009243#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009244#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009246#endif
9247#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009249#endif
Fred Draked86ed291999-12-15 15:34:33 +00009250#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009252#endif
9253#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009255#endif
9256#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009258#endif
9259#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009261#endif
Fred Drakec9680921999-12-13 16:37:25 +00009262#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
9268#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009270#endif
9271#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
9277#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009279#endif
9280#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009282#endif
9283#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009285#endif
Fred Draked86ed291999-12-15 15:34:33 +00009286#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009288#endif
Fred Drakec9680921999-12-13 16:37:25 +00009289#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
Fred Draked86ed291999-12-15 15:34:33 +00009292#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009294#endif
9295#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009297#endif
9298#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009300#endif
9301#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009303#endif
Fred Drakec9680921999-12-13 16:37:25 +00009304#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
Fred Draked86ed291999-12-15 15:34:33 +00009352#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009354#endif
9355#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009357#endif
9358#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009360#endif
9361#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009363#endif
9364#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009366#endif
9367#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009369#endif
9370#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009372#endif
9373#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009375#endif
9376#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009378#endif
9379#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009381#endif
9382#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009384#endif
9385#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009387#endif
9388#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009390#endif
Fred Drakec9680921999-12-13 16:37:25 +00009391};
9392
9393static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009394conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009395{
9396 return conv_confname(arg, valuep, posix_constants_confstr,
9397 sizeof(posix_constants_confstr)
9398 / sizeof(struct constdef));
9399}
9400
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009401PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009402"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009403Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009404
9405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009406posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009407{
9408 PyObject *result = NULL;
9409 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009410 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009411 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009412
Victor Stinnercb043522010-09-10 23:49:04 +00009413 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9414 return NULL;
9415
9416 errno = 0;
9417 len = confstr(name, buffer, sizeof(buffer));
9418 if (len == 0) {
9419 if (errno) {
9420 posix_error();
9421 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009422 }
9423 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009424 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009425 }
9426 }
Victor Stinnercb043522010-09-10 23:49:04 +00009427
9428 if ((unsigned int)len >= sizeof(buffer)) {
9429 char *buf = PyMem_Malloc(len);
9430 if (buf == NULL)
9431 return PyErr_NoMemory();
9432 confstr(name, buf, len);
9433 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9434 PyMem_Free(buf);
9435 }
9436 else
9437 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009438 return result;
9439}
9440#endif
9441
9442
9443#ifdef HAVE_SYSCONF
9444static struct constdef posix_constants_sysconf[] = {
9445#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009447#endif
9448#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009450#endif
9451#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009453#endif
9454#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009456#endif
9457#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
Fred Draked86ed291999-12-15 15:34:33 +00009475#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009477#endif
9478#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009480#endif
Fred Drakec9680921999-12-13 16:37:25 +00009481#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
Fred Drakec9680921999-12-13 16:37:25 +00009484#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
9487#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
Fred Draked86ed291999-12-15 15:34:33 +00009499#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009501#endif
Fred Drakec9680921999-12-13 16:37:25 +00009502#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
Fred Draked86ed291999-12-15 15:34:33 +00009517#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009519#endif
Fred Drakec9680921999-12-13 16:37:25 +00009520#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
9529#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009531#endif
9532#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
Fred Draked86ed291999-12-15 15:34:33 +00009589#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009591#endif
Fred Drakec9680921999-12-13 16:37:25 +00009592#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
Fred Draked86ed291999-12-15 15:34:33 +00009601#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009603#endif
Fred Drakec9680921999-12-13 16:37:25 +00009604#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
Fred Draked86ed291999-12-15 15:34:33 +00009607#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009609#endif
9610#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009612#endif
Fred Drakec9680921999-12-13 16:37:25 +00009613#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
Fred Draked86ed291999-12-15 15:34:33 +00009625#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009627#endif
Fred Drakec9680921999-12-13 16:37:25 +00009628#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
9637#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
9640#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
Fred Draked86ed291999-12-15 15:34:33 +00009649#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
Fred Drakec9680921999-12-13 16:37:25 +00009652#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
Fred Draked86ed291999-12-15 15:34:33 +00009658#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
Fred Drakec9680921999-12-13 16:37:25 +00009661#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
9664#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
9667#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
9670#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009672#endif
9673#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
9676#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
Fred Draked86ed291999-12-15 15:34:33 +00009688#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009690#endif
9691#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009693#endif
Fred Drakec9680921999-12-13 16:37:25 +00009694#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
9712#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
9718#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
Fred Draked86ed291999-12-15 15:34:33 +00009799#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009801#endif
Fred Drakec9680921999-12-13 16:37:25 +00009802#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
9841#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937};
9938
9939static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009940conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009941{
9942 return conv_confname(arg, valuep, posix_constants_sysconf,
9943 sizeof(posix_constants_sysconf)
9944 / sizeof(struct constdef));
9945}
9946
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009947PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009948"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009949Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009950
9951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009952posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009953{
9954 PyObject *result = NULL;
9955 int name;
9956
9957 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9958 int value;
9959
9960 errno = 0;
9961 value = sysconf(name);
9962 if (value == -1 && errno != 0)
9963 posix_error();
9964 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009965 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009966 }
9967 return result;
9968}
9969#endif
9970
9971
Fred Drakebec628d1999-12-15 18:31:10 +00009972/* This code is used to ensure that the tables of configuration value names
9973 * are in sorted order as required by conv_confname(), and also to build the
9974 * the exported dictionaries that are used to publish information about the
9975 * names available on the host platform.
9976 *
9977 * Sorting the table at runtime ensures that the table is properly ordered
9978 * when used, even for platforms we're not able to test on. It also makes
9979 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009980 */
Fred Drakebec628d1999-12-15 18:31:10 +00009981
9982static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009983cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009984{
9985 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009987 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009989
9990 return strcmp(c1->name, c2->name);
9991}
9992
9993static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009994setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009996{
Fred Drakebec628d1999-12-15 18:31:10 +00009997 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009998 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009999
10000 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10001 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010002 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010004
Barry Warsaw3155db32000-04-13 15:20:40 +000010005 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 PyObject *o = PyLong_FromLong(table[i].value);
10007 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10008 Py_XDECREF(o);
10009 Py_DECREF(d);
10010 return -1;
10011 }
10012 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010013 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010014 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010015}
10016
Fred Drakebec628d1999-12-15 18:31:10 +000010017/* Return -1 on failure, 0 on success. */
10018static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010019setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010020{
10021#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010022 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010023 sizeof(posix_constants_pathconf)
10024 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010025 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010026 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010027#endif
10028#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010029 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010030 sizeof(posix_constants_confstr)
10031 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010032 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010033 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010036 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010037 sizeof(posix_constants_sysconf)
10038 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010039 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010040 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010041#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010042 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010043}
Fred Draked86ed291999-12-15 15:34:33 +000010044
10045
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010046PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010047"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010048Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010049in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010050
10051static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010052posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010053{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010054 abort();
10055 /*NOTREACHED*/
10056 Py_FatalError("abort() called from Python code didn't abort!");
10057 return NULL;
10058}
Fred Drakebec628d1999-12-15 18:31:10 +000010059
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010060#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010061PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010062"startfile(filepath [, operation]) - Start a file with its associated\n\
10063application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010064\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010065When \"operation\" is not specified or \"open\", this acts like\n\
10066double-clicking the file in Explorer, or giving the file name as an\n\
10067argument to the DOS \"start\" command: the file is opened with whatever\n\
10068application (if any) its extension is associated.\n\
10069When another \"operation\" is given, it specifies what should be done with\n\
10070the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010071\n\
10072startfile returns as soon as the associated application is launched.\n\
10073There is no option to wait for the application to close, and no way\n\
10074to retrieve the application's exit status.\n\
10075\n\
10076The filepath is relative to the current directory. If you want to use\n\
10077an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010078the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010079
10080static PyObject *
10081win32_startfile(PyObject *self, PyObject *args)
10082{
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 PyObject *ofilepath;
10084 char *filepath;
10085 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010086 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010088
Victor Stinnereb5657a2011-09-30 01:44:27 +020010089 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 if (!PyArg_ParseTuple(args, "U|s:startfile",
10091 &unipath, &operation)) {
10092 PyErr_Clear();
10093 goto normal;
10094 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010095
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010097 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010099 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 PyErr_Clear();
10101 operation = NULL;
10102 goto normal;
10103 }
10104 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010105
Victor Stinnereb5657a2011-09-30 01:44:27 +020010106 wpath = PyUnicode_AsUnicode(unipath);
10107 if (wpath == NULL)
10108 goto normal;
10109 if (uoperation) {
10110 woperation = PyUnicode_AsUnicode(uoperation);
10111 if (woperation == NULL)
10112 goto normal;
10113 }
10114 else
10115 woperation = NULL;
10116
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010118 rc = ShellExecuteW((HWND)0, woperation, wpath,
10119 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 Py_END_ALLOW_THREADS
10121
Victor Stinnereb5657a2011-09-30 01:44:27 +020010122 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010124 win32_error_object("startfile", unipath);
10125 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 }
10127 Py_INCREF(Py_None);
10128 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010129
10130normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10132 PyUnicode_FSConverter, &ofilepath,
10133 &operation))
10134 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010135 if (win32_warn_bytes_api()) {
10136 Py_DECREF(ofilepath);
10137 return NULL;
10138 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 filepath = PyBytes_AsString(ofilepath);
10140 Py_BEGIN_ALLOW_THREADS
10141 rc = ShellExecute((HWND)0, operation, filepath,
10142 NULL, NULL, SW_SHOWNORMAL);
10143 Py_END_ALLOW_THREADS
10144 if (rc <= (HINSTANCE)32) {
10145 PyObject *errval = win32_error("startfile", filepath);
10146 Py_DECREF(ofilepath);
10147 return errval;
10148 }
10149 Py_DECREF(ofilepath);
10150 Py_INCREF(Py_None);
10151 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010152}
10153#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010154
Martin v. Löwis438b5342002-12-27 10:16:42 +000010155#ifdef HAVE_GETLOADAVG
10156PyDoc_STRVAR(posix_getloadavg__doc__,
10157"getloadavg() -> (float, float, float)\n\n\
10158Return the number of processes in the system run queue averaged over\n\
10159the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10160was unobtainable");
10161
10162static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010163posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010164{
10165 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010166 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010167 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10168 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010169 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010170 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010171}
10172#endif
10173
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010174PyDoc_STRVAR(device_encoding__doc__,
10175"device_encoding(fd) -> str\n\n\
10176Return a string describing the encoding of the device\n\
10177if the output is a terminal; else return None.");
10178
10179static PyObject *
10180device_encoding(PyObject *self, PyObject *args)
10181{
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010183
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10185 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010186
10187 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010188}
10189
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010190#ifdef HAVE_SETRESUID
10191PyDoc_STRVAR(posix_setresuid__doc__,
10192"setresuid(ruid, euid, suid)\n\n\
10193Set the current process's real, effective, and saved user ids.");
10194
10195static PyObject*
10196posix_setresuid (PyObject *self, PyObject *args)
10197{
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 /* We assume uid_t is no larger than a long. */
10199 long ruid, euid, suid;
10200 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10201 return NULL;
10202 if (setresuid(ruid, euid, suid) < 0)
10203 return posix_error();
10204 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010205}
10206#endif
10207
10208#ifdef HAVE_SETRESGID
10209PyDoc_STRVAR(posix_setresgid__doc__,
10210"setresgid(rgid, egid, sgid)\n\n\
10211Set the current process's real, effective, and saved group ids.");
10212
10213static PyObject*
10214posix_setresgid (PyObject *self, PyObject *args)
10215{
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 /* We assume uid_t is no larger than a long. */
10217 long rgid, egid, sgid;
10218 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10219 return NULL;
10220 if (setresgid(rgid, egid, sgid) < 0)
10221 return posix_error();
10222 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010223}
10224#endif
10225
10226#ifdef HAVE_GETRESUID
10227PyDoc_STRVAR(posix_getresuid__doc__,
10228"getresuid() -> (ruid, euid, suid)\n\n\
10229Get tuple of the current process's real, effective, and saved user ids.");
10230
10231static PyObject*
10232posix_getresuid (PyObject *self, PyObject *noargs)
10233{
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 uid_t ruid, euid, suid;
10235 long l_ruid, l_euid, l_suid;
10236 if (getresuid(&ruid, &euid, &suid) < 0)
10237 return posix_error();
10238 /* Force the values into long's as we don't know the size of uid_t. */
10239 l_ruid = ruid;
10240 l_euid = euid;
10241 l_suid = suid;
10242 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010243}
10244#endif
10245
10246#ifdef HAVE_GETRESGID
10247PyDoc_STRVAR(posix_getresgid__doc__,
10248"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010249Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010250
10251static PyObject*
10252posix_getresgid (PyObject *self, PyObject *noargs)
10253{
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 uid_t rgid, egid, sgid;
10255 long l_rgid, l_egid, l_sgid;
10256 if (getresgid(&rgid, &egid, &sgid) < 0)
10257 return posix_error();
10258 /* Force the values into long's as we don't know the size of uid_t. */
10259 l_rgid = rgid;
10260 l_egid = egid;
10261 l_sgid = sgid;
10262 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010263}
10264#endif
10265
Benjamin Peterson9428d532011-09-14 11:45:52 -040010266#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010267
Benjamin Peterson799bd802011-08-31 22:15:17 -040010268PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010269"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10270Return the value of extended attribute attribute on path.\n\
10271\n\
10272path may be either a string or an open file descriptor.\n\
10273If follow_symlinks is False, and the last element of the path is a symbolic\n\
10274 link, getxattr will examine the symbolic link itself instead of the file\n\
10275 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010276
10277static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010278posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010279{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010280 path_t path;
10281 path_t attribute;
10282 int follow_symlinks = 1;
10283 PyObject *buffer = NULL;
10284 int i;
10285 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010286
Larry Hastings9cf065c2012-06-22 16:30:09 -070010287 memset(&path, 0, sizeof(path));
10288 memset(&attribute, 0, sizeof(attribute));
10289 path.allow_fd = 1;
10290 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10291 path_converter, &path,
10292 path_converter, &attribute,
10293 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010294 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010295
Larry Hastings9cf065c2012-06-22 16:30:09 -070010296 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10297 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010298
Larry Hastings9cf065c2012-06-22 16:30:09 -070010299 for (i = 0; ; i++) {
10300 void *ptr;
10301 ssize_t result;
10302 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10303 Py_ssize_t buffer_size = buffer_sizes[i];
10304 if (!buffer_size) {
10305 path_error("getxattr", &path);
10306 goto exit;
10307 }
10308 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10309 if (!buffer)
10310 goto exit;
10311 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010312
Larry Hastings9cf065c2012-06-22 16:30:09 -070010313 Py_BEGIN_ALLOW_THREADS;
10314 if (path.fd >= 0)
10315 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10316 else if (follow_symlinks)
10317 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10318 else
10319 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10320 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010321
Larry Hastings9cf065c2012-06-22 16:30:09 -070010322 if (result < 0) {
10323 Py_DECREF(buffer);
10324 buffer = NULL;
10325 if (errno == ERANGE)
10326 continue;
10327 path_error("getxattr", &path);
10328 goto exit;
10329 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010330
Larry Hastings9cf065c2012-06-22 16:30:09 -070010331 if (result != buffer_size) {
10332 /* Can only shrink. */
10333 _PyBytes_Resize(&buffer, result);
10334 }
10335 break;
10336 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010337
Larry Hastings9cf065c2012-06-22 16:30:09 -070010338exit:
10339 path_cleanup(&path);
10340 path_cleanup(&attribute);
10341 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010342}
10343
10344PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010345"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10346Set extended attribute attribute on path to value.\n\
10347path may be either a string or an open file descriptor.\n\
10348If follow_symlinks is False, and the last element of the path is a symbolic\n\
10349 link, setxattr will modify the symbolic link itself instead of the file\n\
10350 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010351
10352static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010353posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010354{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010355 path_t path;
10356 path_t attribute;
10357 Py_buffer value;
10358 int flags = 0;
10359 int follow_symlinks = 1;
10360 int result;
10361 PyObject *return_value = NULL;
10362 static char *keywords[] = {"path", "attribute", "value",
10363 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010364
Larry Hastings9cf065c2012-06-22 16:30:09 -070010365 memset(&path, 0, sizeof(path));
10366 path.allow_fd = 1;
10367 memset(&attribute, 0, sizeof(attribute));
10368 memset(&value, 0, sizeof(value));
10369 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10370 keywords,
10371 path_converter, &path,
10372 path_converter, &attribute,
10373 &value, &flags,
10374 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010375 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010376
10377 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10378 goto exit;
10379
Benjamin Peterson799bd802011-08-31 22:15:17 -040010380 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010381 if (path.fd > -1)
10382 result = fsetxattr(path.fd, attribute.narrow,
10383 value.buf, value.len, flags);
10384 else if (follow_symlinks)
10385 result = setxattr(path.narrow, attribute.narrow,
10386 value.buf, value.len, flags);
10387 else
10388 result = lsetxattr(path.narrow, attribute.narrow,
10389 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010390 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010391
Larry Hastings9cf065c2012-06-22 16:30:09 -070010392 if (result) {
10393 return_value = path_error("setxattr", &path);
10394 goto exit;
10395 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010396
Larry Hastings9cf065c2012-06-22 16:30:09 -070010397 return_value = Py_None;
10398 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010399
Larry Hastings9cf065c2012-06-22 16:30:09 -070010400exit:
10401 path_cleanup(&path);
10402 path_cleanup(&attribute);
10403 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010404
Larry Hastings9cf065c2012-06-22 16:30:09 -070010405 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010406}
10407
10408PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010409"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10410Remove extended attribute attribute on path.\n\
10411path may be either a string or an open file descriptor.\n\
10412If follow_symlinks is False, and the last element of the path is a symbolic\n\
10413 link, removexattr will modify the symbolic link itself instead of the file\n\
10414 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010415
10416static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010417posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010418{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419 path_t path;
10420 path_t attribute;
10421 int follow_symlinks = 1;
10422 int result;
10423 PyObject *return_value = NULL;
10424 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010425
Larry Hastings9cf065c2012-06-22 16:30:09 -070010426 memset(&path, 0, sizeof(path));
10427 memset(&attribute, 0, sizeof(attribute));
10428 path.allow_fd = 1;
10429 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10430 keywords,
10431 path_converter, &path,
10432 path_converter, &attribute,
10433 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010434 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010435
10436 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10437 goto exit;
10438
Benjamin Peterson799bd802011-08-31 22:15:17 -040010439 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010440 if (path.fd > -1)
10441 result = fremovexattr(path.fd, attribute.narrow);
10442 else if (follow_symlinks)
10443 result = removexattr(path.narrow, attribute.narrow);
10444 else
10445 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010446 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010447
Larry Hastings9cf065c2012-06-22 16:30:09 -070010448 if (result) {
10449 return_value = path_error("removexattr", &path);
10450 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 return_value = Py_None;
10454 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010455
Larry Hastings9cf065c2012-06-22 16:30:09 -070010456exit:
10457 path_cleanup(&path);
10458 path_cleanup(&attribute);
10459
10460 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010461}
10462
10463PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010464"listxattr(path='.', *, follow_symlinks=True)\n\n\
10465Return a list of extended attributes on path.\n\
10466\n\
10467path may be either None, a string, or an open file descriptor.\n\
10468if path is None, listxattr will examine the current directory.\n\
10469If follow_symlinks is False, and the last element of the path is a symbolic\n\
10470 link, listxattr will examine the symbolic link itself instead of the file\n\
10471 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010472
10473static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010474posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010475{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010476 path_t path;
10477 int follow_symlinks = 1;
10478 Py_ssize_t i;
10479 PyObject *result = NULL;
10480 char *buffer = NULL;
10481 char *name;
10482 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010483
Larry Hastings9cf065c2012-06-22 16:30:09 -070010484 memset(&path, 0, sizeof(path));
10485 path.allow_fd = 1;
10486 path.fd = -1;
10487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10488 path_converter, &path,
10489 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010490 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010491
Larry Hastings9cf065c2012-06-22 16:30:09 -070010492 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10493 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494
Larry Hastings9cf065c2012-06-22 16:30:09 -070010495 name = path.narrow ? path.narrow : ".";
10496 for (i = 0; ; i++) {
10497 char *start, *trace, *end;
10498 ssize_t length;
10499 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10500 Py_ssize_t buffer_size = buffer_sizes[i];
10501 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010502 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010503 path_error("listxattr", &path);
10504 break;
10505 }
10506 buffer = PyMem_MALLOC(buffer_size);
10507 if (!buffer) {
10508 PyErr_NoMemory();
10509 break;
10510 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010511
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512 Py_BEGIN_ALLOW_THREADS;
10513 if (path.fd > -1)
10514 length = flistxattr(path.fd, buffer, buffer_size);
10515 else if (follow_symlinks)
10516 length = listxattr(name, buffer, buffer_size);
10517 else
10518 length = llistxattr(name, buffer, buffer_size);
10519 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010520
Larry Hastings9cf065c2012-06-22 16:30:09 -070010521 if (length < 0) {
10522 if (errno == ERANGE)
10523 continue;
10524 path_error("listxattr", &path);
10525 break;
10526 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010527
Larry Hastings9cf065c2012-06-22 16:30:09 -070010528 result = PyList_New(0);
10529 if (!result) {
10530 goto exit;
10531 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010532
Larry Hastings9cf065c2012-06-22 16:30:09 -070010533 end = buffer + length;
10534 for (trace = start = buffer; trace != end; trace++) {
10535 if (!*trace) {
10536 int error;
10537 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10538 trace - start);
10539 if (!attribute) {
10540 Py_DECREF(result);
10541 result = NULL;
10542 goto exit;
10543 }
10544 error = PyList_Append(result, attribute);
10545 Py_DECREF(attribute);
10546 if (error) {
10547 Py_DECREF(result);
10548 result = NULL;
10549 goto exit;
10550 }
10551 start = trace + 1;
10552 }
10553 }
10554 break;
10555 }
10556exit:
10557 path_cleanup(&path);
10558 if (buffer)
10559 PyMem_FREE(buffer);
10560 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561}
10562
Benjamin Peterson9428d532011-09-14 11:45:52 -040010563#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010565
Georg Brandl2fb477c2012-02-21 00:33:36 +010010566PyDoc_STRVAR(posix_urandom__doc__,
10567"urandom(n) -> str\n\n\
10568Return n random bytes suitable for cryptographic use.");
10569
10570static PyObject *
10571posix_urandom(PyObject *self, PyObject *args)
10572{
10573 Py_ssize_t size;
10574 PyObject *result;
10575 int ret;
10576
10577 /* Read arguments */
10578 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10579 return NULL;
10580 if (size < 0)
10581 return PyErr_Format(PyExc_ValueError,
10582 "negative argument not allowed");
10583 result = PyBytes_FromStringAndSize(NULL, size);
10584 if (result == NULL)
10585 return NULL;
10586
10587 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10588 PyBytes_GET_SIZE(result));
10589 if (ret == -1) {
10590 Py_DECREF(result);
10591 return NULL;
10592 }
10593 return result;
10594}
10595
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010596/* Terminal size querying */
10597
10598static PyTypeObject TerminalSizeType;
10599
10600PyDoc_STRVAR(TerminalSize_docstring,
10601 "A tuple of (columns, lines) for holding terminal window size");
10602
10603static PyStructSequence_Field TerminalSize_fields[] = {
10604 {"columns", "width of the terminal window in characters"},
10605 {"lines", "height of the terminal window in characters"},
10606 {NULL, NULL}
10607};
10608
10609static PyStructSequence_Desc TerminalSize_desc = {
10610 "os.terminal_size",
10611 TerminalSize_docstring,
10612 TerminalSize_fields,
10613 2,
10614};
10615
10616#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10617PyDoc_STRVAR(termsize__doc__,
10618 "Return the size of the terminal window as (columns, lines).\n" \
10619 "\n" \
10620 "The optional argument fd (default standard output) specifies\n" \
10621 "which file descriptor should be queried.\n" \
10622 "\n" \
10623 "If the file descriptor is not connected to a terminal, an OSError\n" \
10624 "is thrown.\n" \
10625 "\n" \
10626 "This function will only be defined if an implementation is\n" \
10627 "available for this system.\n" \
10628 "\n" \
10629 "shutil.get_terminal_size is the high-level function which should \n" \
10630 "normally be used, os.get_terminal_size is the low-level implementation.");
10631
10632static PyObject*
10633get_terminal_size(PyObject *self, PyObject *args)
10634{
10635 int columns, lines;
10636 PyObject *termsize;
10637
10638 int fd = fileno(stdout);
10639 /* Under some conditions stdout may not be connected and
10640 * fileno(stdout) may point to an invalid file descriptor. For example
10641 * GUI apps don't have valid standard streams by default.
10642 *
10643 * If this happens, and the optional fd argument is not present,
10644 * the ioctl below will fail returning EBADF. This is what we want.
10645 */
10646
10647 if (!PyArg_ParseTuple(args, "|i", &fd))
10648 return NULL;
10649
10650#ifdef TERMSIZE_USE_IOCTL
10651 {
10652 struct winsize w;
10653 if (ioctl(fd, TIOCGWINSZ, &w))
10654 return PyErr_SetFromErrno(PyExc_OSError);
10655 columns = w.ws_col;
10656 lines = w.ws_row;
10657 }
10658#endif /* TERMSIZE_USE_IOCTL */
10659
10660#ifdef TERMSIZE_USE_CONIO
10661 {
10662 DWORD nhandle;
10663 HANDLE handle;
10664 CONSOLE_SCREEN_BUFFER_INFO csbi;
10665 switch (fd) {
10666 case 0: nhandle = STD_INPUT_HANDLE;
10667 break;
10668 case 1: nhandle = STD_OUTPUT_HANDLE;
10669 break;
10670 case 2: nhandle = STD_ERROR_HANDLE;
10671 break;
10672 default:
10673 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10674 }
10675 handle = GetStdHandle(nhandle);
10676 if (handle == NULL)
10677 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10678 if (handle == INVALID_HANDLE_VALUE)
10679 return PyErr_SetFromWindowsErr(0);
10680
10681 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10682 return PyErr_SetFromWindowsErr(0);
10683
10684 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10685 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10686 }
10687#endif /* TERMSIZE_USE_CONIO */
10688
10689 termsize = PyStructSequence_New(&TerminalSizeType);
10690 if (termsize == NULL)
10691 return NULL;
10692 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10693 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10694 if (PyErr_Occurred()) {
10695 Py_DECREF(termsize);
10696 return NULL;
10697 }
10698 return termsize;
10699}
10700#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10701
10702
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010703static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010704 {"access", (PyCFunction)posix_access,
10705 METH_VARARGS | METH_KEYWORDS,
10706 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010707#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010709#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010710 {"chdir", (PyCFunction)posix_chdir,
10711 METH_VARARGS | METH_KEYWORDS,
10712 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010713#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010714 {"chflags", (PyCFunction)posix_chflags,
10715 METH_VARARGS | METH_KEYWORDS,
10716 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010717#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718 {"chmod", (PyCFunction)posix_chmod,
10719 METH_VARARGS | METH_KEYWORDS,
10720 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010721#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010723#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010724#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010725 {"chown", (PyCFunction)posix_chown,
10726 METH_VARARGS | METH_KEYWORDS,
10727 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010728#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010729#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010731#endif /* HAVE_LCHMOD */
10732#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010734#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010735#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010737#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010738#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010740#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010741#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010743#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010744#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010746#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010747#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10749 METH_NOARGS, posix_getcwd__doc__},
10750 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10751 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010752#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10754 {"link", (PyCFunction)posix_link,
10755 METH_VARARGS | METH_KEYWORDS,
10756 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010757#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 {"listdir", (PyCFunction)posix_listdir,
10759 METH_VARARGS | METH_KEYWORDS,
10760 posix_listdir__doc__},
10761 {"lstat", (PyCFunction)posix_lstat,
10762 METH_VARARGS | METH_KEYWORDS,
10763 posix_lstat__doc__},
10764 {"mkdir", (PyCFunction)posix_mkdir,
10765 METH_VARARGS | METH_KEYWORDS,
10766 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010767#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010769#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010770#ifdef HAVE_GETPRIORITY
10771 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10772#endif /* HAVE_GETPRIORITY */
10773#ifdef HAVE_SETPRIORITY
10774 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10775#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010776#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 {"readlink", (PyCFunction)posix_readlink,
10778 METH_VARARGS | METH_KEYWORDS,
10779 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010780#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010781#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 {"readlink", (PyCFunction)win_readlink,
10783 METH_VARARGS | METH_KEYWORDS,
10784 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010785#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010786 {"rename", (PyCFunction)posix_rename,
10787 METH_VARARGS | METH_KEYWORDS,
10788 posix_rename__doc__},
10789 {"replace", (PyCFunction)posix_replace,
10790 METH_VARARGS | METH_KEYWORDS,
10791 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010792 {"rmdir", (PyCFunction)posix_rmdir,
10793 METH_VARARGS | METH_KEYWORDS,
10794 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010795 {"stat", (PyCFunction)posix_stat,
10796 METH_VARARGS | METH_KEYWORDS,
10797 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010799#if defined(HAVE_SYMLINK)
10800 {"symlink", (PyCFunction)posix_symlink,
10801 METH_VARARGS | METH_KEYWORDS,
10802 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010803#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010804#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010806#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010808#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010810#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 {"unlink", (PyCFunction)posix_unlink,
10812 METH_VARARGS | METH_KEYWORDS,
10813 posix_unlink__doc__},
10814 {"remove", (PyCFunction)posix_unlink,
10815 METH_VARARGS | METH_KEYWORDS,
10816 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010817 {"utime", (PyCFunction)posix_utime,
10818 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010819#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010821#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010823#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 {"execve", (PyCFunction)posix_execve,
10826 METH_VARARGS | METH_KEYWORDS,
10827 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010828#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010829#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10831 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010832#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10834 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010835#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010836#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010837#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010839#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010840#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010842#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010843#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010844#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010845 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10846 {"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 +020010847#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010848#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010849 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010850#endif
10851#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010852 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010853#endif
10854#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010855 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010856#endif
10857#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010858 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010859#endif
10860#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010861 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010862#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010863 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010864#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010865 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10866 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10867#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010868#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010869#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010871#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010872#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010874#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010875#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010877#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010878#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010880#endif /* HAVE_GETEUID */
10881#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010883#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010884#ifdef HAVE_GETGROUPLIST
10885 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10886#endif
Fred Drakec9680921999-12-13 16:37:25 +000010887#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010891#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010893#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010894#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010896#endif /* HAVE_GETPPID */
10897#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010899#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010900#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010902#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010903#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010905#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010906#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010908#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010909#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010911#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10914 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010915#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010916#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010918#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010919#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010921#endif /* HAVE_SETEUID */
10922#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010924#endif /* HAVE_SETEGID */
10925#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010927#endif /* HAVE_SETREUID */
10928#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010930#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010931#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010933#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010934#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010936#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010937#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010939#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010940#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010942#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010943#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010945#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010946#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010948#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010949#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010950 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010951#endif /* HAVE_WAIT3 */
10952#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010953 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010954#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010955#if defined(HAVE_WAITID) && !defined(__APPLE__)
10956 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10957#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010958#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010960#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010961#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010963#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010964#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010966#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010967#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010969#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010970#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010972#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010973#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010975#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010976 {"open", (PyCFunction)posix_open,\
10977 METH_VARARGS | METH_KEYWORDS,
10978 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10980 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10981 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10982 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10983 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010984#ifdef HAVE_LOCKF
10985 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10986#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10988 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010989#ifdef HAVE_READV
10990 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10991#endif
10992#ifdef HAVE_PREAD
10993 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10994#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010996#ifdef HAVE_WRITEV
10997 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10998#endif
10999#ifdef HAVE_PWRITE
11000 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11001#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011002#ifdef HAVE_SENDFILE
11003 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11004 posix_sendfile__doc__},
11005#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011006 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011008#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011010#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011011#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011012 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011013#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011014#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 {"mkfifo", (PyCFunction)posix_mkfifo,
11016 METH_VARARGS | METH_KEYWORDS,
11017 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011018#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011019#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 {"mknod", (PyCFunction)posix_mknod,
11021 METH_VARARGS | METH_KEYWORDS,
11022 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011023#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011024#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11026 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11027 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011028#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011029#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011031#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011032#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011033 {"truncate", (PyCFunction)posix_truncate,
11034 METH_VARARGS | METH_KEYWORDS,
11035 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011036#endif
11037#ifdef HAVE_POSIX_FALLOCATE
11038 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11039#endif
11040#ifdef HAVE_POSIX_FADVISE
11041 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11042#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011043#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011045#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011046#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011048#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011050#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011052#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011053#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011055#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011056#ifdef HAVE_SYNC
11057 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11058#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011059#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011061#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011062#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011063#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011065#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011066#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011068#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011069#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011071#endif /* WIFSTOPPED */
11072#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011074#endif /* WIFSIGNALED */
11075#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011077#endif /* WIFEXITED */
11078#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011080#endif /* WEXITSTATUS */
11081#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011083#endif /* WTERMSIG */
11084#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011086#endif /* WSTOPSIG */
11087#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011088#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011090#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011091#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011092 {"statvfs", (PyCFunction)posix_statvfs,
11093 METH_VARARGS | METH_KEYWORDS,
11094 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011095#endif
Fred Drakec9680921999-12-13 16:37:25 +000011096#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011098#endif
11099#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
11102#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011106 {"pathconf", (PyCFunction)posix_pathconf,
11107 METH_VARARGS | METH_KEYWORDS,
11108 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011109#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011111#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011113 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011114 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011115 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011116 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011117#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011118#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011120#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011121 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011122#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011124#endif
11125#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011127#endif
11128#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011130#endif
11131#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011133#endif
11134
Benjamin Peterson9428d532011-09-14 11:45:52 -040011135#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011136 {"setxattr", (PyCFunction)posix_setxattr,
11137 METH_VARARGS | METH_KEYWORDS,
11138 posix_setxattr__doc__},
11139 {"getxattr", (PyCFunction)posix_getxattr,
11140 METH_VARARGS | METH_KEYWORDS,
11141 posix_getxattr__doc__},
11142 {"removexattr", (PyCFunction)posix_removexattr,
11143 METH_VARARGS | METH_KEYWORDS,
11144 posix_removexattr__doc__},
11145 {"listxattr", (PyCFunction)posix_listxattr,
11146 METH_VARARGS | METH_KEYWORDS,
11147 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011148#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011149#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11150 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11151#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011153};
11154
11155
Barry Warsaw4a342091996-12-19 23:50:02 +000011156static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011157ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011158{
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011160}
11161
Guido van Rossumd48f2521997-12-05 22:19:34 +000011162#if defined(PYOS_OS2)
11163/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011164static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011165{
11166 APIRET rc;
11167 ULONG values[QSV_MAX+1];
11168 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011169 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011170
11171 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011172 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011173 Py_END_ALLOW_THREADS
11174
11175 if (rc != NO_ERROR) {
11176 os2_error(rc);
11177 return -1;
11178 }
11179
Fred Drake4d1e64b2002-04-15 19:40:07 +000011180 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11181 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11182 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11183 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11184 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11185 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11186 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011187
11188 switch (values[QSV_VERSION_MINOR]) {
11189 case 0: ver = "2.00"; break;
11190 case 10: ver = "2.10"; break;
11191 case 11: ver = "2.11"; break;
11192 case 30: ver = "3.00"; break;
11193 case 40: ver = "4.00"; break;
11194 case 50: ver = "5.00"; break;
11195 default:
Tim Peters885d4572001-11-28 20:27:42 +000011196 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011198 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011199 ver = &tmp[0];
11200 }
11201
11202 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011203 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011204 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011205
11206 /* Add Indicator of Which Drive was Used to Boot the System */
11207 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11208 tmp[1] = ':';
11209 tmp[2] = '\0';
11210
Fred Drake4d1e64b2002-04-15 19:40:07 +000011211 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011212}
11213#endif
11214
Brian Curtin52173d42010-12-02 18:29:18 +000011215#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011216static int
Brian Curtin52173d42010-12-02 18:29:18 +000011217enable_symlink()
11218{
11219 HANDLE tok;
11220 TOKEN_PRIVILEGES tok_priv;
11221 LUID luid;
11222 int meth_idx = 0;
11223
11224 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011225 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011226
11227 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011228 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011229
11230 tok_priv.PrivilegeCount = 1;
11231 tok_priv.Privileges[0].Luid = luid;
11232 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11233
11234 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11235 sizeof(TOKEN_PRIVILEGES),
11236 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011237 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011238
Brian Curtin3b4499c2010-12-28 14:31:47 +000011239 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11240 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011241}
11242#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11243
Barry Warsaw4a342091996-12-19 23:50:02 +000011244static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011245all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011246{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011247#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011249#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011250#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011252#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011253#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011255#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011256#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011258#endif
Fred Drakec9680921999-12-13 16:37:25 +000011259#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011261#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011262#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011264#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011265#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011267#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011268#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011270#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011271#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011272 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011273#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011274#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011276#endif
11277#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011279#endif
11280#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011282#endif
11283#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011285#endif
11286#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011288#endif
11289#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011291#endif
11292#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011294#endif
11295#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011297#endif
11298#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011300#endif
11301#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011303#endif
11304#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011306#endif
11307#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011309#endif
11310#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011312#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011313#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011315#endif
11316#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011318#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011319#ifdef O_XATTR
11320 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11321#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011322#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011324#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011325#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011327#endif
11328#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011330#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011331#ifdef O_EXEC
11332 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11333#endif
11334#ifdef O_SEARCH
11335 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11336#endif
11337#ifdef O_TTY_INIT
11338 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11339#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011340#ifdef PRIO_PROCESS
11341 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11342#endif
11343#ifdef PRIO_PGRP
11344 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11345#endif
11346#ifdef PRIO_USER
11347 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11348#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011349#ifdef O_CLOEXEC
11350 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11351#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011352#ifdef O_ACCMODE
11353 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11354#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011355
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011356
Jesus Cea94363612012-06-22 18:32:07 +020011357#ifdef SEEK_HOLE
11358 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11359#endif
11360#ifdef SEEK_DATA
11361 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11362#endif
11363
Tim Peters5aa91602002-01-30 05:46:57 +000011364/* MS Windows */
11365#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 /* Don't inherit in child processes. */
11367 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011368#endif
11369#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 /* Optimize for short life (keep in memory). */
11371 /* MS forgot to define this one with a non-underscore form too. */
11372 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011373#endif
11374#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 /* Automatically delete when last handle is closed. */
11376 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011377#endif
11378#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 /* Optimize for random access. */
11380 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011381#endif
11382#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 /* Optimize for sequential access. */
11384 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011385#endif
11386
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011387/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011388#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 /* Send a SIGIO signal whenever input or output
11390 becomes available on file descriptor */
11391 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011392#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011393#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 /* Direct disk access. */
11395 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011396#endif
11397#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 /* Must be a directory. */
11399 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011400#endif
11401#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 /* Do not follow links. */
11403 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011404#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011405#ifdef O_NOLINKS
11406 /* Fails if link count of the named file is greater than 1 */
11407 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11408#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011409#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 /* Do not update the access time. */
11411 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011412#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011413
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011415#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011417#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011418#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011420#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011421#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011423#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011424#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011426#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011427#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011428 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011429#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011430#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011431 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011432#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011433#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011435#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011436#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011438#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011439#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011441#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011442#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011444#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011445#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011447#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011448#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011450#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011451#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011452 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011453#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011454#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011455 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011456#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011457#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011459#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011460#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011462#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011463#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011465#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011466
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011467 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011468#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011469 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011470#endif /* ST_RDONLY */
11471#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011472 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011473#endif /* ST_NOSUID */
11474
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011475 /* FreeBSD sendfile() constants */
11476#ifdef SF_NODISKIO
11477 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11478#endif
11479#ifdef SF_MNOWAIT
11480 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11481#endif
11482#ifdef SF_SYNC
11483 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11484#endif
11485
Ross Lagerwall7807c352011-03-17 20:20:30 +020011486 /* constants for posix_fadvise */
11487#ifdef POSIX_FADV_NORMAL
11488 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11489#endif
11490#ifdef POSIX_FADV_SEQUENTIAL
11491 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11492#endif
11493#ifdef POSIX_FADV_RANDOM
11494 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11495#endif
11496#ifdef POSIX_FADV_NOREUSE
11497 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11498#endif
11499#ifdef POSIX_FADV_WILLNEED
11500 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11501#endif
11502#ifdef POSIX_FADV_DONTNEED
11503 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11504#endif
11505
11506 /* constants for waitid */
11507#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11508 if (ins(d, "P_PID", (long)P_PID)) return -1;
11509 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11510 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11511#endif
11512#ifdef WEXITED
11513 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11514#endif
11515#ifdef WNOWAIT
11516 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11517#endif
11518#ifdef WSTOPPED
11519 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11520#endif
11521#ifdef CLD_EXITED
11522 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11523#endif
11524#ifdef CLD_DUMPED
11525 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11526#endif
11527#ifdef CLD_TRAPPED
11528 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11529#endif
11530#ifdef CLD_CONTINUED
11531 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11532#endif
11533
11534 /* constants for lockf */
11535#ifdef F_LOCK
11536 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11537#endif
11538#ifdef F_TLOCK
11539 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11540#endif
11541#ifdef F_ULOCK
11542 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11543#endif
11544#ifdef F_TEST
11545 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11546#endif
11547
Guido van Rossum246bc171999-02-01 23:54:31 +000011548#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011549#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11551 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11552 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11553 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11554 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11555 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11556 if (ins(d, "P_PM", (long)P_PM)) return -1;
11557 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11558 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11559 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11560 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11561 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11562 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11563 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11564 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11565 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11566 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11567 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11568 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11569 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011570#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11572 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11573 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11574 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11575 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011576#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011577#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011578
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011579#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011580 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011581 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11582 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11583#ifdef SCHED_SPORADIC
11584 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11585#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011586#ifdef SCHED_BATCH
11587 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11588#endif
11589#ifdef SCHED_IDLE
11590 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11591#endif
11592#ifdef SCHED_RESET_ON_FORK
11593 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11594#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011595#ifdef SCHED_SYS
11596 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11597#endif
11598#ifdef SCHED_IA
11599 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11600#endif
11601#ifdef SCHED_FSS
11602 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11603#endif
11604#ifdef SCHED_FX
11605 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11606#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011607#endif
11608
Benjamin Peterson9428d532011-09-14 11:45:52 -040011609#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011610 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11611 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11612 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11613#endif
11614
Victor Stinner8b905bd2011-10-25 13:34:04 +020011615#ifdef RTLD_LAZY
11616 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11617#endif
11618#ifdef RTLD_NOW
11619 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11620#endif
11621#ifdef RTLD_GLOBAL
11622 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11623#endif
11624#ifdef RTLD_LOCAL
11625 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11626#endif
11627#ifdef RTLD_NODELETE
11628 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11629#endif
11630#ifdef RTLD_NOLOAD
11631 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11632#endif
11633#ifdef RTLD_DEEPBIND
11634 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11635#endif
11636
Guido van Rossumd48f2521997-12-05 22:19:34 +000011637#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011638 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011639#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011641}
11642
11643
Tim Peters5aa91602002-01-30 05:46:57 +000011644#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011645#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011646#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011647
11648#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011649#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011650#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011651
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011652#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011653#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011654#define MODNAME "posix"
11655#endif
11656
Martin v. Löwis1a214512008-06-11 05:26:20 +000011657static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 PyModuleDef_HEAD_INIT,
11659 MODNAME,
11660 posix__doc__,
11661 -1,
11662 posix_methods,
11663 NULL,
11664 NULL,
11665 NULL,
11666 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011667};
11668
11669
Larry Hastings9cf065c2012-06-22 16:30:09 -070011670static char *have_functions[] = {
11671
11672#ifdef HAVE_FACCESSAT
11673 "HAVE_FACCESSAT",
11674#endif
11675
11676#ifdef HAVE_FCHDIR
11677 "HAVE_FCHDIR",
11678#endif
11679
11680#ifdef HAVE_FCHMOD
11681 "HAVE_FCHMOD",
11682#endif
11683
11684#ifdef HAVE_FCHMODAT
11685 "HAVE_FCHMODAT",
11686#endif
11687
11688#ifdef HAVE_FCHOWN
11689 "HAVE_FCHOWN",
11690#endif
11691
11692#ifdef HAVE_FEXECVE
11693 "HAVE_FEXECVE",
11694#endif
11695
11696#ifdef HAVE_FDOPENDIR
11697 "HAVE_FDOPENDIR",
11698#endif
11699
Georg Brandl306336b2012-06-24 12:55:33 +020011700#ifdef HAVE_FPATHCONF
11701 "HAVE_FPATHCONF",
11702#endif
11703
Larry Hastings9cf065c2012-06-22 16:30:09 -070011704#ifdef HAVE_FSTATAT
11705 "HAVE_FSTATAT",
11706#endif
11707
11708#ifdef HAVE_FSTATVFS
11709 "HAVE_FSTATVFS",
11710#endif
11711
Georg Brandl306336b2012-06-24 12:55:33 +020011712#ifdef HAVE_FTRUNCATE
11713 "HAVE_FTRUNCATE",
11714#endif
11715
Larry Hastings9cf065c2012-06-22 16:30:09 -070011716#ifdef HAVE_FUTIMENS
11717 "HAVE_FUTIMENS",
11718#endif
11719
11720#ifdef HAVE_FUTIMES
11721 "HAVE_FUTIMES",
11722#endif
11723
11724#ifdef HAVE_FUTIMESAT
11725 "HAVE_FUTIMESAT",
11726#endif
11727
11728#ifdef HAVE_LINKAT
11729 "HAVE_LINKAT",
11730#endif
11731
11732#ifdef HAVE_LCHFLAGS
11733 "HAVE_LCHFLAGS",
11734#endif
11735
11736#ifdef HAVE_LCHMOD
11737 "HAVE_LCHMOD",
11738#endif
11739
11740#ifdef HAVE_LCHOWN
11741 "HAVE_LCHOWN",
11742#endif
11743
11744#ifdef HAVE_LSTAT
11745 "HAVE_LSTAT",
11746#endif
11747
11748#ifdef HAVE_LUTIMES
11749 "HAVE_LUTIMES",
11750#endif
11751
11752#ifdef HAVE_MKDIRAT
11753 "HAVE_MKDIRAT",
11754#endif
11755
11756#ifdef HAVE_MKFIFOAT
11757 "HAVE_MKFIFOAT",
11758#endif
11759
11760#ifdef HAVE_MKNODAT
11761 "HAVE_MKNODAT",
11762#endif
11763
11764#ifdef HAVE_OPENAT
11765 "HAVE_OPENAT",
11766#endif
11767
11768#ifdef HAVE_READLINKAT
11769 "HAVE_READLINKAT",
11770#endif
11771
11772#ifdef HAVE_RENAMEAT
11773 "HAVE_RENAMEAT",
11774#endif
11775
11776#ifdef HAVE_SYMLINKAT
11777 "HAVE_SYMLINKAT",
11778#endif
11779
11780#ifdef HAVE_UNLINKAT
11781 "HAVE_UNLINKAT",
11782#endif
11783
11784#ifdef HAVE_UTIMENSAT
11785 "HAVE_UTIMENSAT",
11786#endif
11787
11788#ifdef MS_WINDOWS
11789 "MS_WINDOWS",
11790#endif
11791
11792 NULL
11793};
11794
11795
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011796PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011797INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011798{
Victor Stinner8c62be82010-05-06 00:08:46 +000011799 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011800 PyObject *list;
11801 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011802
Brian Curtin52173d42010-12-02 18:29:18 +000011803#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011804 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011805#endif
11806
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 m = PyModule_Create(&posixmodule);
11808 if (m == NULL)
11809 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011810
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 /* Initialize environ dictionary */
11812 v = convertenviron();
11813 Py_XINCREF(v);
11814 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11815 return NULL;
11816 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011817
Victor Stinner8c62be82010-05-06 00:08:46 +000011818 if (all_ins(m))
11819 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011820
Victor Stinner8c62be82010-05-06 00:08:46 +000011821 if (setup_confname_tables(m))
11822 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011823
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 Py_INCREF(PyExc_OSError);
11825 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011826
Guido van Rossumb3d39562000-01-31 18:41:26 +000011827#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 if (posix_putenv_garbage == NULL)
11829 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011830#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011831
Victor Stinner8c62be82010-05-06 00:08:46 +000011832 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011833#if defined(HAVE_WAITID) && !defined(__APPLE__)
11834 waitid_result_desc.name = MODNAME ".waitid_result";
11835 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11836#endif
11837
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 stat_result_desc.name = MODNAME ".stat_result";
11839 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11840 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11841 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11842 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11843 structseq_new = StatResultType.tp_new;
11844 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011845
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 statvfs_result_desc.name = MODNAME ".statvfs_result";
11847 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011848#ifdef NEED_TICKS_PER_SECOND
11849# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011851# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011852 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011853# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011854 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011855# endif
11856#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011857
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011858#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011859 sched_param_desc.name = MODNAME ".sched_param";
11860 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11861 SchedParamType.tp_new = sched_param_new;
11862#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011863
11864 /* initialize TerminalSize_info */
11865 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011866 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011867#if defined(HAVE_WAITID) && !defined(__APPLE__)
11868 Py_INCREF((PyObject*) &WaitidResultType);
11869 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11870#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 Py_INCREF((PyObject*) &StatResultType);
11872 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11873 Py_INCREF((PyObject*) &StatVFSResultType);
11874 PyModule_AddObject(m, "statvfs_result",
11875 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011876
11877#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011878 Py_INCREF(&SchedParamType);
11879 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011880#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011881
Larry Hastings605a62d2012-06-24 04:33:36 -070011882 times_result_desc.name = MODNAME ".times_result";
11883 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11884 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11885
11886 uname_result_desc.name = MODNAME ".uname_result";
11887 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11888 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11889
Thomas Wouters477c8d52006-05-27 19:21:47 +000011890#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011891 /*
11892 * Step 2 of weak-linking support on Mac OS X.
11893 *
11894 * The code below removes functions that are not available on the
11895 * currently active platform.
11896 *
11897 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011898 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 * OSX 10.4.
11900 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011901#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 if (fstatvfs == NULL) {
11903 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11904 return NULL;
11905 }
11906 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011907#endif /* HAVE_FSTATVFS */
11908
11909#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011910 if (statvfs == NULL) {
11911 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11912 return NULL;
11913 }
11914 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011915#endif /* HAVE_STATVFS */
11916
11917# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 if (lchown == NULL) {
11919 if (PyObject_DelAttrString(m, "lchown") == -1) {
11920 return NULL;
11921 }
11922 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011923#endif /* HAVE_LCHOWN */
11924
11925
11926#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011927
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011928 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011929 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11930
Larry Hastings6fe20b32012-04-19 15:07:49 -070011931 billion = PyLong_FromLong(1000000000);
11932 if (!billion)
11933 return NULL;
11934
Larry Hastings9cf065c2012-06-22 16:30:09 -070011935 /* suppress "function not used" warnings */
11936 {
11937 int ignored;
11938 fd_specified("", -1);
11939 follow_symlinks_specified("", 1);
11940 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11941 dir_fd_converter(Py_None, &ignored);
11942 dir_fd_unavailable(Py_None, &ignored);
11943 }
11944
11945 /*
11946 * provide list of locally available functions
11947 * so os.py can populate support_* lists
11948 */
11949 list = PyList_New(0);
11950 if (!list)
11951 return NULL;
11952 for (trace = have_functions; *trace; trace++) {
11953 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11954 if (!unicode)
11955 return NULL;
11956 if (PyList_Append(list, unicode))
11957 return NULL;
11958 Py_DECREF(unicode);
11959 }
11960 PyModule_AddObject(m, "_have_functions", list);
11961
11962 initialized = 1;
11963
Victor Stinner8c62be82010-05-06 00:08:46 +000011964 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011965
Guido van Rossumb6775db1994-08-01 11:34:53 +000011966}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011967
11968#ifdef __cplusplus
11969}
11970#endif