blob: 1f1711df8fa8225e5461f3d9796a4bdf83b1491b [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
417#define DEFAULT_DIR_FD AT_FDCWD
418#else
419#define DEFAULT_DIR_FD (-100)
420#endif
421
422static int
423_fd_converter(PyObject *o, int *p, int default_value) {
424 long long_value;
425 if (o == Py_None) {
426 *p = default_value;
427 return 1;
428 }
429 if (PyFloat_Check(o)) {
430 PyErr_SetString(PyExc_TypeError,
431 "integer argument expected, got float" );
432 return 0;
433 }
434 long_value = PyLong_AsLong(o);
435 if (long_value == -1 && PyErr_Occurred())
436 return 0;
437 if (long_value > INT_MAX) {
438 PyErr_SetString(PyExc_OverflowError,
439 "signed integer is greater than maximum");
440 return 0;
441 }
442 if (long_value < INT_MIN) {
443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is less than minimum");
445 return 0;
446 }
447 *p = (int)long_value;
448 return 1;
449}
450
451static int
452dir_fd_converter(PyObject *o, void *p) {
453 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
454}
455
456
457
458/*
459 * A PyArg_ParseTuple "converter" function
460 * that handles filesystem paths in the manner
461 * preferred by the os module.
462 *
463 * path_converter accepts (Unicode) strings and their
464 * subclasses, and bytes and their subclasses. What
465 * it does with the argument depends on the platform:
466 *
467 * * On Windows, if we get a (Unicode) string we
468 * extract the wchar_t * and return it; if we get
469 * bytes we extract the char * and return that.
470 *
471 * * On all other platforms, strings are encoded
472 * to bytes using PyUnicode_FSConverter, then we
473 * extract the char * from the bytes object and
474 * return that.
475 *
476 * path_converter also optionally accepts signed
477 * integers (representing open file descriptors) instead
478 * of path strings.
479 *
480 * Input fields:
481 * path.nullable
482 * If nonzero, the path is permitted to be None.
483 * path.allow_fd
484 * If nonzero, the path is permitted to be a file handle
485 * (a signed int) instead of a string.
486 * path.function_name
487 * If non-NULL, path_converter will use that as the name
488 * of the function in error messages.
489 * (If path.argument_name is NULL it omits the function name.)
490 * path.argument_name
491 * If non-NULL, path_converter will use that as the name
492 * of the parameter in error messages.
493 * (If path.argument_name is NULL it uses "path".)
494 *
495 * Output fields:
496 * path.wide
497 * Points to the path if it was expressed as Unicode
498 * and was not encoded. (Only used on Windows.)
499 * path.narrow
500 * Points to the path if it was expressed as bytes,
501 * or it was Unicode and was encoded to bytes.
502 * path.fd
503 * Contains a file descriptor if path.accept_fd was true
504 * and the caller provided a signed integer instead of any
505 * sort of string.
506 *
507 * WARNING: if your "path" parameter is optional, and is
508 * unspecified, path_converter will never get called.
509 * So if you set allow_fd, you *MUST* initialize path.fd = -1
510 * yourself!
511 * path.length
512 * The length of the path in characters, if specified as
513 * a string.
514 * path.object
515 * The original object passed in.
516 * path.cleanup
517 * For internal use only. May point to a temporary object.
518 * (Pay no attention to the man behind the curtain.)
519 *
520 * At most one of path.wide or path.narrow will be non-NULL.
521 * If path was None and path.nullable was set,
522 * or if path was an integer and path.allow_fd was set,
523 * both path.wide and path.narrow will be NULL
524 * and path.length will be 0.
525 *
526 * path_converter takes care to not write to the path_t
527 * unless it's successful. However it must reset the
528 * "cleanup" field each time it's called.
529 *
530 * Use as follows:
531 * path_t path;
532 * memset(&path, 0, sizeof(path));
533 * PyArg_ParseTuple(args, "O&", path_converter, &path);
534 * // ... use values from path ...
535 * path_cleanup(&path);
536 *
537 * (Note that if PyArg_Parse fails you don't need to call
538 * path_cleanup(). However it is safe to do so.)
539 */
540typedef struct {
541 char *function_name;
542 char *argument_name;
543 int nullable;
544 int allow_fd;
545 wchar_t *wide;
546 char *narrow;
547 int fd;
548 Py_ssize_t length;
549 PyObject *object;
550 PyObject *cleanup;
551} path_t;
552
553static void
554path_cleanup(path_t *path) {
555 if (path->cleanup) {
556 Py_DECREF(path->cleanup);
557 path->cleanup = NULL;
558 }
559}
560
561static int
562path_converter(PyObject *o, void *p) {
563 path_t *path = (path_t *)p;
564 PyObject *unicode, *bytes;
565 Py_ssize_t length;
566 char *narrow;
567
568#define FORMAT_EXCEPTION(exc, fmt) \
569 PyErr_Format(exc, "%s%s" fmt, \
570 path->function_name ? path->function_name : "", \
571 path->function_name ? ": " : "", \
572 path->argument_name ? path->argument_name : "path")
573
574 /* Py_CLEANUP_SUPPORTED support */
575 if (o == NULL) {
576 path_cleanup(path);
577 return 1;
578 }
579
580 /* ensure it's always safe to call path_cleanup() */
581 path->cleanup = NULL;
582
583 if (o == Py_None) {
584 if (!path->nullable) {
585 FORMAT_EXCEPTION(PyExc_TypeError,
586 "can't specify None for %s argument");
587 return 0;
588 }
589 path->wide = NULL;
590 path->narrow = NULL;
591 path->length = 0;
592 path->object = o;
593 path->fd = -1;
594 return 1;
595 }
596
597 unicode = PyUnicode_FromObject(o);
598 if (unicode) {
599#ifdef MS_WINDOWS
600 wchar_t *wide;
601 length = PyUnicode_GET_SIZE(unicode);
602 if (length > 32767) {
603 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
604 Py_DECREF(unicode);
605 return 0;
606 }
607
608 wide = PyUnicode_AsUnicode(unicode);
609 if (!wide) {
610 Py_DECREF(unicode);
611 return 0;
612 }
613
614 path->wide = wide;
615 path->narrow = NULL;
616 path->length = length;
617 path->object = o;
618 path->fd = -1;
619 path->cleanup = unicode;
620 return Py_CLEANUP_SUPPORTED;
621#else
622 int converted = PyUnicode_FSConverter(unicode, &bytes);
623 Py_DECREF(unicode);
624 if (!converted)
625 bytes = NULL;
626#endif
627 }
628 else {
629 PyErr_Clear();
630 bytes = PyBytes_FromObject(o);
631 if (!bytes) {
632 PyErr_Clear();
633 if (path->allow_fd) {
634 int fd;
635 /*
636 * note: _fd_converter always permits None.
637 * but we've already done our None check.
638 * so o cannot be None at this point.
639 */
640 int result = _fd_converter(o, &fd, -1);
641 if (result) {
642 path->wide = NULL;
643 path->narrow = NULL;
644 path->length = 0;
645 path->object = o;
646 path->fd = fd;
647 return result;
648 }
649 }
650 }
651 }
652
653 if (!bytes) {
654 if (!PyErr_Occurred())
655 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
656 return 0;
657 }
658
659#ifdef MS_WINDOWS
660 if (win32_warn_bytes_api()) {
661 Py_DECREF(bytes);
662 return 0;
663 }
664#endif
665
666 length = PyBytes_GET_SIZE(bytes);
667#ifdef MS_WINDOWS
668 if (length > MAX_PATH) {
669 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 narrow = PyBytes_AS_STRING(bytes);
676 if (length != strlen(narrow)) {
677 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
678 Py_DECREF(bytes);
679 return 0;
680 }
681
682 path->wide = NULL;
683 path->narrow = narrow;
684 path->length = length;
685 path->object = o;
686 path->fd = -1;
687 path->cleanup = bytes;
688 return Py_CLEANUP_SUPPORTED;
689}
690
691static void
692argument_unavailable_error(char *function_name, char *argument_name) {
693 PyErr_Format(PyExc_NotImplementedError,
694 "%s%s%s unavailable on this platform",
695 (function_name != NULL) ? function_name : "",
696 (function_name != NULL) ? ": ": "",
697 argument_name);
698}
699
700static int
701dir_fd_unavailable(PyObject *o, void *p) {
702 int *dir_fd = (int *)p;
703 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
704 if (!return_value)
705 return 0;
706 if (*dir_fd == DEFAULT_DIR_FD)
707 return 1;
708 argument_unavailable_error(NULL, "dir_fd");
709 return 0;
710}
711
712static int
713fd_specified(char *function_name, int fd) {
714 if (fd == -1)
715 return 0;
716
717 argument_unavailable_error(function_name, "fd");
718 return 1;
719}
720
721static int
722follow_symlinks_specified(char *function_name, int follow_symlinks) {
723 if (follow_symlinks)
724 return 0;
725
726 argument_unavailable_error(function_name, "follow_symlinks");
727 return 1;
728}
729
730static int
731path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
732 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
733 PyErr_Format(PyExc_ValueError,
734 "%s: can't specify dir_fd without matching path",
735 function_name);
736 return 1;
737 }
738 return 0;
739}
740
741static int
742dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify both dir_fd and fd",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753fd_and_follow_symlinks_invalid(char *function_name, int fd,
754 int follow_symlinks) {
755 if ((fd > 0) && (!follow_symlinks)) {
756 PyErr_Format(PyExc_ValueError,
757 "%s: cannot use fd and follow_symlinks together",
758 function_name);
759 return 1;
760 }
761 return 0;
762}
763
764static int
765dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
766 int follow_symlinks) {
767 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
768 PyErr_Format(PyExc_ValueError,
769 "%s: cannot use dir_fd and follow_symlinks together",
770 function_name);
771 return 1;
772 }
773 return 0;
774}
775
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200776/* A helper used by a number of POSIX-only functions */
777#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000778static int
779_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000780{
781#if !defined(HAVE_LARGEFILE_SUPPORT)
782 *((off_t*)addr) = PyLong_AsLong(arg);
783#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000784 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000785#endif
786 if (PyErr_Occurred())
787 return 0;
788 return 1;
789}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200790#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792#if defined _MSC_VER && _MSC_VER >= 1400
793/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
794 * valid and throw an assertion if it isn't.
795 * Normally, an invalid fd is likely to be a C program error and therefore
796 * an assertion can be useful, but it does contradict the POSIX standard
797 * which for write(2) states:
798 * "Otherwise, -1 shall be returned and errno set to indicate the error."
799 * "[EBADF] The fildes argument is not a valid file descriptor open for
800 * writing."
801 * Furthermore, python allows the user to enter any old integer
802 * as a fd and should merely raise a python exception on error.
803 * The Microsoft CRT doesn't provide an official way to check for the
804 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * internal structures involved.
807 * The structures below must be updated for each version of visual studio
808 * according to the file internal.h in the CRT source, until MS comes
809 * up with a less hacky way to do this.
810 * (all of this is to avoid globally modifying the CRT behaviour using
811 * _set_invalid_parameter_handler() and _CrtSetReportMode())
812 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000813/* The actual size of the structure is determined at runtime.
814 * Only the first items must be present.
815 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000816typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000817 intptr_t osfhnd;
818 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000819} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000820
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000821extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000822#define IOINFO_L2E 5
823#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
824#define IOINFO_ARRAYS 64
825#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
826#define FOPEN 0x01
827#define _NO_CONSOLE_FILENO (intptr_t)-2
828
829/* This function emulates what the windows CRT does to validate file handles */
830int
831_PyVerify_fd(int fd)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 const int i1 = fd >> IOINFO_L2E;
834 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000835
Antoine Pitrou22e41552010-08-15 18:07:50 +0000836 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000837
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 /* Determine the actual size of the ioinfo structure,
839 * as used by the CRT loaded in memory
840 */
841 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
842 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
843 }
844 if (sizeof_ioinfo == 0) {
845 /* This should not happen... */
846 goto fail;
847 }
848
849 /* See that it isn't a special CLEAR fileno */
850 if (fd != _NO_CONSOLE_FILENO) {
851 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
852 * we check pointer validity and other info
853 */
854 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
855 /* finally, check that the file is open */
856 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
857 if (info->osfile & FOPEN) {
858 return 1;
859 }
860 }
861 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000862 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 errno = EBADF;
864 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000865}
866
867/* the special case of checking dup2. The target fd must be in a sensible range */
868static int
869_PyVerify_fd_dup2(int fd1, int fd2)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 if (!_PyVerify_fd(fd1))
872 return 0;
873 if (fd2 == _NO_CONSOLE_FILENO)
874 return 0;
875 if ((unsigned)fd2 < _NHANDLE_)
876 return 1;
877 else
878 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000879}
880#else
881/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
882#define _PyVerify_fd_dup2(A, B) (1)
883#endif
884
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000885#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000886/* The following structure was copied from
887 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
888 include doesn't seem to be present in the Windows SDK (at least as included
889 with Visual Studio Express). */
890typedef struct _REPARSE_DATA_BUFFER {
891 ULONG ReparseTag;
892 USHORT ReparseDataLength;
893 USHORT Reserved;
894 union {
895 struct {
896 USHORT SubstituteNameOffset;
897 USHORT SubstituteNameLength;
898 USHORT PrintNameOffset;
899 USHORT PrintNameLength;
900 ULONG Flags;
901 WCHAR PathBuffer[1];
902 } SymbolicLinkReparseBuffer;
903
904 struct {
905 USHORT SubstituteNameOffset;
906 USHORT SubstituteNameLength;
907 USHORT PrintNameOffset;
908 USHORT PrintNameLength;
909 WCHAR PathBuffer[1];
910 } MountPointReparseBuffer;
911
912 struct {
913 UCHAR DataBuffer[1];
914 } GenericReparseBuffer;
915 };
916} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
917
918#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
919 GenericReparseBuffer)
920#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
921
922static int
Brian Curtind25aef52011-06-13 15:16:04 -0500923win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000924{
925 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
926 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
927 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000928
929 if (0 == DeviceIoControl(
930 reparse_point_handle,
931 FSCTL_GET_REPARSE_POINT,
932 NULL, 0, /* in buffer */
933 target_buffer, sizeof(target_buffer),
934 &n_bytes_returned,
935 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500936 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000937
938 if (reparse_tag)
939 *reparse_tag = rdb->ReparseTag;
940
Brian Curtind25aef52011-06-13 15:16:04 -0500941 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000942}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100943
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000944#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000945
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000947#ifdef WITH_NEXT_FRAMEWORK
948/* On Darwin/MacOSX a shared library or framework has no access to
949** environ directly, we must obtain it with _NSGetEnviron().
950*/
951#include <crt_externs.h>
952static char **environ;
953#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000955#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000958convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000963#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000964 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000965#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000966#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 APIRET rc;
968 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
969#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000970
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 d = PyDict_New();
972 if (d == NULL)
973 return NULL;
974#ifdef WITH_NEXT_FRAMEWORK
975 if (environ == NULL)
976 environ = *_NSGetEnviron();
977#endif
978#ifdef MS_WINDOWS
979 /* _wenviron must be initialized in this way if the program is started
980 through main() instead of wmain(). */
981 _wgetenv(L"");
982 if (_wenviron == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = _wenviron; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 wchar_t *p = wcschr(*e, L'=');
989 if (p == NULL)
990 continue;
991 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000995 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
1008 }
1009#else
1010 if (environ == NULL)
1011 return d;
1012 /* This part ignores errors */
1013 for (e = environ; *e != NULL; e++) {
1014 PyObject *k;
1015 PyObject *v;
1016 char *p = strchr(*e, '=');
1017 if (p == NULL)
1018 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001019 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 if (k == NULL) {
1021 PyErr_Clear();
1022 continue;
1023 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001024 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 if (v == NULL) {
1026 PyErr_Clear();
1027 Py_DECREF(k);
1028 continue;
1029 }
1030 if (PyDict_GetItem(d, k) == NULL) {
1031 if (PyDict_SetItem(d, k, v) != 0)
1032 PyErr_Clear();
1033 }
1034 Py_DECREF(k);
1035 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001036 }
1037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001038#if defined(PYOS_OS2)
1039 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1040 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1041 PyObject *v = PyBytes_FromString(buffer);
1042 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1043 Py_DECREF(v);
1044 }
1045 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1046 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1047 PyObject *v = PyBytes_FromString(buffer);
1048 PyDict_SetItemString(d, "ENDLIBPATH", v);
1049 Py_DECREF(v);
1050 }
1051#endif
1052 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055/* Set a POSIX-specific error from errno, and return NULL */
1056
Barry Warsawd58d7641998-07-23 16:14:40 +00001057static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001058posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061}
Barry Warsawd58d7641998-07-23 16:14:40 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001066}
1067
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001068
Mark Hammondef8b6542001-05-13 08:04:26 +00001069static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001070posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001071{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001072 PyObject *name_str, *rc;
1073 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1074 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001076 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1077 name_str);
1078 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001080}
1081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001082#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001083static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001084win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 /* XXX We should pass the function name along in the future.
1087 (winreg.c also wants to pass the function name.)
1088 This would however require an additional param to the
1089 Windows error object, which is non-trivial.
1090 */
1091 errno = GetLastError();
1092 if (filename)
1093 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1094 else
1095 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001097
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001098static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001099win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 /* XXX - see win32_error for comments on 'function' */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107}
1108
Victor Stinnereb5657a2011-09-30 01:44:27 +02001109static PyObject *
1110win32_error_object(char* function, PyObject* filename)
1111{
1112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1116 PyExc_WindowsError,
1117 errno,
1118 filename);
1119 else
1120 return PyErr_SetFromWindowsErr(errno);
1121}
1122
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001123#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125/*
1126 * Some functions return Win32 errors, others only ever use posix_error
1127 * (this is for backwards compatibility with exceptions)
1128 */
1129static PyObject *
1130path_posix_error(char *function_name, path_t *path)
1131{
1132 if (path->narrow)
1133 return posix_error_with_filename(path->narrow);
1134 return posix_error();
1135}
1136
1137static PyObject *
1138path_error(char *function_name, path_t *path)
1139{
1140#ifdef MS_WINDOWS
1141 if (path->narrow)
1142 return win32_error(function_name, path->narrow);
1143 if (path->wide)
1144 return win32_error_unicode(function_name, path->wide);
1145 return win32_error(function_name, NULL);
1146#else
1147 return path_posix_error(function_name, path);
1148#endif
1149}
1150
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151#if defined(PYOS_OS2)
1152/**********************************************************************
1153 * Helper Function to Trim and Format OS/2 Messages
1154 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001155static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001156os2_formatmsg(char *msgbuf, int msglen, char *reason)
1157{
1158 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1159
1160 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1161 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1162
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001163 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001164 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1165 }
1166
1167 /* Add Optional Reason Text */
1168 if (reason) {
1169 strcat(msgbuf, " : ");
1170 strcat(msgbuf, reason);
1171 }
1172}
1173
1174/**********************************************************************
1175 * Decode an OS/2 Operating System Error Code
1176 *
1177 * A convenience function to lookup an OS/2 error code and return a
1178 * text message we can use to raise a Python exception.
1179 *
1180 * Notes:
1181 * The messages for errors returned from the OS/2 kernel reside in
1182 * the file OSO001.MSG in the \OS2 directory hierarchy.
1183 *
1184 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001185static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001186os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1187{
1188 APIRET rc;
1189 ULONG msglen;
1190
1191 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1192 Py_BEGIN_ALLOW_THREADS
1193 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1194 errorcode, "oso001.msg", &msglen);
1195 Py_END_ALLOW_THREADS
1196
1197 if (rc == NO_ERROR)
1198 os2_formatmsg(msgbuf, msglen, reason);
1199 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001200 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001202
1203 return msgbuf;
1204}
1205
1206/* Set an OS/2-specific error and return NULL. OS/2 kernel
1207 errors are not in a global variable e.g. 'errno' nor are
1208 they congruent with posix error numbers. */
1209
Victor Stinner8c62be82010-05-06 00:08:46 +00001210static PyObject *
1211os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001212{
1213 char text[1024];
1214 PyObject *v;
1215
1216 os2_strerror(text, sizeof(text), code, "");
1217
1218 v = Py_BuildValue("(is)", code, text);
1219 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001220 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221 Py_DECREF(v);
1222 }
1223 return NULL; /* Signal to Python that an Exception is Pending */
1224}
1225
1226#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227
1228/* POSIX generic methods */
1229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001231posix_fildes(PyObject *fdobj, int (*func)(int))
1232{
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 int fd;
1234 int res;
1235 fd = PyObject_AsFileDescriptor(fdobj);
1236 if (fd < 0)
1237 return NULL;
1238 if (!_PyVerify_fd(fd))
1239 return posix_error();
1240 Py_BEGIN_ALLOW_THREADS
1241 res = (*func)(fd);
1242 Py_END_ALLOW_THREADS
1243 if (res < 0)
1244 return posix_error();
1245 Py_INCREF(Py_None);
1246 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247}
Guido van Rossum21142a01999-01-08 21:05:37 +00001248
1249static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 PyObject *opath1 = NULL;
1253 char *path1;
1254 int res;
1255 if (!PyArg_ParseTuple(args, format,
1256 PyUnicode_FSConverter, &opath1))
1257 return NULL;
1258 path1 = PyBytes_AsString(opath1);
1259 Py_BEGIN_ALLOW_THREADS
1260 res = (*func)(path1);
1261 Py_END_ALLOW_THREADS
1262 if (res < 0)
1263 return posix_error_with_allocated_filename(opath1);
1264 Py_DECREF(opath1);
1265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001270#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001272win32_1str(PyObject* args, char* func,
1273 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1274 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001277 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001279
Victor Stinnereb5657a2011-09-30 01:44:27 +02001280 if (PyArg_ParseTuple(args, wformat, &uni))
1281 {
1282 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1283 if (wstr == NULL)
1284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 Py_END_ALLOW_THREADS
1288 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 Py_INCREF(Py_None);
1291 return Py_None;
1292 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 PyErr_Clear();
1294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (!PyArg_ParseTuple(args, format, &ansi))
1296 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001297 if (win32_warn_bytes_api())
1298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_BEGIN_ALLOW_THREADS
1300 result = funcA(ansi);
1301 Py_END_ALLOW_THREADS
1302 if (!result)
1303 return win32_error(func, ansi);
1304 Py_INCREF(Py_None);
1305 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306
1307}
1308
1309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char new_path[MAX_PATH+1];
1318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
1323 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
1327 than MAX_PATH. */
1328 assert(result <= MAX_PATH+1);
1329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
1348 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1349 if (!result)
1350 return FALSE;
1351 if (result > MAX_PATH+1) {
1352 new_path = malloc(result * sizeof(wchar_t));
1353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
1359 free(new_path);
1360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
1370 free(new_path);
1371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001383
1384struct win32_stat{
1385 int st_dev;
1386 __int64 st_ino;
1387 unsigned short st_mode;
1388 int st_nlink;
1389 int st_uid;
1390 int st_gid;
1391 int st_rdev;
1392 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001393 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001395 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001396 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001397 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001398 int st_ctime_nsec;
1399};
1400
1401static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1402
1403static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1407 /* Cannot simply cast and dereference in_ptr,
1408 since it might not be aligned properly */
1409 __int64 in;
1410 memcpy(&in, in_ptr, sizeof(in));
1411 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001412 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001413}
1414
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness */
1419 __int64 out;
1420 out = time_in + secs_between_epochs;
1421 out = out * 10000000 + nsec_in / 100;
1422 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423}
1424
Martin v. Löwis14694662006-02-03 12:54:16 +00001425/* Below, we *know* that ugo+r is 0444 */
1426#if _S_IREAD != 0400
1427#error Unsupported C library
1428#endif
1429static int
1430attributes_to_mode(DWORD attr)
1431{
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 int m = 0;
1433 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1434 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1435 else
1436 m |= _S_IFREG;
1437 if (attr & FILE_ATTRIBUTE_READONLY)
1438 m |= 0444;
1439 else
1440 m |= 0666;
1441 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442}
1443
1444static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 memset(result, 0, sizeof(*result));
1448 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1449 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1450 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1451 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1452 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001453 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001454 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1456 /* first clear the S_IFMT bits */
1457 result->st_mode ^= (result->st_mode & 0170000);
1458 /* now set the bits that make this a symlink */
1459 result->st_mode |= 0120000;
1460 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463}
1464
Guido van Rossumd8faa362007-04-27 19:54:29 +00001465static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATAA FileData;
1470 hFindFile = FindFirstFileA(pszFile, &FileData);
1471 if (hFindFile == INVALID_HANDLE_VALUE)
1472 return FALSE;
1473 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001474 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001475 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001476 info->dwFileAttributes = FileData.dwFileAttributes;
1477 info->ftCreationTime = FileData.ftCreationTime;
1478 info->ftLastAccessTime = FileData.ftLastAccessTime;
1479 info->ftLastWriteTime = FileData.ftLastWriteTime;
1480 info->nFileSizeHigh = FileData.nFileSizeHigh;
1481 info->nFileSizeLow = FileData.nFileSizeLow;
1482/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001483 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1484 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486}
1487
1488static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 HANDLE hFindFile;
1492 WIN32_FIND_DATAW FileData;
1493 hFindFile = FindFirstFileW(pszFile, &FileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE)
1495 return FALSE;
1496 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001498 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 info->dwFileAttributes = FileData.dwFileAttributes;
1500 info->ftCreationTime = FileData.ftCreationTime;
1501 info->ftLastAccessTime = FileData.ftLastAccessTime;
1502 info->ftLastWriteTime = FileData.ftLastWriteTime;
1503 info->nFileSizeHigh = FileData.nFileSizeHigh;
1504 info->nFileSizeLow = FileData.nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509}
1510
Brian Curtind25aef52011-06-13 15:16:04 -05001511/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1512static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001513static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1514 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515static int
Brian Curtind25aef52011-06-13 15:16:04 -05001516check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517{
Brian Curtind25aef52011-06-13 15:16:04 -05001518 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001519 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1520 DWORD);
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* only recheck */
1523 if (!has_GetFinalPathNameByHandle)
1524 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001525 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001526 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1527 "GetFinalPathNameByHandleA");
1528 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1529 "GetFinalPathNameByHandleW");
1530 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1531 Py_GetFinalPathNameByHandleW;
1532 }
1533 return has_GetFinalPathNameByHandle;
1534}
1535
1536static BOOL
1537get_target_path(HANDLE hdl, wchar_t **target_path)
1538{
1539 int buf_size, result_length;
1540 wchar_t *buf;
1541
1542 /* We have a good handle to the target, use it to determine
1543 the target path name (then we'll call lstat on it). */
1544 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1545 VOLUME_NAME_DOS);
1546 if(!buf_size)
1547 return FALSE;
1548
1549 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001550 if (!buf) {
1551 SetLastError(ERROR_OUTOFMEMORY);
1552 return FALSE;
1553 }
1554
Brian Curtind25aef52011-06-13 15:16:04 -05001555 result_length = Py_GetFinalPathNameByHandleW(hdl,
1556 buf, buf_size, VOLUME_NAME_DOS);
1557
1558 if(!result_length) {
1559 free(buf);
1560 return FALSE;
1561 }
1562
1563 if(!CloseHandle(hdl)) {
1564 free(buf);
1565 return FALSE;
1566 }
1567
1568 buf[result_length] = 0;
1569
1570 *target_path = buf;
1571 return TRUE;
1572}
1573
1574static int
1575win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1576 BOOL traverse);
1577static int
1578win32_xstat_impl(const char *path, struct win32_stat *result,
1579 BOOL traverse)
1580{
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const char *dot;
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1590 traverse reparse point. */
1591 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 }
1593
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 hFile = CreateFileA(
1595 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 0, /* share mode */
1598 NULL, /* security attributes */
1599 OPEN_EXISTING,
1600 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001601 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1602 Because of this, calls like GetFinalPathNameByHandle will return
1603 the symlink path agin and not the actual final path. */
1604 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1605 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 NULL);
1607
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 /* Either the target doesn't exist, or we don't have access to
1610 get a handle to it. If the former, we need to return an error.
1611 If the latter, we can use attributes_from_dir. */
1612 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileA(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 free(target_path);
1656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = strrchr(path, '.');
1665 if (dot) {
1666 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1667 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Brian Curtind25aef52011-06-13 15:16:04 -05001674win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1675 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
1677 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001678 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 const wchar_t *dot;
1683
Brian Curtind25aef52011-06-13 15:16:04 -05001684 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1686 traverse reparse point. */
1687 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 }
1689
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 hFile = CreateFileW(
1691 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 0, /* share mode */
1694 NULL, /* security attributes */
1695 OPEN_EXISTING,
1696 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1698 Because of this, calls like GetFinalPathNameByHandle will return
1699 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001700 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 NULL);
1703
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 /* Either the target doesn't exist, or we don't have access to
1706 get a handle to it. If the former, we need to return an error.
1707 If the latter, we can use attributes_from_dir. */
1708 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
1739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
1750 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 free(target_path);
1752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779static int
1780win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1781{
1782 /* Protocol violation: we explicitly clear errno, instead of
1783 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001784 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 errno = 0;
1786 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787}
Brian Curtind25aef52011-06-13 15:16:04 -05001788/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001789
1790 In Posix, stat automatically traverses symlinks and returns the stat
1791 structure for the target. In Windows, the equivalent GetFileAttributes by
1792 default does not traverse symlinks and instead returns attributes for
1793 the symlink.
1794
1795 Therefore, win32_lstat will get the attributes traditionally, and
1796 win32_stat will first explicitly resolve the symlink target and then will
1797 call win32_lstat on that result.
1798
Ezio Melotti4969f702011-03-15 05:59:46 +02001799 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001801static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001802win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001803{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001804 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001805}
1806
Victor Stinner8c62be82010-05-06 00:08:46 +00001807static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001808win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001809{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001811}
1812
1813static int
1814win32_stat(const char* path, struct win32_stat *result)
1815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001817}
1818
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_stat_w(const wchar_t* path, struct win32_stat *result)
1821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001823}
1824
1825static int
1826win32_fstat(int file_number, struct win32_stat *result)
1827{
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 BY_HANDLE_FILE_INFORMATION info;
1829 HANDLE h;
1830 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001831
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001833
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
1836 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001837
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 if (h == INVALID_HANDLE_VALUE) {
1839 /* This is really a C library error (invalid file handle).
1840 We set the Win32 error to the closes one matching. */
1841 SetLastError(ERROR_INVALID_HANDLE);
1842 return -1;
1843 }
1844 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 type = GetFileType(h);
1847 if (type == FILE_TYPE_UNKNOWN) {
1848 DWORD error = GetLastError();
1849 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 }
1852 /* else: valid but unknown file */
1853 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (type != FILE_TYPE_DISK) {
1856 if (type == FILE_TYPE_CHAR)
1857 result->st_mode = _S_IFCHR;
1858 else if (type == FILE_TYPE_PIPE)
1859 result->st_mode = _S_IFIFO;
1860 return 0;
1861 }
1862
1863 if (!GetFileInformationByHandle(h, &info)) {
1864 return -1;
1865 }
1866
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1870 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
1873#endif /* MS_WINDOWS */
1874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001876"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001878 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1880\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001881Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1882or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001885
1886static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 {"st_mode", "protection bits"},
1888 {"st_ino", "inode"},
1889 {"st_dev", "device"},
1890 {"st_nlink", "number of hard links"},
1891 {"st_uid", "user ID of owner"},
1892 {"st_gid", "group ID of owner"},
1893 {"st_size", "total size, in bytes"},
1894 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1895 {NULL, "integer time of last access"},
1896 {NULL, "integer time of last modification"},
1897 {NULL, "integer time of last change"},
1898 {"st_atime", "time of last access"},
1899 {"st_mtime", "time of last modification"},
1900 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 {"st_atime_ns", "time of last access in nanoseconds"},
1902 {"st_mtime_ns", "time of last modification in nanoseconds"},
1903 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001904#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001907#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001910#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001913#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001915#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001916#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001918#endif
1919#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923};
1924
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001925#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001926#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001929#endif
1930
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1933#else
1934#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1935#endif
1936
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1939#else
1940#define ST_RDEV_IDX ST_BLOCKS_IDX
1941#endif
1942
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001943#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1944#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1945#else
1946#define ST_FLAGS_IDX ST_RDEV_IDX
1947#endif
1948
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001949#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001950#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001951#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001952#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001953#endif
1954
1955#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1956#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1957#else
1958#define ST_BIRTHTIME_IDX ST_GEN_IDX
1959#endif
1960
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001961static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 "stat_result", /* name */
1963 stat_result__doc__, /* doc */
1964 stat_result_fields,
1965 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001966};
1967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1970This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001972or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001973\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975
1976static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"f_bsize", },
1978 {"f_frsize", },
1979 {"f_blocks", },
1980 {"f_bfree", },
1981 {"f_bavail", },
1982 {"f_files", },
1983 {"f_ffree", },
1984 {"f_favail", },
1985 {"f_flag", },
1986 {"f_namemax",},
1987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
1990static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 "statvfs_result", /* name */
1992 statvfs_result__doc__, /* doc */
1993 statvfs_result_fields,
1994 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995};
1996
Ross Lagerwall7807c352011-03-17 20:20:30 +02001997#if defined(HAVE_WAITID) && !defined(__APPLE__)
1998PyDoc_STRVAR(waitid_result__doc__,
1999"waitid_result: Result from waitid.\n\n\
2000This object may be accessed either as a tuple of\n\
2001 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2002or via the attributes si_pid, si_uid, and so on.\n\
2003\n\
2004See os.waitid for more information.");
2005
2006static PyStructSequence_Field waitid_result_fields[] = {
2007 {"si_pid", },
2008 {"si_uid", },
2009 {"si_signo", },
2010 {"si_status", },
2011 {"si_code", },
2012 {0}
2013};
2014
2015static PyStructSequence_Desc waitid_result_desc = {
2016 "waitid_result", /* name */
2017 waitid_result__doc__, /* doc */
2018 waitid_result_fields,
2019 5
2020};
2021static PyTypeObject WaitidResultType;
2022#endif
2023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002024static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025static PyTypeObject StatResultType;
2026static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002027#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002028static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002029#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002030static newfunc structseq_new;
2031
2032static PyObject *
2033statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyStructSequence *result;
2036 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002037
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 result = (PyStructSequence*)structseq_new(type, args, kwds);
2039 if (!result)
2040 return NULL;
2041 /* If we have been initialized from a tuple,
2042 st_?time might be set to None. Initialize it
2043 from the int slots. */
2044 for (i = 7; i <= 9; i++) {
2045 if (result->ob_item[i+3] == Py_None) {
2046 Py_DECREF(Py_None);
2047 Py_INCREF(result->ob_item[i]);
2048 result->ob_item[i+3] = result->ob_item[i];
2049 }
2050 }
2051 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052}
2053
2054
2055
2056/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002057static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002058
2059PyDoc_STRVAR(stat_float_times__doc__,
2060"stat_float_times([newval]) -> oldval\n\n\
2061Determine whether os.[lf]stat represents time stamps as float objects.\n\
2062If newval is True, future calls to stat() return floats, if it is False,\n\
2063future calls return ints. \n\
2064If newval is omitted, return the current setting.\n");
2065
2066static PyObject*
2067stat_float_times(PyObject* self, PyObject *args)
2068{
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 int newval = -1;
2070 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2071 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002072 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2073 "stat_float_times() is deprecated",
2074 1))
2075 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 if (newval == -1)
2077 /* Return old value */
2078 return PyBool_FromLong(_stat_float_times);
2079 _stat_float_times = newval;
2080 Py_INCREF(Py_None);
2081 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002082}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083
Larry Hastings6fe20b32012-04-19 15:07:49 -07002084static PyObject *billion = NULL;
2085
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002086static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002087fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002088{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002089 PyObject *s = _PyLong_FromTime_t(sec);
2090 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2091 PyObject *s_in_ns = NULL;
2092 PyObject *ns_total = NULL;
2093 PyObject *float_s = NULL;
2094
2095 if (!(s && ns_fractional))
2096 goto exit;
2097
2098 s_in_ns = PyNumber_Multiply(s, billion);
2099 if (!s_in_ns)
2100 goto exit;
2101
2102 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2103 if (!ns_total)
2104 goto exit;
2105
Victor Stinner4195b5c2012-02-08 23:03:19 +01002106 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002107 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2108 if (!float_s)
2109 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002111 else {
2112 float_s = s;
2113 Py_INCREF(float_s);
2114 }
2115
2116 PyStructSequence_SET_ITEM(v, index, s);
2117 PyStructSequence_SET_ITEM(v, index+3, float_s);
2118 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2119 s = NULL;
2120 float_s = NULL;
2121 ns_total = NULL;
2122exit:
2123 Py_XDECREF(s);
2124 Py_XDECREF(ns_fractional);
2125 Py_XDECREF(s_in_ns);
2126 Py_XDECREF(ns_total);
2127 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002128}
2129
Tim Peters5aa91602002-01-30 05:46:57 +00002130/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002131 (used by posix_stat() and posix_fstat()) */
2132static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002133_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 unsigned long ansec, mnsec, cnsec;
2136 PyObject *v = PyStructSequence_New(&StatResultType);
2137 if (v == NULL)
2138 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002139
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002141#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002142 PyStructSequence_SET_ITEM(v, 1,
2143 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002144#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002146#endif
2147#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 PyStructSequence_SET_ITEM(v, 2,
2149 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002156#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, 6,
2158 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002161#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002162
Martin v. Löwis14694662006-02-03 12:54:16 +00002163#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 ansec = st->st_atim.tv_nsec;
2165 mnsec = st->st_mtim.tv_nsec;
2166 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002167#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 ansec = st->st_atimespec.tv_nsec;
2169 mnsec = st->st_mtimespec.tv_nsec;
2170 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002171#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 ansec = st->st_atime_nsec;
2173 mnsec = st->st_mtime_nsec;
2174 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002177#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002178 fill_time(v, 7, st->st_atime, ansec);
2179 fill_time(v, 8, st->st_mtime, mnsec);
2180 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002181
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002182#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2184 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002185#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002186#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2188 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002190#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2192 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002193#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002194#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2196 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002197#endif
2198#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002200 PyObject *val;
2201 unsigned long bsec,bnsec;
2202 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002203#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002204 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002205#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002207#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002208 if (_stat_float_times) {
2209 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2210 } else {
2211 val = PyLong_FromLong((long)bsec);
2212 }
2213 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2214 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002216#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002217#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2219 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002220#endif
Fred Drake699f3522000-06-29 21:12:41 +00002221
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 if (PyErr_Occurred()) {
2223 Py_DECREF(v);
2224 return NULL;
2225 }
Fred Drake699f3522000-06-29 21:12:41 +00002226
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002228}
2229
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002230/* POSIX methods */
2231
Guido van Rossum94f6f721999-01-06 18:42:14 +00002232
2233static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002234posix_do_stat(char *function_name, path_t *path,
2235 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002236{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002237 STRUCT_STAT st;
2238 int result;
2239
2240#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2241 if (follow_symlinks_specified(function_name, follow_symlinks))
2242 return NULL;
2243#endif
2244
2245 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2246 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2247 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2248 return NULL;
2249
2250 Py_BEGIN_ALLOW_THREADS
2251 if (path->fd != -1)
2252 result = FSTAT(path->fd, &st);
2253 else
2254#ifdef MS_WINDOWS
2255 if (path->wide) {
2256 if (follow_symlinks)
2257 result = win32_stat_w(path->wide, &st);
2258 else
2259 result = win32_lstat_w(path->wide, &st);
2260 }
2261 else
2262#endif
2263#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2264 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2265 result = LSTAT(path->narrow, &st);
2266 else
2267#endif
2268#ifdef HAVE_FSTATAT
2269 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2270 result = fstatat(dir_fd, path->narrow, &st,
2271 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2272 else
2273#endif
2274 result = STAT(path->narrow, &st);
2275 Py_END_ALLOW_THREADS
2276
2277 if (result != 0)
2278 return path_error("stat", path);
2279
2280 return _pystat_fromstructstat(&st);
2281}
2282
2283PyDoc_STRVAR(posix_stat__doc__,
2284"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2285Perform a stat system call on the given path.\n\
2286\n\
2287path may be specified as either a string or as an open file descriptor.\n\
2288\n\
2289If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2290 and path should be relative; path will then be relative to that directory.\n\
2291 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2292 it will raise a NotImplementedError.\n\
2293If follow_symlinks is False, and the last element of the path is a symbolic\n\
2294 link, stat will examine the symbolic link itself instead of the file the\n\
2295 link points to.\n\
2296It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2297 an open file descriptor.");
2298
2299static PyObject *
2300posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2301{
2302 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2303 path_t path;
2304 int dir_fd = DEFAULT_DIR_FD;
2305 int follow_symlinks = 1;
2306 PyObject *return_value;
2307
2308 memset(&path, 0, sizeof(path));
2309 path.allow_fd = 1;
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2311 path_converter, &path,
2312#ifdef HAVE_FSTATAT
2313 dir_fd_converter, &dir_fd,
2314#else
2315 dir_fd_unavailable, &dir_fd,
2316#endif
2317 &follow_symlinks))
2318 return NULL;
2319 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2320 path_cleanup(&path);
2321 return return_value;
2322}
2323
2324PyDoc_STRVAR(posix_lstat__doc__,
2325"lstat(path, *, dir_fd=None) -> stat result\n\n\
2326Like stat(), but do not follow symbolic links.\n\
2327Equivalent to stat(path, follow_symlinks=False).");
2328
2329static PyObject *
2330posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2331{
2332 static char *keywords[] = {"path", "dir_fd", NULL};
2333 path_t path;
2334 int dir_fd = DEFAULT_DIR_FD;
2335 int follow_symlinks = 0;
2336 PyObject *return_value;
2337
2338 memset(&path, 0, sizeof(path));
2339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2340 path_converter, &path,
2341#ifdef HAVE_FSTATAT
2342 dir_fd_converter, &dir_fd
2343#else
2344 dir_fd_unavailable, &dir_fd
2345#endif
2346 ))
2347 return NULL;
2348 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2349 path_cleanup(&path);
2350 return return_value;
2351}
2352
2353PyDoc_STRVAR(posix_access__doc__,
2354"access(path, mode, *, dir_fd=None, effective_ids=False,\
2355 follow_symlinks=True)\n\n\
2356Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2357False otherwise.\n\
2358\n\
2359If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2360 and path should be relative; path will then be relative to that directory.\n\
2361If effective_ids is True, access will use the effective uid/gid instead of\n\
2362 the real uid/gid.\n\
2363If follow_symlinks is False, and the last element of the path is a symbolic\n\
2364 link, access will examine the symbolic link itself instead of the file the\n\
2365 link points to.\n\
2366dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2367 on your platform. If they are unavailable, using them will raise a\n\
2368 NotImplementedError.\n\
2369\n\
2370Note that most operations will use the effective uid/gid, therefore this\n\
2371 routine can be used in a suid/sgid environment to test if the invoking user\n\
2372 has the specified access to the path.\n\
2373The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2374 of R_OK, W_OK, and X_OK.");
2375
2376static PyObject *
2377posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2378{
2379 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2380 "follow_symlinks", NULL};
2381 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002382 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002383 int dir_fd = DEFAULT_DIR_FD;
2384 int effective_ids = 0;
2385 int follow_symlinks = 1;
2386 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002387
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002388#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002392#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002393
2394 memset(&path, 0, sizeof(path));
2395 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2396 path_converter, &path, &mode,
2397#ifdef HAVE_FACCESSAT
2398 dir_fd_converter, &dir_fd,
2399#else
2400 dir_fd_unavailable, &dir_fd,
2401#endif
2402 &effective_ids, &follow_symlinks))
2403 return NULL;
2404
2405#ifndef HAVE_FACCESSAT
2406 if (follow_symlinks_specified("access", follow_symlinks))
2407 goto exit;
2408
2409 if (effective_ids) {
2410 argument_unavailable_error("access", "effective_ids");
2411 goto exit;
2412 }
2413#endif
2414
2415#ifdef MS_WINDOWS
2416 Py_BEGIN_ALLOW_THREADS
2417 if (path.wide != NULL)
2418 attr = GetFileAttributesW(path.wide);
2419 else
2420 attr = GetFileAttributesA(path.narrow);
2421 Py_END_ALLOW_THREADS
2422
2423 /*
2424 * Access is possible if
2425 * * we didn't get a -1, and
2426 * * write access wasn't requested,
2427 * * or the file isn't read-only,
2428 * * or it's a directory.
2429 * (Directories cannot be read-only on Windows.)
2430 */
2431 return_value = PyBool_FromLong(
2432 (attr != 0xFFFFFFFF) &&
2433 ((mode & 2) ||
2434 !(attr & FILE_ATTRIBUTE_READONLY) ||
2435 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2436#else
2437
2438 Py_BEGIN_ALLOW_THREADS
2439#ifdef HAVE_FACCESSAT
2440 if ((dir_fd != DEFAULT_DIR_FD) ||
2441 effective_ids ||
2442 !follow_symlinks) {
2443 int flags = 0;
2444 if (!follow_symlinks)
2445 flags |= AT_SYMLINK_NOFOLLOW;
2446 if (effective_ids)
2447 flags |= AT_EACCESS;
2448 result = faccessat(dir_fd, path.narrow, mode, flags);
2449 }
2450 else
2451#endif
2452 result = access(path.narrow, mode);
2453 Py_END_ALLOW_THREADS
2454 return_value = PyBool_FromLong(!result);
2455#endif
2456
2457#ifndef HAVE_FACCESSAT
2458exit:
2459#endif
2460 path_cleanup(&path);
2461 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002462}
2463
Guido van Rossumd371ff11999-01-25 16:12:23 +00002464#ifndef F_OK
2465#define F_OK 0
2466#endif
2467#ifndef R_OK
2468#define R_OK 4
2469#endif
2470#ifndef W_OK
2471#define W_OK 2
2472#endif
2473#ifndef X_OK
2474#define X_OK 1
2475#endif
2476
2477#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484{
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 int id;
2486 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2489 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002491#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002492 /* file descriptor 0 only, the default input device (stdin) */
2493 if (id == 0) {
2494 ret = ttyname();
2495 }
2496 else {
2497 ret = NULL;
2498 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (ret == NULL)
2503 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002504 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002508#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002510"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512
2513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002514posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515{
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 char *ret;
2517 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518
Greg Wardb48bc172000-03-01 21:51:56 +00002519#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (ret == NULL)
2525 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002526 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527}
2528#endif
2529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532Change the current working directory to the specified path.\n\
2533\n\
2534path may always be specified as a string.\n\
2535On some platforms, path may also be specified as an open file descriptor.\n\
2536 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 path_t path;
2542 int result;
2543 PyObject *return_value = NULL;
2544 static char *keywords[] = {"path", NULL};
2545
2546 memset(&path, 0, sizeof(path));
2547#ifdef HAVE_FCHDIR
2548 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2551 path_converter, &path
2552 ))
2553 return NULL;
2554
2555 Py_BEGIN_ALLOW_THREADS
2556#ifdef MS_WINDOWS
2557 if (path.wide)
2558 result = win32_wchdir(path.wide);
2559 else
2560 result = win32_chdir(path.narrow);
2561 result = !result; /* on unix, success = 0, on windows, success = !0 */
2562#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2563 result = _chdir2(path.narrow);
2564#else
2565#ifdef HAVE_FCHDIR
2566 if (path.fd != -1)
2567 result = fchdir(path.fd);
2568 else
2569#endif
2570 result = chdir(path.narrow);
2571#endif
2572 Py_END_ALLOW_THREADS
2573
2574 if (result) {
2575 return_value = path_error("chdir", &path);
2576 goto exit;
2577 }
2578
2579 return_value = Py_None;
2580 Py_INCREF(Py_None);
2581
2582exit:
2583 path_cleanup(&path);
2584 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002585}
2586
Fred Drake4d1e64b2002-04-15 19:40:07 +00002587#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589"fchdir(fd)\n\n\
2590Change to the directory of the given file descriptor. fd must be\n\
2591opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002592
2593static PyObject *
2594posix_fchdir(PyObject *self, PyObject *fdobj)
2595{
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002597}
2598#endif /* HAVE_FCHDIR */
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002601PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2603Change the access permissions of a file.\n\
2604\n\
2605path may always be specified as a string.\n\
2606On some platforms, path may also be specified as an open file descriptor.\n\
2607 If this functionality is unavailable, using it raises an exception.\n\
2608If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2609 and path should be relative; path will then be relative to that directory.\n\
2610If follow_symlinks is False, and the last element of the path is a symbolic\n\
2611 link, chmod will modify the symbolic link itself instead of the file the\n\
2612 link points to.\n\
2613It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2614 an open file descriptor.\n\
2615dir_fd and follow_symlinks may not be implemented on your platform.\n\
2616 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002617
Barry Warsaw53699e91996-12-10 23:23:01 +00002618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 path_t path;
2622 int mode;
2623 int dir_fd = DEFAULT_DIR_FD;
2624 int follow_symlinks = 1;
2625 int result;
2626 PyObject *return_value = NULL;
2627 static char *keywords[] = {"path", "mode", "dir_fd",
2628 "follow_symlinks", NULL};
2629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002630#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002633
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634#ifdef HAVE_FCHMODAT
2635 int fchmodat_nofollow_unsupported = 0;
2636#endif
2637
2638 memset(&path, 0, sizeof(path));
2639#ifdef HAVE_FCHMOD
2640 path.allow_fd = 1;
2641#endif
2642 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2643 path_converter, &path,
2644 &mode,
2645#ifdef HAVE_FCHMODAT
2646 dir_fd_converter, &dir_fd,
2647#else
2648 dir_fd_unavailable, &dir_fd,
2649#endif
2650 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002651 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652
2653#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2654 if (follow_symlinks_specified("chmod", follow_symlinks))
2655 goto exit;
2656#endif
2657
2658#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002659 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 if (path.wide)
2661 attr = GetFileAttributesW(path.wide);
2662 else
2663 attr = GetFileAttributesA(path.narrow);
2664 if (attr == 0xFFFFFFFF)
2665 result = 0;
2666 else {
2667 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 attr &= ~FILE_ATTRIBUTE_READONLY;
2669 else
2670 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 if (path.wide)
2672 result = SetFileAttributesW(path.wide, attr);
2673 else
2674 result = SetFileAttributesA(path.narrow, attr);
2675 }
2676 Py_END_ALLOW_THREADS
2677
2678 if (!result) {
2679 return_value = win32_error_object("chmod", path.object);
2680 goto exit;
2681 }
2682#else /* MS_WINDOWS */
2683 Py_BEGIN_ALLOW_THREADS
2684#ifdef HAVE_FCHMOD
2685 if (path.fd != -1)
2686 result = fchmod(path.fd, mode);
2687 else
2688#endif
2689#ifdef HAVE_LCHMOD
2690 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2691 result = lchmod(path.narrow, mode);
2692 else
2693#endif
2694#ifdef HAVE_FCHMODAT
2695 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2696 /*
2697 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2698 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002699 * and then says it isn't implemented yet.
2700 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 *
2702 * Once it is supported, os.chmod will automatically
2703 * support dir_fd and follow_symlinks=False. (Hopefully.)
2704 * Until then, we need to be careful what exception we raise.
2705 */
2706 result = fchmodat(dir_fd, path.narrow, mode,
2707 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2708 /*
2709 * But wait! We can't throw the exception without allowing threads,
2710 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2711 */
2712 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002713 result &&
2714 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2715 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 }
2717 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002718#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719 result = chmod(path.narrow, mode);
2720 Py_END_ALLOW_THREADS
2721
2722 if (result) {
2723#ifdef HAVE_FCHMODAT
2724 if (fchmodat_nofollow_unsupported) {
2725 if (dir_fd != DEFAULT_DIR_FD)
2726 dir_fd_and_follow_symlinks_invalid("chmod",
2727 dir_fd, follow_symlinks);
2728 else
2729 follow_symlinks_specified("chmod", follow_symlinks);
2730 }
2731 else
2732#endif
2733 return_value = path_error("chmod", &path);
2734 goto exit;
2735 }
2736#endif
2737
2738 Py_INCREF(Py_None);
2739 return_value = Py_None;
2740exit:
2741 path_cleanup(&path);
2742 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002743}
2744
Larry Hastings9cf065c2012-06-22 16:30:09 -07002745
Christian Heimes4e30a842007-11-30 22:12:06 +00002746#ifdef HAVE_FCHMOD
2747PyDoc_STRVAR(posix_fchmod__doc__,
2748"fchmod(fd, mode)\n\n\
2749Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002751
2752static PyObject *
2753posix_fchmod(PyObject *self, PyObject *args)
2754{
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 int fd, mode, res;
2756 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2757 return NULL;
2758 Py_BEGIN_ALLOW_THREADS
2759 res = fchmod(fd, mode);
2760 Py_END_ALLOW_THREADS
2761 if (res < 0)
2762 return posix_error();
2763 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002764}
2765#endif /* HAVE_FCHMOD */
2766
2767#ifdef HAVE_LCHMOD
2768PyDoc_STRVAR(posix_lchmod__doc__,
2769"lchmod(path, mode)\n\n\
2770Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771affects the link itself rather than the target.\n\
2772Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002773
2774static PyObject *
2775posix_lchmod(PyObject *self, PyObject *args)
2776{
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 PyObject *opath;
2778 char *path;
2779 int i;
2780 int res;
2781 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2782 &opath, &i))
2783 return NULL;
2784 path = PyBytes_AsString(opath);
2785 Py_BEGIN_ALLOW_THREADS
2786 res = lchmod(path, i);
2787 Py_END_ALLOW_THREADS
2788 if (res < 0)
2789 return posix_error_with_allocated_filename(opath);
2790 Py_DECREF(opath);
2791 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002792}
2793#endif /* HAVE_LCHMOD */
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Thomas Wouterscf297e42007-02-23 15:07:44 +00002796#ifdef HAVE_CHFLAGS
2797PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798"chflags(path, flags, *, follow_symlinks=True)\n\n\
2799Set file flags.\n\
2800\n\
2801If follow_symlinks is False, and the last element of the path is a symbolic\n\
2802 link, chflags will change flags on the symbolic link itself instead of the\n\
2803 file the link points to.\n\
2804follow_symlinks may not be implemented on your platform. If it is\n\
2805unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002806
2807static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002809{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002811 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 int follow_symlinks = 1;
2813 int result;
2814 PyObject *return_value;
2815 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2816
2817 memset(&path, 0, sizeof(path));
2818 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2819 path_converter, &path,
2820 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822
2823#ifndef HAVE_LCHFLAGS
2824 if (follow_symlinks_specified("chflags", follow_symlinks))
2825 goto exit;
2826#endif
2827
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829#ifdef HAVE_LCHFLAGS
2830 if (!follow_symlinks)
2831 result = lchflags(path.narrow, flags);
2832 else
2833#endif
2834 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002835 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836
2837 if (result) {
2838 return_value = path_posix_error("chflags", &path);
2839 goto exit;
2840 }
2841
2842 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844
2845exit:
2846 path_cleanup(&path);
2847 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002848}
2849#endif /* HAVE_CHFLAGS */
2850
2851#ifdef HAVE_LCHFLAGS
2852PyDoc_STRVAR(posix_lchflags__doc__,
2853"lchflags(path, flags)\n\n\
2854Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855This function will not follow symbolic links.\n\
2856Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002857
2858static PyObject *
2859posix_lchflags(PyObject *self, PyObject *args)
2860{
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 PyObject *opath;
2862 char *path;
2863 unsigned long flags;
2864 int res;
2865 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2866 PyUnicode_FSConverter, &opath, &flags))
2867 return NULL;
2868 path = PyBytes_AsString(opath);
2869 Py_BEGIN_ALLOW_THREADS
2870 res = lchflags(path, flags);
2871 Py_END_ALLOW_THREADS
2872 if (res < 0)
2873 return posix_error_with_allocated_filename(opath);
2874 Py_DECREF(opath);
2875 Py_INCREF(Py_None);
2876 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002877}
2878#endif /* HAVE_LCHFLAGS */
2879
Martin v. Löwis244edc82001-10-04 22:44:26 +00002880#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002881PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002882"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002884
2885static PyObject *
2886posix_chroot(PyObject *self, PyObject *args)
2887{
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002889}
2890#endif
2891
Guido van Rossum21142a01999-01-08 21:05:37 +00002892#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002896
2897static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002898posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002899{
Stefan Krah0e803b32010-11-26 16:16:47 +00002900 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002901}
2902#endif /* HAVE_FSYNC */
2903
Ross Lagerwall7807c352011-03-17 20:20:30 +02002904#ifdef HAVE_SYNC
2905PyDoc_STRVAR(posix_sync__doc__,
2906"sync()\n\n\
2907Force write of everything to disk.");
2908
2909static PyObject *
2910posix_sync(PyObject *self, PyObject *noargs)
2911{
2912 Py_BEGIN_ALLOW_THREADS
2913 sync();
2914 Py_END_ALLOW_THREADS
2915 Py_RETURN_NONE;
2916}
2917#endif
2918
Guido van Rossum21142a01999-01-08 21:05:37 +00002919#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002920
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002921#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002922extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2923#endif
2924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002927force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002929
2930static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002931posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002932{
Stefan Krah0e803b32010-11-26 16:16:47 +00002933 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002934}
2935#endif /* HAVE_FDATASYNC */
2936
2937
Fredrik Lundh10723342000-07-10 16:38:09 +00002938#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2941Change the owner and group id of path to the numeric uid and gid.\n\
2942\n\
2943path may always be specified as a string.\n\
2944On some platforms, path may also be specified as an open file descriptor.\n\
2945 If this functionality is unavailable, using it raises an exception.\n\
2946If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2947 and path should be relative; path will then be relative to that directory.\n\
2948If follow_symlinks is False, and the last element of the path is a symbolic\n\
2949 link, chown will modify the symbolic link itself instead of the file the\n\
2950 link points to.\n\
2951It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2952 an open file descriptor.\n\
2953dir_fd and follow_symlinks may not be implemented on your platform.\n\
2954 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002958{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 path_t path;
2960 long uid_l, gid_l;
2961 uid_t uid;
2962 gid_t gid;
2963 int dir_fd = DEFAULT_DIR_FD;
2964 int follow_symlinks = 1;
2965 int result;
2966 PyObject *return_value = NULL;
2967 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2968 "follow_symlinks", NULL};
2969
2970 memset(&path, 0, sizeof(path));
2971#ifdef HAVE_FCHOWN
2972 path.allow_fd = 1;
2973#endif
2974 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2975 path_converter, &path,
2976 &uid_l, &gid_l,
2977#ifdef HAVE_FCHOWNAT
2978 dir_fd_converter, &dir_fd,
2979#else
2980 dir_fd_unavailable, &dir_fd,
2981#endif
2982 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
2985#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2986 if (follow_symlinks_specified("chown", follow_symlinks))
2987 goto exit;
2988#endif
2989 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2990 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2991 goto exit;
2992
2993#ifdef __APPLE__
2994 /*
2995 * This is for Mac OS X 10.3, which doesn't have lchown.
2996 * (But we still have an lchown symbol because of weak-linking.)
2997 * It doesn't have fchownat either. So there's no possibility
2998 * of a graceful failover.
2999 */
3000 if ((!follow_symlinks) && (lchown == NULL)) {
3001 follow_symlinks_specified("chown", follow_symlinks);
3002 goto exit;
3003 }
3004#endif
3005
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007 uid = (uid_t)uid_l;
3008 gid = (uid_t)gid_l;
3009#ifdef HAVE_FCHOWN
3010 if (path.fd != -1)
3011 result = fchown(path.fd, uid, gid);
3012 else
3013#endif
3014#ifdef HAVE_LCHOWN
3015 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3016 result = lchown(path.narrow, uid, gid);
3017 else
3018#endif
3019#ifdef HAVE_FCHOWNAT
3020 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3021 result = fchownat(dir_fd, path.narrow, uid, gid,
3022 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3023 else
3024#endif
3025 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027
3028 if (result) {
3029 return_value = path_posix_error("chown", &path);
3030 goto exit;
3031 }
3032
3033 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035
3036exit:
3037 path_cleanup(&path);
3038 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003039}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003040#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003041
Christian Heimes4e30a842007-11-30 22:12:06 +00003042#ifdef HAVE_FCHOWN
3043PyDoc_STRVAR(posix_fchown__doc__,
3044"fchown(fd, uid, gid)\n\n\
3045Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003047
3048static PyObject *
3049posix_fchown(PyObject *self, PyObject *args)
3050{
Victor Stinner8c62be82010-05-06 00:08:46 +00003051 int fd;
3052 long uid, gid;
3053 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003054 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 return NULL;
3056 Py_BEGIN_ALLOW_THREADS
3057 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3058 Py_END_ALLOW_THREADS
3059 if (res < 0)
3060 return posix_error();
3061 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003062}
3063#endif /* HAVE_FCHOWN */
3064
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003065#ifdef HAVE_LCHOWN
3066PyDoc_STRVAR(posix_lchown__doc__,
3067"lchown(path, uid, gid)\n\n\
3068Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069This function will not follow symbolic links.\n\
3070Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003071
3072static PyObject *
3073posix_lchown(PyObject *self, PyObject *args)
3074{
Victor Stinner8c62be82010-05-06 00:08:46 +00003075 PyObject *opath;
3076 char *path;
3077 long uid, gid;
3078 int res;
3079 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3080 PyUnicode_FSConverter, &opath,
3081 &uid, &gid))
3082 return NULL;
3083 path = PyBytes_AsString(opath);
3084 Py_BEGIN_ALLOW_THREADS
3085 res = lchown(path, (uid_t) uid, (gid_t) gid);
3086 Py_END_ALLOW_THREADS
3087 if (res < 0)
3088 return posix_error_with_allocated_filename(opath);
3089 Py_DECREF(opath);
3090 Py_INCREF(Py_None);
3091 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003092}
3093#endif /* HAVE_LCHOWN */
3094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095
Guido van Rossum36bc6801995-06-14 22:54:23 +00003096#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003097static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003098posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003099{
Victor Stinner8c62be82010-05-06 00:08:46 +00003100 char buf[1026];
3101 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 if (!use_bytes) {
3105 wchar_t wbuf[1026];
3106 wchar_t *wbuf2 = wbuf;
3107 PyObject *resobj;
3108 DWORD len;
3109 Py_BEGIN_ALLOW_THREADS
3110 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3111 /* If the buffer is large enough, len does not include the
3112 terminating \0. If the buffer is too small, len includes
3113 the space needed for the terminator. */
3114 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3115 wbuf2 = malloc(len * sizeof(wchar_t));
3116 if (wbuf2)
3117 len = GetCurrentDirectoryW(len, wbuf2);
3118 }
3119 Py_END_ALLOW_THREADS
3120 if (!wbuf2) {
3121 PyErr_NoMemory();
3122 return NULL;
3123 }
3124 if (!len) {
3125 if (wbuf2 != wbuf) free(wbuf2);
3126 return win32_error("getcwdu", NULL);
3127 }
3128 resobj = PyUnicode_FromWideChar(wbuf2, len);
3129 if (wbuf2 != wbuf) free(wbuf2);
3130 return resobj;
3131 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003132
3133 if (win32_warn_bytes_api())
3134 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135#endif
3136
Victor Stinner8c62be82010-05-06 00:08:46 +00003137 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003138#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003140#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003142#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 Py_END_ALLOW_THREADS
3144 if (res == NULL)
3145 return posix_error();
3146 if (use_bytes)
3147 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003148 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003149}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003150
3151PyDoc_STRVAR(posix_getcwd__doc__,
3152"getcwd() -> path\n\n\
3153Return a unicode string representing the current working directory.");
3154
3155static PyObject *
3156posix_getcwd_unicode(PyObject *self)
3157{
3158 return posix_getcwd(0);
3159}
3160
3161PyDoc_STRVAR(posix_getcwdb__doc__,
3162"getcwdb() -> path\n\n\
3163Return a bytes string representing the current working directory.");
3164
3165static PyObject *
3166posix_getcwd_bytes(PyObject *self)
3167{
3168 return posix_getcwd(1);
3169}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003170#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003171
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3173#define HAVE_LINK 1
3174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3179Create a hard link to a file.\n\
3180\n\
3181If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3182 descriptor open to a directory, and the respective path string (src or dst)\n\
3183 should be relative; the path will then be relative to that directory.\n\
3184If follow_symlinks is False, and the last element of src is a symbolic\n\
3185 link, link will create a link to the symbolic link itself instead of the\n\
3186 file the link points to.\n\
3187src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3188 platform. If they are unavailable, using them will raise a\n\
3189 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Barry Warsaw53699e91996-12-10 23:23:01 +00003191static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003193{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 path_t src, dst;
3195 int src_dir_fd = DEFAULT_DIR_FD;
3196 int dst_dir_fd = DEFAULT_DIR_FD;
3197 int follow_symlinks = 1;
3198 PyObject *return_value = NULL;
3199 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3200 "follow_symlinks", NULL};
3201#ifdef MS_WINDOWS
3202 BOOL result;
3203#else
3204 int result;
3205#endif
3206
3207 memset(&src, 0, sizeof(src));
3208 memset(&dst, 0, sizeof(dst));
3209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3210 path_converter, &src,
3211 path_converter, &dst,
3212 dir_fd_converter, &src_dir_fd,
3213 dir_fd_converter, &dst_dir_fd,
3214 &follow_symlinks))
3215 return NULL;
3216
3217#ifndef HAVE_LINKAT
3218 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3219 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3220 goto exit;
3221 }
3222#endif
3223
3224 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3225 PyErr_SetString(PyExc_NotImplementedError,
3226 "link: src and dst must be the same type");
3227 goto exit;
3228 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003229
Brian Curtin1b9df392010-11-24 20:24:31 +00003230#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231 Py_BEGIN_ALLOW_THREADS
3232 if (src.wide)
3233 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3234 else
3235 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3236 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003237
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 if (!result) {
3239 return_value = win32_error_object("link", dst.object);
3240 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003241 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242#else
3243 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003244#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3246 (dst_dir_fd != DEFAULT_DIR_FD) ||
3247 (!follow_symlinks))
3248 result = linkat(src_dir_fd, src.narrow,
3249 dst_dir_fd, dst.narrow,
3250 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3251 else
3252#endif
3253 result = link(src.narrow, dst.narrow);
3254 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003255
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 if (result) {
3257 return_value = path_error("link", &dst);
3258 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003259 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260#endif
3261
3262 return_value = Py_None;
3263 Py_INCREF(Py_None);
3264
3265exit:
3266 path_cleanup(&src);
3267 path_cleanup(&dst);
3268 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003269}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270#endif
3271
Brian Curtin1b9df392010-11-24 20:24:31 +00003272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003274PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275"listdir(path='.') -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276Return a list containing the names of the entries in the directory.\n\
3277\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279entries '.' and '..' even if they are present in the directory.\n\
3280\n\
3281path can always be specified as a string.\n\
3282On some platforms, path may also be specified as an open file descriptor.\n\
3283 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Barry Warsaw53699e91996-12-10 23:23:01 +00003285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288 path_t path;
3289 PyObject *list = NULL;
3290 static char *keywords[] = {"path", NULL};
3291 int fd = -1;
3292
3293#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3294 PyObject *v;
3295 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3296 BOOL result;
3297 WIN32_FIND_DATA FileData;
3298 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3299 char *bufptr = namebuf;
3300 /* only claim to have space for MAX_PATH */
3301 Py_ssize_t len = sizeof(namebuf)-5;
3302 PyObject *po = NULL;
3303 wchar_t *wnamebuf = NULL;
3304#elif defined(PYOS_OS2)
3305#ifndef MAX_PATH
3306#define MAX_PATH CCHMAXPATH
3307#endif
3308 char *pt;
3309 PyObject *v;
3310 char namebuf[MAX_PATH+5];
3311 HDIR hdir = 1;
3312 ULONG srchcnt = 1;
3313 FILEFINDBUF3 ep;
3314 APIRET rc;
3315#else
3316 PyObject *v;
3317 DIR *dirp = NULL;
3318 struct dirent *ep;
3319 int arg_is_unicode = 1;
3320#endif
3321
3322 memset(&path, 0, sizeof(path));
3323 path.nullable = 1;
3324#ifdef HAVE_FDOPENDIR
3325 path.allow_fd = 1;
3326 path.fd = -1;
3327#endif
3328 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3329 path_converter, &path
3330 ))
3331 return NULL;
3332
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 /* XXX Should redo this putting the (now four) versions of opendir
3334 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003335#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003339
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003341 po_wchars = L".";
3342 len = 1;
3343 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 po_wchars = path.wide;
3345 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3349 if (!wnamebuf) {
3350 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003353 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003355 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (wch != L'/' && wch != L'\\' && wch != L':')
3357 wnamebuf[len++] = L'\\';
3358 wcscpy(wnamebuf + len, L"*.*");
3359 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 if ((list = PyList_New(0)) == NULL) {
3361 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003363 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003365 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 if (hFindFile == INVALID_HANDLE_VALUE) {
3367 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 if (error == ERROR_FILE_NOT_FOUND)
3369 goto exit;
3370 Py_DECREF(list);
3371 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 }
3375 do {
3376 /* Skip over . and .. */
3377 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3378 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 v = PyUnicode_FromWideChar(wFileData.cFileName,
3380 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 Py_DECREF(list);
3383 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 break;
3385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003387 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 Py_DECREF(list);
3389 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 break;
3391 }
3392 Py_DECREF(v);
3393 }
3394 Py_BEGIN_ALLOW_THREADS
3395 result = FindNextFileW(hFindFile, &wFileData);
3396 Py_END_ALLOW_THREADS
3397 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3398 it got to the end of the directory. */
3399 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 Py_DECREF(list);
3401 list = win32_error_unicode("FindNextFileW", wnamebuf);
3402 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 }
3404 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003405
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 strcpy(namebuf, path.narrow);
3409 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 if (len > 0) {
3411 char ch = namebuf[len-1];
3412 if (ch != SEP && ch != ALTSEP && ch != ':')
3413 namebuf[len++] = '/';
3414 strcpy(namebuf + len, "*.*");
3415 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003419
Antoine Pitroub73caab2010-08-09 23:39:31 +00003420 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 if (hFindFile == INVALID_HANDLE_VALUE) {
3424 int error = GetLastError();
3425 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 goto exit;
3427 Py_DECREF(list);
3428 list = win32_error("FindFirstFile", namebuf);
3429 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 }
3431 do {
3432 /* Skip over . and .. */
3433 if (strcmp(FileData.cFileName, ".") != 0 &&
3434 strcmp(FileData.cFileName, "..") != 0) {
3435 v = PyBytes_FromString(FileData.cFileName);
3436 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 Py_DECREF(list);
3438 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 break;
3440 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_DECREF(list);
3444 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 break;
3446 }
3447 Py_DECREF(v);
3448 }
3449 Py_BEGIN_ALLOW_THREADS
3450 result = FindNextFile(hFindFile, &FileData);
3451 Py_END_ALLOW_THREADS
3452 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3453 it got to the end of the directory. */
3454 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_DECREF(list);
3456 list = win32_error("FindNextFile", namebuf);
3457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
3459 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461exit:
3462 if (hFindFile != INVALID_HANDLE_VALUE) {
3463 if (FindClose(hFindFile) == FALSE) {
3464 if (list != NULL) {
3465 Py_DECREF(list);
3466 list = win32_error_object("FindClose", path.object);
3467 }
3468 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 if (wnamebuf)
3471 free(wnamebuf);
3472 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003473
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003475
Tim Peters0bb44a42000-09-15 07:44:49 +00003476#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003478 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003480 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003482 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483 if (*pt == ALTSEP)
3484 *pt = SEP;
3485 if (namebuf[len-1] != SEP)
3486 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487 strcpy(namebuf + len, "*.*");
3488
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 if ((list = PyList_New(0)) == NULL) {
3490 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003491 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003493 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3494 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003495 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003496 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3497 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3498 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499
3500 if (rc != NO_ERROR) {
3501 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = posix_error_with_filename(path.narrow);
3504 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505 }
3506
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003507 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508 do {
3509 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003510 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003511 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512
3513 strcpy(namebuf, ep.achName);
3514
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003515 /* Leave Case of Name Alone -- In Native Form */
3516 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517
Christian Heimes72b710a2008-05-26 13:28:38 +00003518 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522 break;
3523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003528 break;
3529 }
3530 Py_DECREF(v);
3531 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3532 }
3533
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534exit:
3535 path_cleanup(&path);
3536
3537 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003541 /* v is never read, so it does not need to be initialized yet. */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 if (path.narrow && !PyArg_ParseTuple(args, "U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 arg_is_unicode = 0;
3544 PyErr_Clear();
3545 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546#ifdef HAVE_FDOPENDIR
3547 if (path.fd != -1) {
3548 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003549 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003551 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552
3553 if (fd == -1) {
3554 list = posix_error();
3555 goto exit;
3556 }
3557
3558 Py_BEGIN_ALLOW_THREADS
3559 dirp = fdopendir(fd);
3560 Py_END_ALLOW_THREADS
3561 }
3562 else
3563#endif
3564 {
3565 char *name = path.narrow ? path.narrow : ".";
3566 Py_BEGIN_ALLOW_THREADS
3567 dirp = opendir(name);
3568 Py_END_ALLOW_THREADS
3569 }
3570
3571 if (dirp == NULL) {
3572 list = path_error("listdir", &path);
3573 goto exit;
3574 }
3575 if ((list = PyList_New(0)) == NULL) {
3576 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
3578 for (;;) {
3579 errno = 0;
3580 Py_BEGIN_ALLOW_THREADS
3581 ep = readdir(dirp);
3582 Py_END_ALLOW_THREADS
3583 if (ep == NULL) {
3584 if (errno == 0) {
3585 break;
3586 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_DECREF(list);
3588 list = path_error("listdir", &path);
3589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
3591 }
3592 if (ep->d_name[0] == '.' &&
3593 (NAMLEN(ep) == 1 ||
3594 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3595 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00003596 if (arg_is_unicode)
3597 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3598 else
3599 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 break;
3603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 break;
3608 }
3609 Py_DECREF(v);
3610 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612exit:
3613 if (dirp != NULL) {
3614 Py_BEGIN_ALLOW_THREADS
3615 if (fd > -1)
3616 rewinddir(dirp);
3617 closedir(dirp);
3618 Py_END_ALLOW_THREADS
3619 }
3620
3621 path_cleanup(&path);
3622
3623 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003624
Tim Peters0bb44a42000-09-15 07:44:49 +00003625#endif /* which OS */
3626} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003627
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003628#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003629/* A helper function for abspath on win32 */
3630static PyObject *
3631posix__getfullpathname(PyObject *self, PyObject *args)
3632{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003633 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 char outbuf[MAX_PATH*2];
3635 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636 PyObject *po;
3637
3638 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3639 {
3640 wchar_t *wpath;
3641 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3642 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 DWORD result;
3644 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003645
3646 wpath = PyUnicode_AsUnicode(po);
3647 if (wpath == NULL)
3648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003650 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003652 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003653 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 if (!woutbufp)
3655 return PyErr_NoMemory();
3656 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3657 }
3658 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003659 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003661 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 if (woutbufp != woutbuf)
3663 free(woutbufp);
3664 return v;
3665 }
3666 /* Drop the argument parsing error as narrow strings
3667 are also valid. */
3668 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003669
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003670 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3671 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003673 if (win32_warn_bytes_api())
3674 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003675 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 outbuf, &temp)) {
3677 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 return NULL;
3679 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3681 return PyUnicode_Decode(outbuf, strlen(outbuf),
3682 Py_FileSystemDefaultEncoding, NULL);
3683 }
3684 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003685} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
Brian Curtind25aef52011-06-13 15:16:04 -05003687
Brian Curtinf5e76d02010-11-24 13:14:05 +00003688
Brian Curtind40e6f72010-07-08 21:39:08 +00003689/* A helper function for samepath on windows */
3690static PyObject *
3691posix__getfinalpathname(PyObject *self, PyObject *args)
3692{
3693 HANDLE hFile;
3694 int buf_size;
3695 wchar_t *target_path;
3696 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003697 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003698 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003699
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003701 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003702 path = PyUnicode_AsUnicode(po);
3703 if (path == NULL)
3704 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003705
3706 if(!check_GetFinalPathNameByHandle()) {
3707 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3708 NotImplementedError. */
3709 return PyErr_Format(PyExc_NotImplementedError,
3710 "GetFinalPathNameByHandle not available on this platform");
3711 }
3712
3713 hFile = CreateFileW(
3714 path,
3715 0, /* desired access */
3716 0, /* share mode */
3717 NULL, /* security attributes */
3718 OPEN_EXISTING,
3719 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3720 FILE_FLAG_BACKUP_SEMANTICS,
3721 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003722
Victor Stinnereb5657a2011-09-30 01:44:27 +02003723 if(hFile == INVALID_HANDLE_VALUE)
3724 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003725
3726 /* We have a good handle to the target, use it to determine the
3727 target path name. */
3728 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3729
3730 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003732
3733 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3734 if(!target_path)
3735 return PyErr_NoMemory();
3736
3737 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3738 buf_size, VOLUME_NAME_DOS);
3739 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
3742 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003746 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003747 free(target_path);
3748 return result;
3749
3750} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003751
3752static PyObject *
3753posix__getfileinformation(PyObject *self, PyObject *args)
3754{
3755 HANDLE hFile;
3756 BY_HANDLE_FILE_INFORMATION info;
3757 int fd;
3758
3759 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3760 return NULL;
3761
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003762 if (!_PyVerify_fd(fd))
3763 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003764
3765 hFile = (HANDLE)_get_osfhandle(fd);
3766 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003767 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003768
3769 if (!GetFileInformationByHandle(hFile, &info))
3770 return win32_error("_getfileinformation", NULL);
3771
3772 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3773 info.nFileIndexHigh,
3774 info.nFileIndexLow);
3775}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003776
Brian Curtin95d028f2011-06-09 09:10:38 -05003777PyDoc_STRVAR(posix__isdir__doc__,
3778"Return true if the pathname refers to an existing directory.");
3779
Brian Curtin9c669cc2011-06-08 18:17:18 -05003780static PyObject *
3781posix__isdir(PyObject *self, PyObject *args)
3782{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003783 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003784 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003785 DWORD attributes;
3786
3787 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003788 wchar_t *wpath = PyUnicode_AsUnicode(po);
3789 if (wpath == NULL)
3790 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003791
3792 attributes = GetFileAttributesW(wpath);
3793 if (attributes == INVALID_FILE_ATTRIBUTES)
3794 Py_RETURN_FALSE;
3795 goto check;
3796 }
3797 /* Drop the argument parsing error as narrow strings
3798 are also valid. */
3799 PyErr_Clear();
3800
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003801 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003802 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003803 if (win32_warn_bytes_api())
3804 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003805 attributes = GetFileAttributesA(path);
3806 if (attributes == INVALID_FILE_ATTRIBUTES)
3807 Py_RETURN_FALSE;
3808
3809check:
3810 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3811 Py_RETURN_TRUE;
3812 else
3813 Py_RETURN_FALSE;
3814}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003815#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003817PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003818"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3819Create a directory.\n\
3820\n\
3821If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3822 and path should be relative; path will then be relative to that directory.\n\
3823dir_fd may not be implemented on your platform.\n\
3824 If it is unavailable, using it will raise a NotImplementedError.\n\
3825\n\
3826The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003827
Barry Warsaw53699e91996-12-10 23:23:01 +00003828static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003830{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003833 int dir_fd = DEFAULT_DIR_FD;
3834 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3835 PyObject *return_value = NULL;
3836 int result;
3837
3838 memset(&path, 0, sizeof(path));
3839 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3840 path_converter, &path, &mode,
3841#ifdef HAVE_MKDIRAT
3842 dir_fd_converter, &dir_fd
3843#else
3844 dir_fd_unavailable, &dir_fd
3845#endif
3846 ))
3847 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003848
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003849#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851 if (path.wide)
3852 result = CreateDirectoryW(path.wide, NULL);
3853 else
3854 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003856
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 if (!result) {
3858 return_value = win32_error_object("mkdir", path.object);
3859 goto exit;
3860 }
3861#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863#if HAVE_MKDIRAT
3864 if (dir_fd != DEFAULT_DIR_FD)
3865 result = mkdirat(dir_fd, path.narrow, mode);
3866 else
3867#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003868#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003870#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003874 if (result < 0) {
3875 return_value = path_error("mkdir", &path);
3876 goto exit;
3877 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 return_value = Py_None;
3880 Py_INCREF(Py_None);
3881exit:
3882 path_cleanup(&path);
3883 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003884}
3885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003887/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3888#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003889#include <sys/resource.h>
3890#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003892
3893#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003894PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003895"nice(inc) -> new_priority\n\n\
3896Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Barry Warsaw53699e91996-12-10 23:23:01 +00003898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003899posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003900{
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003902
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3904 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003905
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 /* There are two flavours of 'nice': one that returns the new
3907 priority (as required by almost all standards out there) and the
3908 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3909 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003910
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 If we are of the nice family that returns the new priority, we
3912 need to clear errno before the call, and check if errno is filled
3913 before calling posix_error() on a returnvalue of -1, because the
3914 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003915
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 errno = 0;
3917 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003918#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 if (value == 0)
3920 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (value == -1 && errno != 0)
3923 /* either nice() or getpriority() returned an error */
3924 return posix_error();
3925 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003927#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003928
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003929
3930#ifdef HAVE_GETPRIORITY
3931PyDoc_STRVAR(posix_getpriority__doc__,
3932"getpriority(which, who) -> current_priority\n\n\
3933Get program scheduling priority.");
3934
3935static PyObject *
3936posix_getpriority(PyObject *self, PyObject *args)
3937{
3938 int which, who, retval;
3939
3940 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3941 return NULL;
3942 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944 if (errno != 0)
3945 return posix_error();
3946 return PyLong_FromLong((long)retval);
3947}
3948#endif /* HAVE_GETPRIORITY */
3949
3950
3951#ifdef HAVE_SETPRIORITY
3952PyDoc_STRVAR(posix_setpriority__doc__,
3953"setpriority(which, who, prio) -> None\n\n\
3954Set program scheduling priority.");
3955
3956static PyObject *
3957posix_setpriority(PyObject *self, PyObject *args)
3958{
3959 int which, who, prio, retval;
3960
3961 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3962 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003964 if (retval == -1)
3965 return posix_error();
3966 Py_RETURN_NONE;
3967}
3968#endif /* HAVE_SETPRIORITY */
3969
3970
Barry Warsaw53699e91996-12-10 23:23:01 +00003971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 char *function_name = is_replace ? "replace" : "rename";
3975 path_t src;
3976 path_t dst;
3977 int src_dir_fd = DEFAULT_DIR_FD;
3978 int dst_dir_fd = DEFAULT_DIR_FD;
3979 int dir_fd_specified;
3980 PyObject *return_value = NULL;
3981 char format[24];
3982 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3983
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003985 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003986 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003987#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003988 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990
3991 memset(&src, 0, sizeof(src));
3992 memset(&dst, 0, sizeof(dst));
3993 strcpy(format, "O&O&|$O&O&:");
3994 strcat(format, function_name);
3995 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3996 path_converter, &src,
3997 path_converter, &dst,
3998 dir_fd_converter, &src_dir_fd,
3999 dir_fd_converter, &dst_dir_fd))
4000 return NULL;
4001
4002 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4003 (dst_dir_fd != DEFAULT_DIR_FD);
4004#ifndef HAVE_RENAMEAT
4005 if (dir_fd_specified) {
4006 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4007 goto exit;
4008 }
4009#endif
4010
4011 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4012 PyErr_Format(PyExc_ValueError,
4013 "%s: src and dst must be the same type", function_name);
4014 goto exit;
4015 }
4016
4017#ifdef MS_WINDOWS
4018 Py_BEGIN_ALLOW_THREADS
4019 if (src.wide)
4020 result = MoveFileExW(src.wide, dst.wide, flags);
4021 else
4022 result = MoveFileExA(src.narrow, dst.narrow, flags);
4023 Py_END_ALLOW_THREADS
4024
4025 if (!result) {
4026 return_value = win32_error_object(function_name, dst.object);
4027 goto exit;
4028 }
4029
4030#else
4031 Py_BEGIN_ALLOW_THREADS
4032#ifdef HAVE_RENAMEAT
4033 if (dir_fd_specified)
4034 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4035 else
4036#endif
4037 result = rename(src.narrow, dst.narrow);
4038 Py_END_ALLOW_THREADS
4039
4040 if (result) {
4041 return_value = path_error(function_name, &dst);
4042 goto exit;
4043 }
4044#endif
4045
4046 Py_INCREF(Py_None);
4047 return_value = Py_None;
4048exit:
4049 path_cleanup(&src);
4050 path_cleanup(&dst);
4051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004052}
4053
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004054PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4056Rename a file or directory.\n\
4057\n\
4058If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4059 descriptor open to a directory, and the respective path string (src or dst)\n\
4060 should be relative; the path will then be relative to that directory.\n\
4061src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4062 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004063
4064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004068}
4069
4070PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4072Rename a file or directory, overwriting the destination.\n\
4073\n\
4074If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4075 descriptor open to a directory, and the respective path string (src or dst)\n\
4076 should be relative; the path will then be relative to that directory.\n\
4077src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4078 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004079
4080static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004082{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004084}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004087"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004091posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004093#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004094 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004095#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004096 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004097#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004098}
4099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004100
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004101#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004103"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004105
Barry Warsaw53699e91996-12-10 23:23:01 +00004106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004107posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004108{
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004110#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004111 wchar_t *command;
4112 if (!PyArg_ParseTuple(args, "u:system", &command))
4113 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004114
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 Py_BEGIN_ALLOW_THREADS
4116 sts = _wsystem(command);
4117 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004118#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 PyObject *command_obj;
4120 char *command;
4121 if (!PyArg_ParseTuple(args, "O&:system",
4122 PyUnicode_FSConverter, &command_obj))
4123 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004124
Victor Stinner8c62be82010-05-06 00:08:46 +00004125 command = PyBytes_AsString(command_obj);
4126 Py_BEGIN_ALLOW_THREADS
4127 sts = system(command);
4128 Py_END_ALLOW_THREADS
4129 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004130#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004132}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004133#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004136PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004137"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004139
Barry Warsaw53699e91996-12-10 23:23:01 +00004140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004141posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004142{
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 int i;
4144 if (!PyArg_ParseTuple(args, "i:umask", &i))
4145 return NULL;
4146 i = (int)umask(i);
4147 if (i < 0)
4148 return posix_error();
4149 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004150}
4151
Brian Curtind40e6f72010-07-08 21:39:08 +00004152#ifdef MS_WINDOWS
4153
4154/* override the default DeleteFileW behavior so that directory
4155symlinks can be removed with this function, the same as with
4156Unix symlinks */
4157BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4158{
4159 WIN32_FILE_ATTRIBUTE_DATA info;
4160 WIN32_FIND_DATAW find_data;
4161 HANDLE find_data_handle;
4162 int is_directory = 0;
4163 int is_link = 0;
4164
4165 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4166 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004167
Brian Curtind40e6f72010-07-08 21:39:08 +00004168 /* Get WIN32_FIND_DATA structure for the path to determine if
4169 it is a symlink */
4170 if(is_directory &&
4171 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4172 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4173
4174 if(find_data_handle != INVALID_HANDLE_VALUE) {
4175 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4176 FindClose(find_data_handle);
4177 }
4178 }
4179 }
4180
4181 if (is_directory && is_link)
4182 return RemoveDirectoryW(lpFileName);
4183
4184 return DeleteFileW(lpFileName);
4185}
4186#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004188PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004189"unlink(path, *, dir_fd=None, rmdir=False)\n\n\
4190Remove a file (same as remove()).\n\
4191\n\
4192If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4193 and path should be relative; path will then be relative to that directory.\n\
4194dir_fd may not be implemented on your platform.\n\
4195 If it is unavailable, using it will raise a NotImplementedError.\n\
4196If rmdir is True, unlink will behave like os.rmdir().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004198PyDoc_STRVAR(posix_remove__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004199"remove(path, *, dir_fd=None, rmdir=False)\n\n\
4200Remove a file (same as unlink()).\n\
4201\n\
4202If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4203 and path should be relative; path will then be relative to that directory.\n\
4204dir_fd may not be implemented on your platform.\n\
4205 If it is unavailable, using it will raise a NotImplementedError.\n\
4206If rmdir is True, remove will behave like os.rmdir().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Barry Warsaw53699e91996-12-10 23:23:01 +00004208static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004209posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004210{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004211 path_t path;
4212 int dir_fd = DEFAULT_DIR_FD;
4213 int remove_dir = 0;
4214 static char *keywords[] = {"path", "dir_fd", "rmdir", NULL};
4215 int result;
4216 PyObject *return_value = NULL;
4217
4218 memset(&path, 0, sizeof(path));
4219 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:unlink", keywords,
4220 path_converter, &path,
4221#ifdef HAVE_UNLINKAT
4222 dir_fd_converter, &dir_fd,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004223#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004224 dir_fd_unavailable, &dir_fd,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004225#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004226 &remove_dir))
4227 return NULL;
4228
4229 Py_BEGIN_ALLOW_THREADS
4230#ifdef MS_WINDOWS
4231 if (remove_dir) {
4232 if (path.wide)
4233 result = RemoveDirectoryW(path.wide);
4234 else
4235 result = RemoveDirectoryA(path.narrow);
4236 }
4237 else {
4238 if (path.wide)
4239 result = Py_DeleteFileW(path.wide);
4240 else
4241 result = DeleteFileA(path.narrow);
4242 }
4243 result = !result; /* Windows, success=1, UNIX, success=0 */
4244#else
4245 if (remove_dir && (dir_fd == DEFAULT_DIR_FD))
4246 result = rmdir(path.narrow);
4247 else
4248#ifdef HAVE_UNLINKAT
4249 if (dir_fd != DEFAULT_DIR_FD)
4250 result = unlinkat(dir_fd, path.narrow, remove_dir ? AT_REMOVEDIR : 0);
4251 else
4252#endif /* HAVE_UNLINKAT */
4253 result = unlink(path.narrow);
4254#endif
4255 Py_END_ALLOW_THREADS
4256
4257 if (result) {
4258 return_value = path_error("unlink", &path);
4259 goto exit;
4260 }
4261
4262 return_value = Py_None;
4263 Py_INCREF(Py_None);
4264
4265exit:
4266 path_cleanup(&path);
4267 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004268}
4269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004270
Guido van Rossumb6775db1994-08-01 11:34:53 +00004271#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004272PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004273"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004274Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Barry Warsaw53699e91996-12-10 23:23:01 +00004276static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004277posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004278{
Victor Stinner8c62be82010-05-06 00:08:46 +00004279 struct utsname u;
4280 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00004281
Victor Stinner8c62be82010-05-06 00:08:46 +00004282 Py_BEGIN_ALLOW_THREADS
4283 res = uname(&u);
4284 Py_END_ALLOW_THREADS
4285 if (res < 0)
4286 return posix_error();
4287 return Py_BuildValue("(sssss)",
4288 u.sysname,
4289 u.nodename,
4290 u.release,
4291 u.version,
4292 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004293}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004294#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004295
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004296
Larry Hastings9cf065c2012-06-22 16:30:09 -07004297PyDoc_STRVAR(posix_utime__doc__,
4298"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4299Set the access and modified time of path.\n\
4300\n\
4301path may always be specified as a string.\n\
4302On some platforms, path may also be specified as an open file descriptor.\n\
4303 If this functionality is unavailable, using it raises an exception.\n\
4304\n\
4305If times is not None, it must be a tuple (atime, mtime);\n\
4306 atime and mtime should be expressed as float seconds since the epoch.\n\
4307If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4308 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4309 since the epoch.\n\
4310If both times and ns are None, utime uses the current time.\n\
4311Specifying tuples for both times and ns is an error.\n\
4312\n\
4313If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4314 and path should be relative; path will then be relative to that directory.\n\
4315If follow_symlinks is False, and the last element of the path is a symbolic\n\
4316 link, utime will modify the symbolic link itself instead of the file the\n\
4317 link points to.\n\
4318It is an error to use dir_fd or follow_symlinks when specifying path\n\
4319 as an open file descriptor.\n\
4320dir_fd and follow_symlinks may not be available on your platform.\n\
4321 If they are unavailable, using them will raise a NotImplementedError.");
4322
4323typedef struct {
4324 int now;
4325 time_t atime_s;
4326 long atime_ns;
4327 time_t mtime_s;
4328 long mtime_ns;
4329} utime_t;
4330
4331/*
4332 * these macros assume that "utime" is a pointer to a utime_t
4333 * they also intentionally leak the declaration of a pointer named "time"
4334 */
4335#define UTIME_TO_TIMESPEC \
4336 struct timespec ts[2]; \
4337 struct timespec *time; \
4338 if (utime->now) \
4339 time = NULL; \
4340 else { \
4341 ts[0].tv_sec = utime->atime_s; \
4342 ts[0].tv_nsec = utime->atime_ns; \
4343 ts[1].tv_sec = utime->mtime_s; \
4344 ts[1].tv_nsec = utime->mtime_ns; \
4345 time = ts; \
4346 } \
4347
4348#define UTIME_TO_TIMEVAL \
4349 struct timeval tv[2]; \
4350 struct timeval *time; \
4351 if (utime->now) \
4352 time = NULL; \
4353 else { \
4354 tv[0].tv_sec = utime->atime_s; \
4355 tv[0].tv_usec = utime->atime_ns / 1000; \
4356 tv[1].tv_sec = utime->mtime_s; \
4357 tv[1].tv_usec = utime->mtime_ns / 1000; \
4358 time = tv; \
4359 } \
4360
4361#define UTIME_TO_UTIMBUF \
4362 struct utimbuf u[2]; \
4363 struct utimbuf *time; \
4364 if (utime->now) \
4365 time = NULL; \
4366 else { \
4367 u.actime = utime->atime_s; \
4368 u.modtime = utime->mtime_s; \
4369 time = u; \
4370 }
4371
4372#define UTIME_TO_TIME_T \
4373 time_t timet[2]; \
4374 struct timet time; \
4375 if (utime->now) \
4376 time = NULL; \
4377 else { \
4378 timet[0] = utime->atime_s; \
4379 timet[1] = utime->mtime_s; \
4380 time = &timet; \
4381 } \
4382
4383
4384#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4385
4386#if UTIME_HAVE_DIR_FD
4387
4388static int
4389utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4390{
4391#ifdef HAVE_UTIMENSAT
4392 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4393 UTIME_TO_TIMESPEC;
4394 return utimensat(dir_fd, path, time, flags);
4395#elif defined(HAVE_FUTIMESAT)
4396 UTIME_TO_TIMEVAL;
4397 /*
4398 * follow_symlinks will never be false here;
4399 * we only allow !follow_symlinks and dir_fd together
4400 * if we have utimensat()
4401 */
4402 assert(follow_symlinks);
4403 return futimesat(dir_fd, path, time);
4404#endif
4405}
4406
4407#endif
4408
4409#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4410
4411#if UTIME_HAVE_FD
4412
4413static int
4414utime_fd(utime_t *utime, int fd)
4415{
4416#ifdef HAVE_FUTIMENS
4417 UTIME_TO_TIMESPEC;
4418 return futimens(fd, time);
4419#else
4420 UTIME_TO_TIMEVAL;
4421 return futimes(fd, time);
4422#endif
4423}
4424
4425#endif
4426
4427
4428#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4429 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4430
4431#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4432
4433static int
4434utime_nofollow_symlinks(utime_t *utime, char *path)
4435{
4436#ifdef HAVE_UTIMENSAT
4437 UTIME_TO_TIMESPEC;
4438 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4439#else
4440 UTIME_TO_TIMEVAL;
4441 return lutimes(path, time);
4442#endif
4443}
4444
4445#endif
4446
4447#ifndef MS_WINDOWS
4448
4449static int
4450utime_default(utime_t *utime, char *path)
4451{
4452#ifdef HAVE_UTIMENSAT
4453 UTIME_TO_TIMESPEC;
4454 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4455#elif defined(HAVE_UTIMES)
4456 UTIME_TO_TIMEVAL;
4457 return utimes(path, time);
4458#elif defined(HAVE_UTIME_H)
4459 UTIME_TO_UTIMBUF;
4460 return utime(path, time);
4461#else
4462 UTIME_TO_TIME_T;
4463 return utime(path, time);
4464#endif
4465}
4466
4467#endif
4468
Larry Hastings76ad59b2012-05-03 00:30:07 -07004469static int
4470split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4471{
4472 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004473 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004474 divmod = PyNumber_Divmod(py_long, billion);
4475 if (!divmod)
4476 goto exit;
4477 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4478 if ((*s == -1) && PyErr_Occurred())
4479 goto exit;
4480 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004481 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004482 goto exit;
4483
4484 result = 1;
4485exit:
4486 Py_XDECREF(divmod);
4487 return result;
4488}
4489
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490static PyObject *
4491posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004492{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004493 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004494 PyObject *times = NULL;
4495 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496 int dir_fd = DEFAULT_DIR_FD;
4497 int follow_symlinks = 1;
4498 char *keywords[] = {"path", "times", "ns", "dir_fd",
4499 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004500
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004502
Larry Hastings9cf065c2012-06-22 16:30:09 -07004503#ifdef MS_WINDOWS
4504 HANDLE hFile;
4505 FILETIME atime, mtime;
4506#else
4507 int result;
4508#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004509
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004511
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 memset(&path, 0, sizeof(path));
4513#if UTIME_HAVE_FD
4514 path.allow_fd = 1;
4515#endif
4516 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4517 "O&|O$OO&p:utime", keywords,
4518 path_converter, &path,
4519 &times, &ns,
4520#if UTIME_HAVE_DIR_FD
4521 dir_fd_converter, &dir_fd,
4522#else
4523 dir_fd_unavailable, &dir_fd,
4524#endif
4525 &follow_symlinks
4526 ))
4527 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004528
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 if (times && (times != Py_None) && ns) {
4530 PyErr_SetString(PyExc_ValueError,
4531 "utime: you may specify either 'times'"
4532 " or 'ns' but not both");
4533 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004534 }
4535
4536 if (times && (times != Py_None)) {
4537 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 PyErr_SetString(PyExc_TypeError,
4539 "utime: 'times' must be either"
4540 " a tuple of two ints or None");
4541 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004542 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004544 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004546 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547 &utime.mtime_s, &utime.mtime_ns) == -1) {
4548 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004549 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004550 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004552 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 PyErr_SetString(PyExc_TypeError,
4554 "utime: 'ns' must be a tuple of two ints");
4555 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004556 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004558 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004560 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561 &utime.mtime_s, &utime.mtime_ns)) {
4562 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004563 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564 }
4565 else {
4566 /* times and ns are both None/unspecified. use "now". */
4567 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004568 }
4569
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4571 if (follow_symlinks_specified("utime", follow_symlinks))
4572 goto exit;
4573#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004574
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4576 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4577 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4578 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004579
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580#if !defined(HAVE_UTIMENSAT)
4581 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
4582 PyErr_SetString(PyExc_RuntimeError,
4583 "utime: cannot use dir_fd and follow_symlinks "
4584 "together on this platform");
4585 goto exit;
4586 }
4587#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004589#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 Py_BEGIN_ALLOW_THREADS
4591 if (path.wide)
4592 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 NULL, OPEN_EXISTING,
4594 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 else
4596 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004597 NULL, OPEN_EXISTING,
4598 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 Py_END_ALLOW_THREADS
4600 if (hFile == INVALID_HANDLE_VALUE) {
4601 win32_error_object("utime", path.object);
4602 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004603 }
4604
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 SYSTEMTIME now;
4607 GetSystemTime(&now);
4608 if (!SystemTimeToFileTime(&now, &mtime) ||
4609 !SystemTimeToFileTime(&now, &atime)) {
4610 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004612 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004613 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004614 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4616 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004617 }
4618 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4619 /* Avoid putting the file name into the error here,
4620 as that may confuse the user into believing that
4621 something is wrong with the file, when it also
4622 could be the time stamp that gives a problem. */
4623 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004625 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004626#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004628
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4630 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4631 result = utime_nofollow_symlinks(&utime, path.narrow);
4632 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004633#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634
4635#if UTIME_HAVE_DIR_FD
4636 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4637 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4638 else
4639#endif
4640
4641#if UTIME_HAVE_FD
4642 if (path.fd != -1)
4643 result = utime_fd(&utime, path.fd);
4644 else
4645#endif
4646
4647 result = utime_default(&utime, path.narrow);
4648
4649 Py_END_ALLOW_THREADS
4650
4651 if (result < 0) {
4652 /* see previous comment about not putting filename in error here */
4653 return_value = posix_error();
4654 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004655 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004657#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658
4659 Py_INCREF(Py_None);
4660 return_value = Py_None;
4661
4662exit:
4663 path_cleanup(&path);
4664#ifdef MS_WINDOWS
4665 if (hFile != INVALID_HANDLE_VALUE)
4666 CloseHandle(hFile);
4667#endif
4668 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004669}
4670
Guido van Rossum3b066191991-06-04 19:40:25 +00004671/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004674"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004675Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004676
Barry Warsaw53699e91996-12-10 23:23:01 +00004677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004678posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004679{
Victor Stinner8c62be82010-05-06 00:08:46 +00004680 int sts;
4681 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4682 return NULL;
4683 _exit(sts);
4684 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004685}
4686
Martin v. Löwis114619e2002-10-07 06:44:21 +00004687#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4688static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004689free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004690{
Victor Stinner8c62be82010-05-06 00:08:46 +00004691 Py_ssize_t i;
4692 for (i = 0; i < count; i++)
4693 PyMem_Free(array[i]);
4694 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004695}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004696
Antoine Pitrou69f71142009-05-24 21:25:49 +00004697static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004698int fsconvert_strdup(PyObject *o, char**out)
4699{
Victor Stinner8c62be82010-05-06 00:08:46 +00004700 PyObject *bytes;
4701 Py_ssize_t size;
4702 if (!PyUnicode_FSConverter(o, &bytes))
4703 return 0;
4704 size = PyBytes_GET_SIZE(bytes);
4705 *out = PyMem_Malloc(size+1);
4706 if (!*out)
4707 return 0;
4708 memcpy(*out, PyBytes_AsString(bytes), size+1);
4709 Py_DECREF(bytes);
4710 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004711}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004712#endif
4713
Ross Lagerwall7807c352011-03-17 20:20:30 +02004714#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004715static char**
4716parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4717{
Victor Stinner8c62be82010-05-06 00:08:46 +00004718 char **envlist;
4719 Py_ssize_t i, pos, envc;
4720 PyObject *keys=NULL, *vals=NULL;
4721 PyObject *key, *val, *key2, *val2;
4722 char *p, *k, *v;
4723 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004724
Victor Stinner8c62be82010-05-06 00:08:46 +00004725 i = PyMapping_Size(env);
4726 if (i < 0)
4727 return NULL;
4728 envlist = PyMem_NEW(char *, i + 1);
4729 if (envlist == NULL) {
4730 PyErr_NoMemory();
4731 return NULL;
4732 }
4733 envc = 0;
4734 keys = PyMapping_Keys(env);
4735 vals = PyMapping_Values(env);
4736 if (!keys || !vals)
4737 goto error;
4738 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4739 PyErr_Format(PyExc_TypeError,
4740 "env.keys() or env.values() is not a list");
4741 goto error;
4742 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004743
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 for (pos = 0; pos < i; pos++) {
4745 key = PyList_GetItem(keys, pos);
4746 val = PyList_GetItem(vals, pos);
4747 if (!key || !val)
4748 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004749
Victor Stinner8c62be82010-05-06 00:08:46 +00004750 if (PyUnicode_FSConverter(key, &key2) == 0)
4751 goto error;
4752 if (PyUnicode_FSConverter(val, &val2) == 0) {
4753 Py_DECREF(key2);
4754 goto error;
4755 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004756
4757#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4759 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004760#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 k = PyBytes_AsString(key2);
4762 v = PyBytes_AsString(val2);
4763 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004764
Victor Stinner8c62be82010-05-06 00:08:46 +00004765 p = PyMem_NEW(char, len);
4766 if (p == NULL) {
4767 PyErr_NoMemory();
4768 Py_DECREF(key2);
4769 Py_DECREF(val2);
4770 goto error;
4771 }
4772 PyOS_snprintf(p, len, "%s=%s", k, v);
4773 envlist[envc++] = p;
4774 Py_DECREF(key2);
4775 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004776#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004777 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 }
4780 Py_DECREF(vals);
4781 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004782
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 envlist[envc] = 0;
4784 *envc_ptr = envc;
4785 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004786
4787error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 Py_XDECREF(keys);
4789 Py_XDECREF(vals);
4790 while (--envc >= 0)
4791 PyMem_DEL(envlist[envc]);
4792 PyMem_DEL(envlist);
4793 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004794}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004795
Ross Lagerwall7807c352011-03-17 20:20:30 +02004796static char**
4797parse_arglist(PyObject* argv, Py_ssize_t *argc)
4798{
4799 int i;
4800 char **argvlist = PyMem_NEW(char *, *argc+1);
4801 if (argvlist == NULL) {
4802 PyErr_NoMemory();
4803 return NULL;
4804 }
4805 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004806 PyObject* item = PySequence_ITEM(argv, i);
4807 if (item == NULL)
4808 goto fail;
4809 if (!fsconvert_strdup(item, &argvlist[i])) {
4810 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004811 goto fail;
4812 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004813 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004814 }
4815 argvlist[*argc] = NULL;
4816 return argvlist;
4817fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004818 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004819 free_string_array(argvlist, *argc);
4820 return NULL;
4821}
4822#endif
4823
4824#ifdef HAVE_EXECV
4825PyDoc_STRVAR(posix_execv__doc__,
4826"execv(path, args)\n\n\
4827Execute an executable path with arguments, replacing current process.\n\
4828\n\
4829 path: path of executable file\n\
4830 args: tuple or list of strings");
4831
4832static PyObject *
4833posix_execv(PyObject *self, PyObject *args)
4834{
4835 PyObject *opath;
4836 char *path;
4837 PyObject *argv;
4838 char **argvlist;
4839 Py_ssize_t argc;
4840
4841 /* execv has two arguments: (path, argv), where
4842 argv is a list or tuple of strings. */
4843
4844 if (!PyArg_ParseTuple(args, "O&O:execv",
4845 PyUnicode_FSConverter,
4846 &opath, &argv))
4847 return NULL;
4848 path = PyBytes_AsString(opath);
4849 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4850 PyErr_SetString(PyExc_TypeError,
4851 "execv() arg 2 must be a tuple or list");
4852 Py_DECREF(opath);
4853 return NULL;
4854 }
4855 argc = PySequence_Size(argv);
4856 if (argc < 1) {
4857 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4858 Py_DECREF(opath);
4859 return NULL;
4860 }
4861
4862 argvlist = parse_arglist(argv, &argc);
4863 if (argvlist == NULL) {
4864 Py_DECREF(opath);
4865 return NULL;
4866 }
4867
4868 execv(path, argvlist);
4869
4870 /* If we get here it's definitely an error */
4871
4872 free_string_array(argvlist, argc);
4873 Py_DECREF(opath);
4874 return posix_error();
4875}
4876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004877PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004878"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004879Execute a path with arguments and environment, replacing current process.\n\
4880\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 path: path of executable file\n\
4882 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 env: dictionary of strings mapping to strings\n\
4884\n\
4885On some platforms, you may specify an open file descriptor for path;\n\
4886 execve will execute the program the file descriptor is open to.\n\
4887 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004891{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004893 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004895 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004896 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 /* execve has three arguments: (path, argv, env), where
4900 argv is a list or tuple of strings and env is a dictionary
4901 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004902
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903 memset(&path, 0, sizeof(path));
4904#ifdef HAVE_FEXECVE
4905 path.allow_fd = 1;
4906#endif
4907 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4908 path_converter, &path,
4909 &argv, &env
4910 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912
Ross Lagerwall7807c352011-03-17 20:20:30 +02004913 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004915 "execve: argv must be a tuple or list");
4916 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004917 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004918 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 if (!PyMapping_Check(env)) {
4920 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921 "execve: environment must be a mapping object");
4922 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004924
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 envlist = parse_envlist(env, &envc);
4931 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004932 goto fail;
4933
Larry Hastings9cf065c2012-06-22 16:30:09 -07004934#ifdef HAVE_FEXECVE
4935 if (path.fd > -1)
4936 fexecve(path.fd, argvlist, envlist);
4937 else
4938#endif
4939 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004940
4941 /* If we get here it's definitely an error */
4942
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944
4945 while (--envc >= 0)
4946 PyMem_DEL(envlist[envc]);
4947 PyMem_DEL(envlist);
4948 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 if (argvlist)
4950 free_string_array(argvlist, argc);
4951 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004952 return NULL;
4953}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004954#endif /* HAVE_EXECV */
4955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Guido van Rossuma1065681999-01-25 23:20:23 +00004957#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004960Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004961\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 mode: mode of process creation\n\
4963 path: path of executable file\n\
4964 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004965
4966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004967posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004968{
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 PyObject *opath;
4970 char *path;
4971 PyObject *argv;
4972 char **argvlist;
4973 int mode, i;
4974 Py_ssize_t argc;
4975 Py_intptr_t spawnval;
4976 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 /* spawnv has three arguments: (mode, path, argv), where
4979 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4982 PyUnicode_FSConverter,
4983 &opath, &argv))
4984 return NULL;
4985 path = PyBytes_AsString(opath);
4986 if (PyList_Check(argv)) {
4987 argc = PyList_Size(argv);
4988 getitem = PyList_GetItem;
4989 }
4990 else if (PyTuple_Check(argv)) {
4991 argc = PyTuple_Size(argv);
4992 getitem = PyTuple_GetItem;
4993 }
4994 else {
4995 PyErr_SetString(PyExc_TypeError,
4996 "spawnv() arg 2 must be a tuple or list");
4997 Py_DECREF(opath);
4998 return NULL;
4999 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 argvlist = PyMem_NEW(char *, argc+1);
5002 if (argvlist == NULL) {
5003 Py_DECREF(opath);
5004 return PyErr_NoMemory();
5005 }
5006 for (i = 0; i < argc; i++) {
5007 if (!fsconvert_strdup((*getitem)(argv, i),
5008 &argvlist[i])) {
5009 free_string_array(argvlist, i);
5010 PyErr_SetString(
5011 PyExc_TypeError,
5012 "spawnv() arg 2 must contain only strings");
5013 Py_DECREF(opath);
5014 return NULL;
5015 }
5016 }
5017 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005018
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005019#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 Py_BEGIN_ALLOW_THREADS
5021 spawnval = spawnv(mode, path, argvlist);
5022 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005023#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 if (mode == _OLD_P_OVERLAY)
5025 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005026
Victor Stinner8c62be82010-05-06 00:08:46 +00005027 Py_BEGIN_ALLOW_THREADS
5028 spawnval = _spawnv(mode, path, argvlist);
5029 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005030#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 free_string_array(argvlist, argc);
5033 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005034
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 if (spawnval == -1)
5036 return posix_error();
5037 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005038#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005040#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005042#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005043}
5044
5045
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005047"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005048Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005049\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 mode: mode of process creation\n\
5051 path: path of executable file\n\
5052 args: tuple or list of arguments\n\
5053 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005054
5055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005056posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005057{
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 PyObject *opath;
5059 char *path;
5060 PyObject *argv, *env;
5061 char **argvlist;
5062 char **envlist;
5063 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005064 int mode;
5065 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 Py_intptr_t spawnval;
5067 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5068 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 /* spawnve has four arguments: (mode, path, argv, env), where
5071 argv is a list or tuple of strings and env is a dictionary
5072 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5075 PyUnicode_FSConverter,
5076 &opath, &argv, &env))
5077 return NULL;
5078 path = PyBytes_AsString(opath);
5079 if (PyList_Check(argv)) {
5080 argc = PyList_Size(argv);
5081 getitem = PyList_GetItem;
5082 }
5083 else if (PyTuple_Check(argv)) {
5084 argc = PyTuple_Size(argv);
5085 getitem = PyTuple_GetItem;
5086 }
5087 else {
5088 PyErr_SetString(PyExc_TypeError,
5089 "spawnve() arg 2 must be a tuple or list");
5090 goto fail_0;
5091 }
5092 if (!PyMapping_Check(env)) {
5093 PyErr_SetString(PyExc_TypeError,
5094 "spawnve() arg 3 must be a mapping object");
5095 goto fail_0;
5096 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005097
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 argvlist = PyMem_NEW(char *, argc+1);
5099 if (argvlist == NULL) {
5100 PyErr_NoMemory();
5101 goto fail_0;
5102 }
5103 for (i = 0; i < argc; i++) {
5104 if (!fsconvert_strdup((*getitem)(argv, i),
5105 &argvlist[i]))
5106 {
5107 lastarg = i;
5108 goto fail_1;
5109 }
5110 }
5111 lastarg = argc;
5112 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 envlist = parse_envlist(env, &envc);
5115 if (envlist == NULL)
5116 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005117
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005118#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 Py_BEGIN_ALLOW_THREADS
5120 spawnval = spawnve(mode, path, argvlist, envlist);
5121 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005122#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 if (mode == _OLD_P_OVERLAY)
5124 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 Py_BEGIN_ALLOW_THREADS
5127 spawnval = _spawnve(mode, path, argvlist, envlist);
5128 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005129#endif
Tim Peters25059d32001-12-07 20:35:43 +00005130
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 if (spawnval == -1)
5132 (void) posix_error();
5133 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005134#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005136#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005138#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005139
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 while (--envc >= 0)
5141 PyMem_DEL(envlist[envc]);
5142 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005143 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005145 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 Py_DECREF(opath);
5147 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005149
5150/* OS/2 supports spawnvp & spawnvpe natively */
5151#if defined(PYOS_OS2)
5152PyDoc_STRVAR(posix_spawnvp__doc__,
5153"spawnvp(mode, file, args)\n\n\
5154Execute the program 'file' in a new process, using the environment\n\
5155search path to find the file.\n\
5156\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 mode: mode of process creation\n\
5158 file: executable file name\n\
5159 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005160
5161static PyObject *
5162posix_spawnvp(PyObject *self, PyObject *args)
5163{
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 PyObject *opath;
5165 char *path;
5166 PyObject *argv;
5167 char **argvlist;
5168 int mode, i, argc;
5169 Py_intptr_t spawnval;
5170 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 /* spawnvp has three arguments: (mode, path, argv), where
5173 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005174
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5176 PyUnicode_FSConverter,
5177 &opath, &argv))
5178 return NULL;
5179 path = PyBytes_AsString(opath);
5180 if (PyList_Check(argv)) {
5181 argc = PyList_Size(argv);
5182 getitem = PyList_GetItem;
5183 }
5184 else if (PyTuple_Check(argv)) {
5185 argc = PyTuple_Size(argv);
5186 getitem = PyTuple_GetItem;
5187 }
5188 else {
5189 PyErr_SetString(PyExc_TypeError,
5190 "spawnvp() arg 2 must be a tuple or list");
5191 Py_DECREF(opath);
5192 return NULL;
5193 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005194
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 argvlist = PyMem_NEW(char *, argc+1);
5196 if (argvlist == NULL) {
5197 Py_DECREF(opath);
5198 return PyErr_NoMemory();
5199 }
5200 for (i = 0; i < argc; i++) {
5201 if (!fsconvert_strdup((*getitem)(argv, i),
5202 &argvlist[i])) {
5203 free_string_array(argvlist, i);
5204 PyErr_SetString(
5205 PyExc_TypeError,
5206 "spawnvp() arg 2 must contain only strings");
5207 Py_DECREF(opath);
5208 return NULL;
5209 }
5210 }
5211 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005212
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005214#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005216#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005220
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 free_string_array(argvlist, argc);
5222 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 if (spawnval == -1)
5225 return posix_error();
5226 else
5227 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005228}
5229
5230
5231PyDoc_STRVAR(posix_spawnvpe__doc__,
5232"spawnvpe(mode, file, args, env)\n\n\
5233Execute the program 'file' in a new process, using the environment\n\
5234search path to find the file.\n\
5235\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 mode: mode of process creation\n\
5237 file: executable file name\n\
5238 args: tuple or list of arguments\n\
5239 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005240
5241static PyObject *
5242posix_spawnvpe(PyObject *self, PyObject *args)
5243{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005244 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 char *path;
5246 PyObject *argv, *env;
5247 char **argvlist;
5248 char **envlist;
5249 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005250 int mode;
5251 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 Py_intptr_t spawnval;
5253 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5254 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005255
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 /* spawnvpe has four arguments: (mode, path, argv, env), where
5257 argv is a list or tuple of strings and env is a dictionary
5258 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005259
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5261 PyUnicode_FSConverter,
5262 &opath, &argv, &env))
5263 return NULL;
5264 path = PyBytes_AsString(opath);
5265 if (PyList_Check(argv)) {
5266 argc = PyList_Size(argv);
5267 getitem = PyList_GetItem;
5268 }
5269 else if (PyTuple_Check(argv)) {
5270 argc = PyTuple_Size(argv);
5271 getitem = PyTuple_GetItem;
5272 }
5273 else {
5274 PyErr_SetString(PyExc_TypeError,
5275 "spawnvpe() arg 2 must be a tuple or list");
5276 goto fail_0;
5277 }
5278 if (!PyMapping_Check(env)) {
5279 PyErr_SetString(PyExc_TypeError,
5280 "spawnvpe() arg 3 must be a mapping object");
5281 goto fail_0;
5282 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005283
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 argvlist = PyMem_NEW(char *, argc+1);
5285 if (argvlist == NULL) {
5286 PyErr_NoMemory();
5287 goto fail_0;
5288 }
5289 for (i = 0; i < argc; i++) {
5290 if (!fsconvert_strdup((*getitem)(argv, i),
5291 &argvlist[i]))
5292 {
5293 lastarg = i;
5294 goto fail_1;
5295 }
5296 }
5297 lastarg = argc;
5298 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005299
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 envlist = parse_envlist(env, &envc);
5301 if (envlist == NULL)
5302 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005305#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005307#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005309#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005311
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 if (spawnval == -1)
5313 (void) posix_error();
5314 else
5315 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 while (--envc >= 0)
5318 PyMem_DEL(envlist[envc]);
5319 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005320 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005322 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 Py_DECREF(opath);
5324 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005325}
5326#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005327#endif /* HAVE_SPAWNV */
5328
5329
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005330#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005332"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005333Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5334\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005335Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005336
5337static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005338posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005339{
Victor Stinner8c62be82010-05-06 00:08:46 +00005340 pid_t pid;
5341 int result = 0;
5342 _PyImport_AcquireLock();
5343 pid = fork1();
5344 if (pid == 0) {
5345 /* child: this clobbers and resets the import lock. */
5346 PyOS_AfterFork();
5347 } else {
5348 /* parent: release the import lock. */
5349 result = _PyImport_ReleaseLock();
5350 }
5351 if (pid == -1)
5352 return posix_error();
5353 if (result < 0) {
5354 /* Don't clobber the OSError if the fork failed. */
5355 PyErr_SetString(PyExc_RuntimeError,
5356 "not holding the import lock");
5357 return NULL;
5358 }
5359 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005360}
5361#endif
5362
5363
Guido van Rossumad0ee831995-03-01 10:34:45 +00005364#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005365PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005366"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005367Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005369
Barry Warsaw53699e91996-12-10 23:23:01 +00005370static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005371posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005372{
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 pid_t pid;
5374 int result = 0;
5375 _PyImport_AcquireLock();
5376 pid = fork();
5377 if (pid == 0) {
5378 /* child: this clobbers and resets the import lock. */
5379 PyOS_AfterFork();
5380 } else {
5381 /* parent: release the import lock. */
5382 result = _PyImport_ReleaseLock();
5383 }
5384 if (pid == -1)
5385 return posix_error();
5386 if (result < 0) {
5387 /* Don't clobber the OSError if the fork failed. */
5388 PyErr_SetString(PyExc_RuntimeError,
5389 "not holding the import lock");
5390 return NULL;
5391 }
5392 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005393}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005394#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005395
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005396#ifdef HAVE_SCHED_H
5397
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005398#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5399
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005400PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5401"sched_get_priority_max(policy)\n\n\
5402Get the maximum scheduling priority for *policy*.");
5403
5404static PyObject *
5405posix_sched_get_priority_max(PyObject *self, PyObject *args)
5406{
5407 int policy, max;
5408
5409 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5410 return NULL;
5411 max = sched_get_priority_max(policy);
5412 if (max < 0)
5413 return posix_error();
5414 return PyLong_FromLong(max);
5415}
5416
5417PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5418"sched_get_priority_min(policy)\n\n\
5419Get the minimum scheduling priority for *policy*.");
5420
5421static PyObject *
5422posix_sched_get_priority_min(PyObject *self, PyObject *args)
5423{
5424 int policy, min;
5425
5426 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5427 return NULL;
5428 min = sched_get_priority_min(policy);
5429 if (min < 0)
5430 return posix_error();
5431 return PyLong_FromLong(min);
5432}
5433
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005434#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005436#ifdef HAVE_SCHED_SETSCHEDULER
5437
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005438PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5439"sched_getscheduler(pid)\n\n\
5440Get the scheduling policy for the process with a PID of *pid*.\n\
5441Passing a PID of 0 returns the scheduling policy for the calling process.");
5442
5443static PyObject *
5444posix_sched_getscheduler(PyObject *self, PyObject *args)
5445{
5446 pid_t pid;
5447 int policy;
5448
5449 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5450 return NULL;
5451 policy = sched_getscheduler(pid);
5452 if (policy < 0)
5453 return posix_error();
5454 return PyLong_FromLong(policy);
5455}
5456
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005457#endif
5458
5459#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5460
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005461static PyObject *
5462sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5463{
5464 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005465 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005466
5467 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5468 return NULL;
5469 res = PyStructSequence_New(type);
5470 if (!res)
5471 return NULL;
5472 Py_INCREF(priority);
5473 PyStructSequence_SET_ITEM(res, 0, priority);
5474 return res;
5475}
5476
5477PyDoc_STRVAR(sched_param__doc__,
5478"sched_param(sched_priority): A scheduling parameter.\n\n\
5479Current has only one field: sched_priority");
5480
5481static PyStructSequence_Field sched_param_fields[] = {
5482 {"sched_priority", "the scheduling priority"},
5483 {0}
5484};
5485
5486static PyStructSequence_Desc sched_param_desc = {
5487 "sched_param", /* name */
5488 sched_param__doc__, /* doc */
5489 sched_param_fields,
5490 1
5491};
5492
5493static int
5494convert_sched_param(PyObject *param, struct sched_param *res)
5495{
5496 long priority;
5497
5498 if (Py_TYPE(param) != &SchedParamType) {
5499 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5500 return 0;
5501 }
5502 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5503 if (priority == -1 && PyErr_Occurred())
5504 return 0;
5505 if (priority > INT_MAX || priority < INT_MIN) {
5506 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5507 return 0;
5508 }
5509 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5510 return 1;
5511}
5512
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005513#endif
5514
5515#ifdef HAVE_SCHED_SETSCHEDULER
5516
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005517PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5518"sched_setscheduler(pid, policy, param)\n\n\
5519Set the scheduling policy, *policy*, for *pid*.\n\
5520If *pid* is 0, the calling process is changed.\n\
5521*param* is an instance of sched_param.");
5522
5523static PyObject *
5524posix_sched_setscheduler(PyObject *self, PyObject *args)
5525{
5526 pid_t pid;
5527 int policy;
5528 struct sched_param param;
5529
5530 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5531 &pid, &policy, &convert_sched_param, &param))
5532 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005533
5534 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005535 ** sched_setscheduler() returns 0 in Linux, but the previous
5536 ** scheduling policy under Solaris/Illumos, and others.
5537 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005538 */
5539 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540 return posix_error();
5541 Py_RETURN_NONE;
5542}
5543
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005544#endif
5545
5546#ifdef HAVE_SCHED_SETPARAM
5547
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548PyDoc_STRVAR(posix_sched_getparam__doc__,
5549"sched_getparam(pid) -> sched_param\n\n\
5550Returns scheduling parameters for the process with *pid* as an instance of the\n\
5551sched_param class. A PID of 0 means the calling process.");
5552
5553static PyObject *
5554posix_sched_getparam(PyObject *self, PyObject *args)
5555{
5556 pid_t pid;
5557 struct sched_param param;
5558 PyObject *res, *priority;
5559
5560 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5561 return NULL;
5562 if (sched_getparam(pid, &param))
5563 return posix_error();
5564 res = PyStructSequence_New(&SchedParamType);
5565 if (!res)
5566 return NULL;
5567 priority = PyLong_FromLong(param.sched_priority);
5568 if (!priority) {
5569 Py_DECREF(res);
5570 return NULL;
5571 }
5572 PyStructSequence_SET_ITEM(res, 0, priority);
5573 return res;
5574}
5575
5576PyDoc_STRVAR(posix_sched_setparam__doc__,
5577"sched_setparam(pid, param)\n\n\
5578Set scheduling parameters for a process with PID *pid*.\n\
5579A PID of 0 means the calling process.");
5580
5581static PyObject *
5582posix_sched_setparam(PyObject *self, PyObject *args)
5583{
5584 pid_t pid;
5585 struct sched_param param;
5586
5587 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5588 &pid, &convert_sched_param, &param))
5589 return NULL;
5590 if (sched_setparam(pid, &param))
5591 return posix_error();
5592 Py_RETURN_NONE;
5593}
5594
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005595#endif
5596
5597#ifdef HAVE_SCHED_RR_GET_INTERVAL
5598
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005599PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5600"sched_rr_get_interval(pid) -> float\n\n\
5601Return the round-robin quantum for the process with PID *pid* in seconds.");
5602
5603static PyObject *
5604posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5605{
5606 pid_t pid;
5607 struct timespec interval;
5608
5609 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5610 return NULL;
5611 if (sched_rr_get_interval(pid, &interval))
5612 return posix_error();
5613 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5614}
5615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616#endif
5617
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005618PyDoc_STRVAR(posix_sched_yield__doc__,
5619"sched_yield()\n\n\
5620Voluntarily relinquish the CPU.");
5621
5622static PyObject *
5623posix_sched_yield(PyObject *self, PyObject *noargs)
5624{
5625 if (sched_yield())
5626 return posix_error();
5627 Py_RETURN_NONE;
5628}
5629
Benjamin Peterson2740af82011-08-02 17:41:34 -05005630#ifdef HAVE_SCHED_SETAFFINITY
5631
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005632typedef struct {
5633 PyObject_HEAD;
5634 Py_ssize_t size;
5635 int ncpus;
5636 cpu_set_t *set;
5637} Py_cpu_set;
5638
5639static PyTypeObject cpu_set_type;
5640
5641static void
5642cpu_set_dealloc(Py_cpu_set *set)
5643{
5644 assert(set->set);
5645 CPU_FREE(set->set);
5646 Py_TYPE(set)->tp_free(set);
5647}
5648
5649static Py_cpu_set *
5650make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5651{
5652 Py_cpu_set *set;
5653
5654 if (size < 0) {
5655 PyErr_SetString(PyExc_ValueError, "negative size");
5656 return NULL;
5657 }
5658 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5659 if (!set)
5660 return NULL;
5661 set->ncpus = size;
5662 set->size = CPU_ALLOC_SIZE(size);
5663 set->set = CPU_ALLOC(size);
5664 if (!set->set) {
5665 type->tp_free(set);
5666 PyErr_NoMemory();
5667 return NULL;
5668 }
5669 CPU_ZERO_S(set->size, set->set);
5670 return set;
5671}
5672
5673static PyObject *
5674cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5675{
5676 int size;
5677
5678 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5679 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5680 return NULL;
5681 return (PyObject *)make_new_cpu_set(type, size);
5682}
5683
5684static PyObject *
5685cpu_set_repr(Py_cpu_set *set)
5686{
5687 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005688}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005689
5690static Py_ssize_t
5691cpu_set_len(Py_cpu_set *set)
5692{
5693 return set->ncpus;
5694}
5695
5696static int
5697_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5698{
5699 int cpu;
5700 if (!PyArg_ParseTuple(args, requester, &cpu))
5701 return -1;
5702 if (cpu < 0) {
5703 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5704 return -1;
5705 }
5706 if (cpu >= set->ncpus) {
5707 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5708 return -1;
5709 }
5710 return cpu;
5711}
5712
5713PyDoc_STRVAR(cpu_set_set_doc,
5714"cpu_set.set(i)\n\n\
5715Add CPU *i* to the set.");
5716
5717static PyObject *
5718cpu_set_set(Py_cpu_set *set, PyObject *args)
5719{
5720 int cpu = _get_cpu(set, "i|set", args);
5721 if (cpu == -1)
5722 return NULL;
5723 CPU_SET_S(cpu, set->size, set->set);
5724 Py_RETURN_NONE;
5725}
5726
5727PyDoc_STRVAR(cpu_set_count_doc,
5728"cpu_set.count() -> int\n\n\
5729Return the number of CPUs active in the set.");
5730
5731static PyObject *
5732cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5733{
5734 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5735}
5736
5737PyDoc_STRVAR(cpu_set_clear_doc,
5738"cpu_set.clear(i)\n\n\
5739Remove CPU *i* from the set.");
5740
5741static PyObject *
5742cpu_set_clear(Py_cpu_set *set, PyObject *args)
5743{
5744 int cpu = _get_cpu(set, "i|clear", args);
5745 if (cpu == -1)
5746 return NULL;
5747 CPU_CLR_S(cpu, set->size, set->set);
5748 Py_RETURN_NONE;
5749}
5750
5751PyDoc_STRVAR(cpu_set_isset_doc,
5752"cpu_set.isset(i) -> bool\n\n\
5753Test if CPU *i* is in the set.");
5754
5755static PyObject *
5756cpu_set_isset(Py_cpu_set *set, PyObject *args)
5757{
5758 int cpu = _get_cpu(set, "i|isset", args);
5759 if (cpu == -1)
5760 return NULL;
5761 if (CPU_ISSET_S(cpu, set->size, set->set))
5762 Py_RETURN_TRUE;
5763 Py_RETURN_FALSE;
5764}
5765
5766PyDoc_STRVAR(cpu_set_zero_doc,
5767"cpu_set.zero()\n\n\
5768Clear the cpu_set.");
5769
5770static PyObject *
5771cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5772{
5773 CPU_ZERO_S(set->size, set->set);
5774 Py_RETURN_NONE;
5775}
5776
5777static PyObject *
5778cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5779{
5780 int eq;
5781
Brian Curtindfc80e32011-08-10 20:28:54 -05005782 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5783 Py_RETURN_NOTIMPLEMENTED;
5784
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005785 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5786 if ((op == Py_EQ) ? eq : !eq)
5787 Py_RETURN_TRUE;
5788 else
5789 Py_RETURN_FALSE;
5790}
5791
5792#define CPU_SET_BINOP(name, op) \
5793 static PyObject * \
5794 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5795 if (res) { \
5796 Py_INCREF(res); \
5797 } \
5798 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005799 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005800 if (!res) \
5801 return NULL; \
5802 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005803 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005804 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005805 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005806 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005807 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005808 op(res->size, res->set, left->set, right->set); \
5809 return (PyObject *)res; \
5810 } \
5811 static PyObject * \
5812 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5813 return do_cpu_set_##name(left, right, NULL); \
5814 } \
5815 static PyObject * \
5816 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5817 return do_cpu_set_##name(left, right, left); \
5818 } \
5819
5820CPU_SET_BINOP(and, CPU_AND_S)
5821CPU_SET_BINOP(or, CPU_OR_S)
5822CPU_SET_BINOP(xor, CPU_XOR_S)
5823#undef CPU_SET_BINOP
5824
5825PyDoc_STRVAR(cpu_set_doc,
5826"cpu_set(size)\n\n\
5827Create an empty mask of CPUs.");
5828
5829static PyNumberMethods cpu_set_as_number = {
5830 0, /*nb_add*/
5831 0, /*nb_subtract*/
5832 0, /*nb_multiply*/
5833 0, /*nb_remainder*/
5834 0, /*nb_divmod*/
5835 0, /*nb_power*/
5836 0, /*nb_negative*/
5837 0, /*nb_positive*/
5838 0, /*nb_absolute*/
5839 0, /*nb_bool*/
5840 0, /*nb_invert*/
5841 0, /*nb_lshift*/
5842 0, /*nb_rshift*/
5843 (binaryfunc)cpu_set_and, /*nb_and*/
5844 (binaryfunc)cpu_set_xor, /*nb_xor*/
5845 (binaryfunc)cpu_set_or, /*nb_or*/
5846 0, /*nb_int*/
5847 0, /*nb_reserved*/
5848 0, /*nb_float*/
5849 0, /*nb_inplace_add*/
5850 0, /*nb_inplace_subtract*/
5851 0, /*nb_inplace_multiply*/
5852 0, /*nb_inplace_remainder*/
5853 0, /*nb_inplace_power*/
5854 0, /*nb_inplace_lshift*/
5855 0, /*nb_inplace_rshift*/
5856 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5857 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5858 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5859};
5860
5861static PySequenceMethods cpu_set_as_sequence = {
5862 (lenfunc)cpu_set_len, /* sq_length */
5863};
5864
5865static PyMethodDef cpu_set_methods[] = {
5866 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5867 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5868 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5869 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5870 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5871 {NULL, NULL} /* sentinel */
5872};
5873
5874static PyTypeObject cpu_set_type = {
5875 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5876 "posix.cpu_set", /* tp_name */
5877 sizeof(Py_cpu_set), /* tp_basicsize */
5878 0, /* tp_itemsize */
5879 /* methods */
5880 (destructor)cpu_set_dealloc, /* tp_dealloc */
5881 0, /* tp_print */
5882 0, /* tp_getattr */
5883 0, /* tp_setattr */
5884 0, /* tp_reserved */
5885 (reprfunc)cpu_set_repr, /* tp_repr */
5886 &cpu_set_as_number, /* tp_as_number */
5887 &cpu_set_as_sequence, /* tp_as_sequence */
5888 0, /* tp_as_mapping */
5889 PyObject_HashNotImplemented, /* tp_hash */
5890 0, /* tp_call */
5891 0, /* tp_str */
5892 PyObject_GenericGetAttr, /* tp_getattro */
5893 0, /* tp_setattro */
5894 0, /* tp_as_buffer */
5895 Py_TPFLAGS_DEFAULT, /* tp_flags */
5896 cpu_set_doc, /* tp_doc */
5897 0, /* tp_traverse */
5898 0, /* tp_clear */
5899 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5900 0, /* tp_weaklistoffset */
5901 0, /* tp_iter */
5902 0, /* tp_iternext */
5903 cpu_set_methods, /* tp_methods */
5904 0, /* tp_members */
5905 0, /* tp_getset */
5906 0, /* tp_base */
5907 0, /* tp_dict */
5908 0, /* tp_descr_get */
5909 0, /* tp_descr_set */
5910 0, /* tp_dictoffset */
5911 0, /* tp_init */
5912 PyType_GenericAlloc, /* tp_alloc */
5913 cpu_set_new, /* tp_new */
5914 PyObject_Del, /* tp_free */
5915};
5916
5917PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5918"sched_setaffinity(pid, cpu_set)\n\n\
5919Set the affinity of the process with PID *pid* to *cpu_set*.");
5920
5921static PyObject *
5922posix_sched_setaffinity(PyObject *self, PyObject *args)
5923{
5924 pid_t pid;
5925 Py_cpu_set *cpu_set;
5926
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005927 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005928 &pid, &cpu_set_type, &cpu_set))
5929 return NULL;
5930 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5931 return posix_error();
5932 Py_RETURN_NONE;
5933}
5934
5935PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5936"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5937Return the affinity of the process with PID *pid*.\n\
5938The returned cpu_set will be of size *ncpus*.");
5939
5940static PyObject *
5941posix_sched_getaffinity(PyObject *self, PyObject *args)
5942{
5943 pid_t pid;
5944 int ncpus;
5945 Py_cpu_set *res;
5946
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005947 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005948 &pid, &ncpus))
5949 return NULL;
5950 res = make_new_cpu_set(&cpu_set_type, ncpus);
5951 if (!res)
5952 return NULL;
5953 if (sched_getaffinity(pid, res->size, res->set)) {
5954 Py_DECREF(res);
5955 return posix_error();
5956 }
5957 return (PyObject *)res;
5958}
5959
Benjamin Peterson2740af82011-08-02 17:41:34 -05005960#endif /* HAVE_SCHED_SETAFFINITY */
5961
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005962#endif /* HAVE_SCHED_H */
5963
Neal Norwitzb59798b2003-03-21 01:43:31 +00005964/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005965/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5966#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005967#define DEV_PTY_FILE "/dev/ptc"
5968#define HAVE_DEV_PTMX
5969#else
5970#define DEV_PTY_FILE "/dev/ptmx"
5971#endif
5972
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005973#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005974#ifdef HAVE_PTY_H
5975#include <pty.h>
5976#else
5977#ifdef HAVE_LIBUTIL_H
5978#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005979#else
5980#ifdef HAVE_UTIL_H
5981#include <util.h>
5982#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005983#endif /* HAVE_LIBUTIL_H */
5984#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005985#ifdef HAVE_STROPTS_H
5986#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005987#endif
5988#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005989
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005990#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005994
5995static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005996posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005997{
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005999#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006001#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006002#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006004#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006006#endif
6007#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006008
Thomas Wouters70c21a12000-07-14 14:28:33 +00006009#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6011 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006012#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6014 if (slave_name == NULL)
6015 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006016
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 slave_fd = open(slave_name, O_RDWR);
6018 if (slave_fd < 0)
6019 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006020#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6022 if (master_fd < 0)
6023 return posix_error();
6024 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6025 /* change permission of slave */
6026 if (grantpt(master_fd) < 0) {
6027 PyOS_setsig(SIGCHLD, sig_saved);
6028 return posix_error();
6029 }
6030 /* unlock slave */
6031 if (unlockpt(master_fd) < 0) {
6032 PyOS_setsig(SIGCHLD, sig_saved);
6033 return posix_error();
6034 }
6035 PyOS_setsig(SIGCHLD, sig_saved);
6036 slave_name = ptsname(master_fd); /* get name of slave */
6037 if (slave_name == NULL)
6038 return posix_error();
6039 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6040 if (slave_fd < 0)
6041 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006042#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6044 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006045#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006047#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006048#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006049#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006050
Victor Stinner8c62be82010-05-06 00:08:46 +00006051 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006052
Fred Drake8cef4cf2000-06-28 16:40:38 +00006053}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006054#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006055
6056#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006057PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006058"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006059Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6060Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006062
6063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006064posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006065{
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 int master_fd = -1, result = 0;
6067 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006068
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 _PyImport_AcquireLock();
6070 pid = forkpty(&master_fd, NULL, NULL, NULL);
6071 if (pid == 0) {
6072 /* child: this clobbers and resets the import lock. */
6073 PyOS_AfterFork();
6074 } else {
6075 /* parent: release the import lock. */
6076 result = _PyImport_ReleaseLock();
6077 }
6078 if (pid == -1)
6079 return posix_error();
6080 if (result < 0) {
6081 /* Don't clobber the OSError if the fork failed. */
6082 PyErr_SetString(PyExc_RuntimeError,
6083 "not holding the import lock");
6084 return NULL;
6085 }
6086 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006087}
6088#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006089
Ross Lagerwall7807c352011-03-17 20:20:30 +02006090
Guido van Rossumad0ee831995-03-01 10:34:45 +00006091#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006093"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Barry Warsaw53699e91996-12-10 23:23:01 +00006096static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006097posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006098{
Victor Stinner8c62be82010-05-06 00:08:46 +00006099 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006100}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006101#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Guido van Rossumad0ee831995-03-01 10:34:45 +00006104#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Barry Warsaw53699e91996-12-10 23:23:01 +00006109static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006110posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006111{
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006113}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006114#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Guido van Rossumad0ee831995-03-01 10:34:45 +00006117#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006118PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006119"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006121
Barry Warsaw53699e91996-12-10 23:23:01 +00006122static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006123posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006124{
Victor Stinner8c62be82010-05-06 00:08:46 +00006125 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006126}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006127#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006131"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006133
Barry Warsaw53699e91996-12-10 23:23:01 +00006134static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006135posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006136{
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006138}
6139
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006140#ifdef HAVE_GETGROUPLIST
6141PyDoc_STRVAR(posix_getgrouplist__doc__,
6142"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6143Returns a list of groups to which a user belongs.\n\n\
6144 user: username to lookup\n\
6145 group: base group id of the user");
6146
6147static PyObject *
6148posix_getgrouplist(PyObject *self, PyObject *args)
6149{
6150#ifdef NGROUPS_MAX
6151#define MAX_GROUPS NGROUPS_MAX
6152#else
6153 /* defined to be 16 on Solaris7, so this should be a small number */
6154#define MAX_GROUPS 64
6155#endif
6156
6157 const char *user;
6158 int i, ngroups;
6159 PyObject *list;
6160#ifdef __APPLE__
6161 int *groups, basegid;
6162#else
6163 gid_t *groups, basegid;
6164#endif
6165 ngroups = MAX_GROUPS;
6166
6167 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6168 return NULL;
6169
6170#ifdef __APPLE__
6171 groups = PyMem_Malloc(ngroups * sizeof(int));
6172#else
6173 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6174#endif
6175 if (groups == NULL)
6176 return PyErr_NoMemory();
6177
6178 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6179 PyMem_Del(groups);
6180 return posix_error();
6181 }
6182
6183 list = PyList_New(ngroups);
6184 if (list == NULL) {
6185 PyMem_Del(groups);
6186 return NULL;
6187 }
6188
6189 for (i = 0; i < ngroups; i++) {
6190 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6191 if (o == NULL) {
6192 Py_DECREF(list);
6193 PyMem_Del(groups);
6194 return NULL;
6195 }
6196 PyList_SET_ITEM(list, i, o);
6197 }
6198
6199 PyMem_Del(groups);
6200
6201 return list;
6202}
6203#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006204
Fred Drakec9680921999-12-13 16:37:25 +00006205#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006206PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006207"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006209
6210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006211posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006212{
6213 PyObject *result = NULL;
6214
Fred Drakec9680921999-12-13 16:37:25 +00006215#ifdef NGROUPS_MAX
6216#define MAX_GROUPS NGROUPS_MAX
6217#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006219#define MAX_GROUPS 64
6220#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006221 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006222
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006223 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006224 * This is a helper variable to store the intermediate result when
6225 * that happens.
6226 *
6227 * To keep the code readable the OSX behaviour is unconditional,
6228 * according to the POSIX spec this should be safe on all unix-y
6229 * systems.
6230 */
6231 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006233
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006235 if (n < 0) {
6236 if (errno == EINVAL) {
6237 n = getgroups(0, NULL);
6238 if (n == -1) {
6239 return posix_error();
6240 }
6241 if (n == 0) {
6242 /* Avoid malloc(0) */
6243 alt_grouplist = grouplist;
6244 } else {
6245 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6246 if (alt_grouplist == NULL) {
6247 errno = EINVAL;
6248 return posix_error();
6249 }
6250 n = getgroups(n, alt_grouplist);
6251 if (n == -1) {
6252 PyMem_Free(alt_grouplist);
6253 return posix_error();
6254 }
6255 }
6256 } else {
6257 return posix_error();
6258 }
6259 }
6260 result = PyList_New(n);
6261 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 int i;
6263 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006264 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006265 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006266 Py_DECREF(result);
6267 result = NULL;
6268 break;
Fred Drakec9680921999-12-13 16:37:25 +00006269 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006271 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006272 }
6273
6274 if (alt_grouplist != grouplist) {
6275 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006277
Fred Drakec9680921999-12-13 16:37:25 +00006278 return result;
6279}
6280#endif
6281
Antoine Pitroub7572f02009-12-02 20:46:48 +00006282#ifdef HAVE_INITGROUPS
6283PyDoc_STRVAR(posix_initgroups__doc__,
6284"initgroups(username, gid) -> None\n\n\
6285Call the system initgroups() to initialize the group access list with all of\n\
6286the groups of which the specified username is a member, plus the specified\n\
6287group id.");
6288
6289static PyObject *
6290posix_initgroups(PyObject *self, PyObject *args)
6291{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006292 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006294 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006296
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6298 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006300 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006301
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006302 res = initgroups(username, (gid_t) gid);
6303 Py_DECREF(oname);
6304 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 Py_INCREF(Py_None);
6308 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006309}
6310#endif
6311
Martin v. Löwis606edc12002-06-13 21:09:11 +00006312#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006313PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006314"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006315Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006316
6317static PyObject *
6318posix_getpgid(PyObject *self, PyObject *args)
6319{
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 pid_t pid, pgid;
6321 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6322 return NULL;
6323 pgid = getpgid(pid);
6324 if (pgid < 0)
6325 return posix_error();
6326 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006327}
6328#endif /* HAVE_GETPGID */
6329
6330
Guido van Rossumb6775db1994-08-01 11:34:53 +00006331#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006333"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006335
Barry Warsaw53699e91996-12-10 23:23:01 +00006336static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006337posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006338{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006339#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006341#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006343#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006344}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006347
Guido van Rossumb6775db1994-08-01 11:34:53 +00006348#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006349PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006350"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006351Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006352
Barry Warsaw53699e91996-12-10 23:23:01 +00006353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006354posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006355{
Guido van Rossum64933891994-10-20 21:56:42 +00006356#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006358#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006360#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 return posix_error();
6362 Py_INCREF(Py_None);
6363 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006364}
6365
Guido van Rossumb6775db1994-08-01 11:34:53 +00006366#endif /* HAVE_SETPGRP */
6367
Guido van Rossumad0ee831995-03-01 10:34:45 +00006368#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006369
6370#ifdef MS_WINDOWS
6371#include <tlhelp32.h>
6372
6373static PyObject*
6374win32_getppid()
6375{
6376 HANDLE snapshot;
6377 pid_t mypid;
6378 PyObject* result = NULL;
6379 BOOL have_record;
6380 PROCESSENTRY32 pe;
6381
6382 mypid = getpid(); /* This function never fails */
6383
6384 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6385 if (snapshot == INVALID_HANDLE_VALUE)
6386 return PyErr_SetFromWindowsErr(GetLastError());
6387
6388 pe.dwSize = sizeof(pe);
6389 have_record = Process32First(snapshot, &pe);
6390 while (have_record) {
6391 if (mypid == (pid_t)pe.th32ProcessID) {
6392 /* We could cache the ulong value in a static variable. */
6393 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6394 break;
6395 }
6396
6397 have_record = Process32Next(snapshot, &pe);
6398 }
6399
6400 /* If our loop exits and our pid was not found (result will be NULL)
6401 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6402 * error anyway, so let's raise it. */
6403 if (!result)
6404 result = PyErr_SetFromWindowsErr(GetLastError());
6405
6406 CloseHandle(snapshot);
6407
6408 return result;
6409}
6410#endif /*MS_WINDOWS*/
6411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006412PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006413"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006414Return the parent's process id. If the parent process has already exited,\n\
6415Windows machines will still return its id; others systems will return the id\n\
6416of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Barry Warsaw53699e91996-12-10 23:23:01 +00006418static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006419posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006420{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006421#ifdef MS_WINDOWS
6422 return win32_getppid();
6423#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006425#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006426}
6427#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006429
Fred Drake12c6e2d1999-12-14 21:25:03 +00006430#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006432"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006433Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006434
6435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006436posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006437{
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006439#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006440 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006441 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006442
6443 if (GetUserNameW(user_name, &num_chars)) {
6444 /* num_chars is the number of unicode chars plus null terminator */
6445 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006446 }
6447 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006448 result = PyErr_SetFromWindowsErr(GetLastError());
6449#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 char *name;
6451 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006452
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 errno = 0;
6454 name = getlogin();
6455 if (name == NULL) {
6456 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006457 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006458 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006459 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 }
6461 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006462 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006464#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465 return result;
6466}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006467#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006468
Guido van Rossumad0ee831995-03-01 10:34:45 +00006469#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006471"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006472Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006473
Barry Warsaw53699e91996-12-10 23:23:01 +00006474static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006475posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006476{
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006478}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006479#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006481
Guido van Rossumad0ee831995-03-01 10:34:45 +00006482#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006483PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006484"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006485Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006486
Barry Warsaw53699e91996-12-10 23:23:01 +00006487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006488posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006489{
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 pid_t pid;
6491 int sig;
6492 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6493 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006494#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006495 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6496 APIRET rc;
6497 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006498 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006499
6500 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6501 APIRET rc;
6502 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006503 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006504
6505 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006506 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006507#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 if (kill(pid, sig) == -1)
6509 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006510#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 Py_INCREF(Py_None);
6512 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006513}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006514#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006515
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006516#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006518"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006519Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006520
6521static PyObject *
6522posix_killpg(PyObject *self, PyObject *args)
6523{
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 int sig;
6525 pid_t pgid;
6526 /* XXX some man pages make the `pgid` parameter an int, others
6527 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6528 take the same type. Moreover, pid_t is always at least as wide as
6529 int (else compilation of this module fails), which is safe. */
6530 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6531 return NULL;
6532 if (killpg(pgid, sig) == -1)
6533 return posix_error();
6534 Py_INCREF(Py_None);
6535 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006536}
6537#endif
6538
Brian Curtineb24d742010-04-12 17:16:38 +00006539#ifdef MS_WINDOWS
6540PyDoc_STRVAR(win32_kill__doc__,
6541"kill(pid, sig)\n\n\
6542Kill a process with a signal.");
6543
6544static PyObject *
6545win32_kill(PyObject *self, PyObject *args)
6546{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006547 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 DWORD pid, sig, err;
6549 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006550
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6552 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006553
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 /* Console processes which share a common console can be sent CTRL+C or
6555 CTRL+BREAK events, provided they handle said events. */
6556 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6557 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6558 err = GetLastError();
6559 PyErr_SetFromWindowsErr(err);
6560 }
6561 else
6562 Py_RETURN_NONE;
6563 }
Brian Curtineb24d742010-04-12 17:16:38 +00006564
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6566 attempt to open and terminate the process. */
6567 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6568 if (handle == NULL) {
6569 err = GetLastError();
6570 return PyErr_SetFromWindowsErr(err);
6571 }
Brian Curtineb24d742010-04-12 17:16:38 +00006572
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 if (TerminateProcess(handle, sig) == 0) {
6574 err = GetLastError();
6575 result = PyErr_SetFromWindowsErr(err);
6576 } else {
6577 Py_INCREF(Py_None);
6578 result = Py_None;
6579 }
Brian Curtineb24d742010-04-12 17:16:38 +00006580
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 CloseHandle(handle);
6582 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006583}
6584#endif /* MS_WINDOWS */
6585
Guido van Rossumc0125471996-06-28 18:55:32 +00006586#ifdef HAVE_PLOCK
6587
6588#ifdef HAVE_SYS_LOCK_H
6589#include <sys/lock.h>
6590#endif
6591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006593"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006595
Barry Warsaw53699e91996-12-10 23:23:01 +00006596static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006597posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006598{
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 int op;
6600 if (!PyArg_ParseTuple(args, "i:plock", &op))
6601 return NULL;
6602 if (plock(op) == -1)
6603 return posix_error();
6604 Py_INCREF(Py_None);
6605 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006606}
6607#endif
6608
Guido van Rossumb6775db1994-08-01 11:34:53 +00006609#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006610PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006611"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006612Set the current process's user id.");
6613
Barry Warsaw53699e91996-12-10 23:23:01 +00006614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006615posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006616{
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 long uid_arg;
6618 uid_t uid;
6619 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6620 return NULL;
6621 uid = uid_arg;
6622 if (uid != uid_arg) {
6623 PyErr_SetString(PyExc_OverflowError, "user id too big");
6624 return NULL;
6625 }
6626 if (setuid(uid) < 0)
6627 return posix_error();
6628 Py_INCREF(Py_None);
6629 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006630}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006631#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006633
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006634#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006635PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006636"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006637Set the current process's effective user id.");
6638
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006639static PyObject *
6640posix_seteuid (PyObject *self, PyObject *args)
6641{
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 long euid_arg;
6643 uid_t euid;
6644 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6645 return NULL;
6646 euid = euid_arg;
6647 if (euid != euid_arg) {
6648 PyErr_SetString(PyExc_OverflowError, "user id too big");
6649 return NULL;
6650 }
6651 if (seteuid(euid) < 0) {
6652 return posix_error();
6653 } else {
6654 Py_INCREF(Py_None);
6655 return Py_None;
6656 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006657}
6658#endif /* HAVE_SETEUID */
6659
6660#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006662"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663Set the current process's effective group id.");
6664
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006665static PyObject *
6666posix_setegid (PyObject *self, PyObject *args)
6667{
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 long egid_arg;
6669 gid_t egid;
6670 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6671 return NULL;
6672 egid = egid_arg;
6673 if (egid != egid_arg) {
6674 PyErr_SetString(PyExc_OverflowError, "group id too big");
6675 return NULL;
6676 }
6677 if (setegid(egid) < 0) {
6678 return posix_error();
6679 } else {
6680 Py_INCREF(Py_None);
6681 return Py_None;
6682 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006683}
6684#endif /* HAVE_SETEGID */
6685
6686#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006688"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689Set the current process's real and effective user ids.");
6690
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006691static PyObject *
6692posix_setreuid (PyObject *self, PyObject *args)
6693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 long ruid_arg, euid_arg;
6695 uid_t ruid, euid;
6696 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6697 return NULL;
6698 if (ruid_arg == -1)
6699 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6700 else
6701 ruid = ruid_arg; /* otherwise, assign from our long */
6702 if (euid_arg == -1)
6703 euid = (uid_t)-1;
6704 else
6705 euid = euid_arg;
6706 if ((euid_arg != -1 && euid != euid_arg) ||
6707 (ruid_arg != -1 && ruid != ruid_arg)) {
6708 PyErr_SetString(PyExc_OverflowError, "user id too big");
6709 return NULL;
6710 }
6711 if (setreuid(ruid, euid) < 0) {
6712 return posix_error();
6713 } else {
6714 Py_INCREF(Py_None);
6715 return Py_None;
6716 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006717}
6718#endif /* HAVE_SETREUID */
6719
6720#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006722"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723Set the current process's real and effective group ids.");
6724
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006725static PyObject *
6726posix_setregid (PyObject *self, PyObject *args)
6727{
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 long rgid_arg, egid_arg;
6729 gid_t rgid, egid;
6730 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6731 return NULL;
6732 if (rgid_arg == -1)
6733 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6734 else
6735 rgid = rgid_arg; /* otherwise, assign from our long */
6736 if (egid_arg == -1)
6737 egid = (gid_t)-1;
6738 else
6739 egid = egid_arg;
6740 if ((egid_arg != -1 && egid != egid_arg) ||
6741 (rgid_arg != -1 && rgid != rgid_arg)) {
6742 PyErr_SetString(PyExc_OverflowError, "group id too big");
6743 return NULL;
6744 }
6745 if (setregid(rgid, egid) < 0) {
6746 return posix_error();
6747 } else {
6748 Py_INCREF(Py_None);
6749 return Py_None;
6750 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006751}
6752#endif /* HAVE_SETREGID */
6753
Guido van Rossumb6775db1994-08-01 11:34:53 +00006754#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006755PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006756"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006757Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006758
Barry Warsaw53699e91996-12-10 23:23:01 +00006759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006760posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 long gid_arg;
6763 gid_t gid;
6764 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6765 return NULL;
6766 gid = gid_arg;
6767 if (gid != gid_arg) {
6768 PyErr_SetString(PyExc_OverflowError, "group id too big");
6769 return NULL;
6770 }
6771 if (setgid(gid) < 0)
6772 return posix_error();
6773 Py_INCREF(Py_None);
6774 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006775}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006776#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006777
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006778#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006779PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006780"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006781Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006782
6783static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006784posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006785{
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 int i, len;
6787 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006788
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 if (!PySequence_Check(groups)) {
6790 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6791 return NULL;
6792 }
6793 len = PySequence_Size(groups);
6794 if (len > MAX_GROUPS) {
6795 PyErr_SetString(PyExc_ValueError, "too many groups");
6796 return NULL;
6797 }
6798 for(i = 0; i < len; i++) {
6799 PyObject *elem;
6800 elem = PySequence_GetItem(groups, i);
6801 if (!elem)
6802 return NULL;
6803 if (!PyLong_Check(elem)) {
6804 PyErr_SetString(PyExc_TypeError,
6805 "groups must be integers");
6806 Py_DECREF(elem);
6807 return NULL;
6808 } else {
6809 unsigned long x = PyLong_AsUnsignedLong(elem);
6810 if (PyErr_Occurred()) {
6811 PyErr_SetString(PyExc_TypeError,
6812 "group id too big");
6813 Py_DECREF(elem);
6814 return NULL;
6815 }
6816 grouplist[i] = x;
6817 /* read back the value to see if it fitted in gid_t */
6818 if (grouplist[i] != x) {
6819 PyErr_SetString(PyExc_TypeError,
6820 "group id too big");
6821 Py_DECREF(elem);
6822 return NULL;
6823 }
6824 }
6825 Py_DECREF(elem);
6826 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 if (setgroups(len, grouplist) < 0)
6829 return posix_error();
6830 Py_INCREF(Py_None);
6831 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006832}
6833#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006834
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6836static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006837wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838{
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 PyObject *result;
6840 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006841 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 if (pid == -1)
6844 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 if (struct_rusage == NULL) {
6847 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6848 if (m == NULL)
6849 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006850 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 Py_DECREF(m);
6852 if (struct_rusage == NULL)
6853 return NULL;
6854 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6857 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6858 if (!result)
6859 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006860
6861#ifndef doubletime
6862#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6863#endif
6864
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006866 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006868 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6871 SET_INT(result, 2, ru->ru_maxrss);
6872 SET_INT(result, 3, ru->ru_ixrss);
6873 SET_INT(result, 4, ru->ru_idrss);
6874 SET_INT(result, 5, ru->ru_isrss);
6875 SET_INT(result, 6, ru->ru_minflt);
6876 SET_INT(result, 7, ru->ru_majflt);
6877 SET_INT(result, 8, ru->ru_nswap);
6878 SET_INT(result, 9, ru->ru_inblock);
6879 SET_INT(result, 10, ru->ru_oublock);
6880 SET_INT(result, 11, ru->ru_msgsnd);
6881 SET_INT(result, 12, ru->ru_msgrcv);
6882 SET_INT(result, 13, ru->ru_nsignals);
6883 SET_INT(result, 14, ru->ru_nvcsw);
6884 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006885#undef SET_INT
6886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 if (PyErr_Occurred()) {
6888 Py_DECREF(result);
6889 return NULL;
6890 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893}
6894#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6895
6896#ifdef HAVE_WAIT3
6897PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006898"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006899Wait for completion of a child process.");
6900
6901static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006902posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903{
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 pid_t pid;
6905 int options;
6906 struct rusage ru;
6907 WAIT_TYPE status;
6908 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909
Victor Stinner4195b5c2012-02-08 23:03:19 +01006910 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 Py_BEGIN_ALLOW_THREADS
6914 pid = wait3(&status, options, &ru);
6915 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916
Victor Stinner4195b5c2012-02-08 23:03:19 +01006917 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918}
6919#endif /* HAVE_WAIT3 */
6920
6921#ifdef HAVE_WAIT4
6922PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006923"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924Wait for completion of a given child process.");
6925
6926static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006927posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006928{
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 pid_t pid;
6930 int options;
6931 struct rusage ru;
6932 WAIT_TYPE status;
6933 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner4195b5c2012-02-08 23:03:19 +01006935 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 Py_BEGIN_ALLOW_THREADS
6939 pid = wait4(pid, &status, options, &ru);
6940 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941
Victor Stinner4195b5c2012-02-08 23:03:19 +01006942 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943}
6944#endif /* HAVE_WAIT4 */
6945
Ross Lagerwall7807c352011-03-17 20:20:30 +02006946#if defined(HAVE_WAITID) && !defined(__APPLE__)
6947PyDoc_STRVAR(posix_waitid__doc__,
6948"waitid(idtype, id, options) -> waitid_result\n\n\
6949Wait for the completion of one or more child processes.\n\n\
6950idtype can be P_PID, P_PGID or P_ALL.\n\
6951id specifies the pid to wait on.\n\
6952options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6953or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6954Returns either waitid_result or None if WNOHANG is specified and there are\n\
6955no children in a waitable state.");
6956
6957static PyObject *
6958posix_waitid(PyObject *self, PyObject *args)
6959{
6960 PyObject *result;
6961 idtype_t idtype;
6962 id_t id;
6963 int options, res;
6964 siginfo_t si;
6965 si.si_pid = 0;
6966 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6967 return NULL;
6968 Py_BEGIN_ALLOW_THREADS
6969 res = waitid(idtype, id, &si, options);
6970 Py_END_ALLOW_THREADS
6971 if (res == -1)
6972 return posix_error();
6973
6974 if (si.si_pid == 0)
6975 Py_RETURN_NONE;
6976
6977 result = PyStructSequence_New(&WaitidResultType);
6978 if (!result)
6979 return NULL;
6980
6981 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6982 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6983 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6984 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6985 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6986 if (PyErr_Occurred()) {
6987 Py_DECREF(result);
6988 return NULL;
6989 }
6990
6991 return result;
6992}
6993#endif
6994
Guido van Rossumb6775db1994-08-01 11:34:53 +00006995#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006996PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006997"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006998Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006999
Barry Warsaw53699e91996-12-10 23:23:01 +00007000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007001posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007002{
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 pid_t pid;
7004 int options;
7005 WAIT_TYPE status;
7006 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007007
Victor Stinner8c62be82010-05-06 00:08:46 +00007008 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7009 return NULL;
7010 Py_BEGIN_ALLOW_THREADS
7011 pid = waitpid(pid, &status, options);
7012 Py_END_ALLOW_THREADS
7013 if (pid == -1)
7014 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007015
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007017}
7018
Tim Petersab034fa2002-02-01 11:27:43 +00007019#elif defined(HAVE_CWAIT)
7020
7021/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007022PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007023"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007024"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007025
7026static PyObject *
7027posix_waitpid(PyObject *self, PyObject *args)
7028{
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 Py_intptr_t pid;
7030 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007031
Victor Stinner8c62be82010-05-06 00:08:46 +00007032 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7033 return NULL;
7034 Py_BEGIN_ALLOW_THREADS
7035 pid = _cwait(&status, pid, options);
7036 Py_END_ALLOW_THREADS
7037 if (pid == -1)
7038 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007039
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 /* shift the status left a byte so this is more like the POSIX waitpid */
7041 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007042}
7043#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007044
Guido van Rossumad0ee831995-03-01 10:34:45 +00007045#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007046PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007047"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007048Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007049
Barry Warsaw53699e91996-12-10 23:23:01 +00007050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007051posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007052{
Victor Stinner8c62be82010-05-06 00:08:46 +00007053 pid_t pid;
7054 WAIT_TYPE status;
7055 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007056
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 Py_BEGIN_ALLOW_THREADS
7058 pid = wait(&status);
7059 Py_END_ALLOW_THREADS
7060 if (pid == -1)
7061 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007062
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007064}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007065#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007067
Larry Hastings9cf065c2012-06-22 16:30:09 -07007068#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7069PyDoc_STRVAR(readlink__doc__,
7070"readlink(path, *, dir_fd=None) -> path\n\n\
7071Return a string representing the path to which the symbolic link points.\n\
7072\n\
7073If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7074 and path should be relative; path will then be relative to that directory.\n\
7075dir_fd may not be implemented on your platform.\n\
7076 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007077#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007078
Guido van Rossumb6775db1994-08-01 11:34:53 +00007079#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007080
Barry Warsaw53699e91996-12-10 23:23:01 +00007081static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007082posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007083{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084 path_t path;
7085 int dir_fd = DEFAULT_DIR_FD;
7086 char buffer[MAXPATHLEN];
7087 ssize_t length;
7088 PyObject *return_value = NULL;
7089 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007090
Larry Hastings9cf065c2012-06-22 16:30:09 -07007091 memset(&path, 0, sizeof(path));
7092 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7093 path_converter, &path,
7094#ifdef HAVE_READLINKAT
7095 dir_fd_converter, &dir_fd
7096#else
7097 dir_fd_unavailable, &dir_fd
7098#endif
7099 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007101
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007103#ifdef HAVE_READLINKAT
7104 if (dir_fd != DEFAULT_DIR_FD)
7105 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007106 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007107#endif
7108 length = readlink(path.narrow, buffer, sizeof(buffer));
7109 Py_END_ALLOW_THREADS
7110
7111 if (length < 0) {
7112 return_value = path_posix_error("readlink", &path);
7113 goto exit;
7114 }
7115
7116 if (PyUnicode_Check(path.object))
7117 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7118 else
7119 return_value = PyBytes_FromStringAndSize(buffer, length);
7120exit:
7121 path_cleanup(&path);
7122 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007123}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124
7125
Guido van Rossumb6775db1994-08-01 11:34:53 +00007126#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007128
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007130PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7132Create a symbolic link pointing to src named dst.\n\n\
7133target_is_directory is required on Windows if the target is to be\n\
7134 interpreted as a directory. (On Windows, symlink requires\n\
7135 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7136 target_is_directory is ignored on non-Windows platforms.\n\
7137\n\
7138If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7139 and path should be relative; path will then be relative to that directory.\n\
7140dir_fd may not be implemented on your platform.\n\
7141 If it is unavailable, using it will raise a NotImplementedError.");
7142
7143#if defined(MS_WINDOWS)
7144
7145/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7146static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7147static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7148static int
7149check_CreateSymbolicLink()
7150{
7151 HINSTANCE hKernel32;
7152 /* only recheck */
7153 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7154 return 1;
7155 hKernel32 = GetModuleHandleW(L"KERNEL32");
7156 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7157 "CreateSymbolicLinkW");
7158 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7159 "CreateSymbolicLinkA");
7160 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7161}
7162
7163#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007164
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007165static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007167{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007168 path_t src;
7169 path_t dst;
7170 int dir_fd = DEFAULT_DIR_FD;
7171 int target_is_directory = 0;
7172 static char *keywords[] = {"src", "dst", "target_is_directory",
7173 "dir_fd", NULL};
7174 PyObject *return_value;
7175#ifdef MS_WINDOWS
7176 DWORD result;
7177#else
7178 int result;
7179#endif
7180
7181 memset(&src, 0, sizeof(src));
7182 src.argument_name = "src";
7183 memset(&dst, 0, sizeof(dst));
7184 dst.argument_name = "dst";
7185
7186#ifdef MS_WINDOWS
7187 if (!check_CreateSymbolicLink()) {
7188 PyErr_SetString(PyExc_NotImplementedError,
7189 "CreateSymbolicLink functions not found");
7190 return NULL;
7191 }
7192 if (!win32_can_symlink) {
7193 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7194 return NULL;
7195 }
7196#endif
7197
7198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7199 keywords,
7200 path_converter, &src,
7201 path_converter, &dst,
7202 &target_is_directory,
7203#ifdef HAVE_SYMLINKAT
7204 dir_fd_converter, &dir_fd
7205#else
7206 dir_fd_unavailable, &dir_fd
7207#endif
7208 ))
7209 return NULL;
7210
7211 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7212 PyErr_SetString(PyExc_ValueError,
7213 "symlink: src and dst must be the same type");
7214 return_value = NULL;
7215 goto exit;
7216 }
7217
7218#ifdef MS_WINDOWS
7219 Py_BEGIN_ALLOW_THREADS
7220 if (dst.wide)
7221 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7222 target_is_directory);
7223 else
7224 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7225 target_is_directory);
7226 Py_END_ALLOW_THREADS
7227
7228 if (!result) {
7229 return_value = win32_error_object("symlink", src.object);
7230 goto exit;
7231 }
7232
7233#else
7234
7235 Py_BEGIN_ALLOW_THREADS
7236#if HAVE_SYMLINKAT
7237 if (dir_fd != DEFAULT_DIR_FD)
7238 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7239 else
7240#endif
7241 result = symlink(src.narrow, dst.narrow);
7242 Py_END_ALLOW_THREADS
7243
7244 if (result) {
7245 return_value = path_error("symlink", &dst);
7246 goto exit;
7247 }
7248#endif
7249
7250 return_value = Py_None;
7251 Py_INCREF(Py_None);
7252 goto exit; /* silence "unused label" warning */
7253exit:
7254 path_cleanup(&src);
7255 path_cleanup(&dst);
7256 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007257}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007258
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007259#endif /* HAVE_SYMLINK */
7260
Larry Hastings9cf065c2012-06-22 16:30:09 -07007261
Brian Curtind40e6f72010-07-08 21:39:08 +00007262#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7263
Brian Curtind40e6f72010-07-08 21:39:08 +00007264static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007266{
7267 wchar_t *path;
7268 DWORD n_bytes_returned;
7269 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007270 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007272 HANDLE reparse_point_handle;
7273
7274 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7275 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7276 wchar_t *print_name;
7277
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278 static char *keywords[] = {"path", "dir_fd", NULL};
7279
7280 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7281 &po,
7282 dir_fd_unavailable, &dir_fd
7283 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007284 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007285
Victor Stinnereb5657a2011-09-30 01:44:27 +02007286 path = PyUnicode_AsUnicode(po);
7287 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007288 return NULL;
7289
7290 /* First get a handle to the reparse point */
7291 Py_BEGIN_ALLOW_THREADS
7292 reparse_point_handle = CreateFileW(
7293 path,
7294 0,
7295 0,
7296 0,
7297 OPEN_EXISTING,
7298 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7299 0);
7300 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007301
Brian Curtind40e6f72010-07-08 21:39:08 +00007302 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007303 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007304
Brian Curtind40e6f72010-07-08 21:39:08 +00007305 Py_BEGIN_ALLOW_THREADS
7306 /* New call DeviceIoControl to read the reparse point */
7307 io_result = DeviceIoControl(
7308 reparse_point_handle,
7309 FSCTL_GET_REPARSE_POINT,
7310 0, 0, /* in buffer */
7311 target_buffer, sizeof(target_buffer),
7312 &n_bytes_returned,
7313 0 /* we're not using OVERLAPPED_IO */
7314 );
7315 CloseHandle(reparse_point_handle);
7316 Py_END_ALLOW_THREADS
7317
7318 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007319 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007320
7321 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7322 {
7323 PyErr_SetString(PyExc_ValueError,
7324 "not a symbolic link");
7325 return NULL;
7326 }
Brian Curtin74e45612010-07-09 15:58:59 +00007327 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7328 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7329
7330 result = PyUnicode_FromWideChar(print_name,
7331 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007332 return result;
7333}
7334
7335#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7336
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007337
7338#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7340static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007341system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007342{
7343 ULONG value = 0;
7344
7345 Py_BEGIN_ALLOW_THREADS
7346 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7347 Py_END_ALLOW_THREADS
7348
7349 return value;
7350}
7351
7352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007353posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007354{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007355 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00007356 return Py_BuildValue("ddddd",
7357 (double)0 /* t.tms_utime / HZ */,
7358 (double)0 /* t.tms_stime / HZ */,
7359 (double)0 /* t.tms_cutime / HZ */,
7360 (double)0 /* t.tms_cstime / HZ */,
7361 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007362}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007363#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007364#define NEED_TICKS_PER_SECOND
7365static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007366static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007367posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007368{
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 struct tms t;
7370 clock_t c;
7371 errno = 0;
7372 c = times(&t);
7373 if (c == (clock_t) -1)
7374 return posix_error();
7375 return Py_BuildValue("ddddd",
7376 (double)t.tms_utime / ticks_per_second,
7377 (double)t.tms_stime / ticks_per_second,
7378 (double)t.tms_cutime / ticks_per_second,
7379 (double)t.tms_cstime / ticks_per_second,
7380 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007381}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007382#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007383#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007384
7385
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007386#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007387#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00007388static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007389posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007390{
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 FILETIME create, exit, kernel, user;
7392 HANDLE hProc;
7393 hProc = GetCurrentProcess();
7394 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7395 /* The fields of a FILETIME structure are the hi and lo part
7396 of a 64-bit value expressed in 100 nanosecond units.
7397 1e7 is one second in such units; 1e-7 the inverse.
7398 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7399 */
7400 return Py_BuildValue(
7401 "ddddd",
7402 (double)(user.dwHighDateTime*429.4967296 +
7403 user.dwLowDateTime*1e-7),
7404 (double)(kernel.dwHighDateTime*429.4967296 +
7405 kernel.dwLowDateTime*1e-7),
7406 (double)0,
7407 (double)0,
7408 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007409}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007410#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007411
7412#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007413PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007414"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007415Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007416#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007418
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007419#ifdef HAVE_GETSID
7420PyDoc_STRVAR(posix_getsid__doc__,
7421"getsid(pid) -> sid\n\n\
7422Call the system call getsid().");
7423
7424static PyObject *
7425posix_getsid(PyObject *self, PyObject *args)
7426{
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 pid_t pid;
7428 int sid;
7429 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7430 return NULL;
7431 sid = getsid(pid);
7432 if (sid < 0)
7433 return posix_error();
7434 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007435}
7436#endif /* HAVE_GETSID */
7437
7438
Guido van Rossumb6775db1994-08-01 11:34:53 +00007439#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007440PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007441"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007442Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007443
Barry Warsaw53699e91996-12-10 23:23:01 +00007444static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007445posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007446{
Victor Stinner8c62be82010-05-06 00:08:46 +00007447 if (setsid() < 0)
7448 return posix_error();
7449 Py_INCREF(Py_None);
7450 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007451}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007453
Guido van Rossumb6775db1994-08-01 11:34:53 +00007454#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007455PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007456"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007457Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007458
Barry Warsaw53699e91996-12-10 23:23:01 +00007459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007460posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007461{
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 pid_t pid;
7463 int pgrp;
7464 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7465 return NULL;
7466 if (setpgid(pid, pgrp) < 0)
7467 return posix_error();
7468 Py_INCREF(Py_None);
7469 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007470}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007471#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007473
Guido van Rossumb6775db1994-08-01 11:34:53 +00007474#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007475PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007476"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007477Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007478
Barry Warsaw53699e91996-12-10 23:23:01 +00007479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007480posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007481{
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 int fd;
7483 pid_t pgid;
7484 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7485 return NULL;
7486 pgid = tcgetpgrp(fd);
7487 if (pgid < 0)
7488 return posix_error();
7489 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007490}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007491#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007493
Guido van Rossumb6775db1994-08-01 11:34:53 +00007494#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007495PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007496"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007497Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007498
Barry Warsaw53699e91996-12-10 23:23:01 +00007499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007500posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007501{
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 int fd;
7503 pid_t pgid;
7504 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7505 return NULL;
7506 if (tcsetpgrp(fd, pgid) < 0)
7507 return posix_error();
7508 Py_INCREF(Py_None);
7509 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007510}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007511#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007512
Guido van Rossum687dd131993-05-17 08:34:16 +00007513/* Functions acting on file descriptors */
7514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007515PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007516"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7517Open a file for low level IO. Returns a file handle (integer).\n\
7518\n\
7519If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7520 and path should be relative; path will then be relative to that directory.\n\
7521dir_fd may not be implemented on your platform.\n\
7522 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007523
Barry Warsaw53699e91996-12-10 23:23:01 +00007524static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007525posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007526{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007527 path_t path;
7528 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007530 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007532 PyObject *return_value = NULL;
7533 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007534
Larry Hastings9cf065c2012-06-22 16:30:09 -07007535 memset(&path, 0, sizeof(path));
7536 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7537 path_converter, &path,
7538 &flags, &mode,
7539#ifdef HAVE_OPENAT
7540 dir_fd_converter, &dir_fd
7541#else
7542 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007543#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007544 ))
7545 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007546
Victor Stinner8c62be82010-05-06 00:08:46 +00007547 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007548#ifdef MS_WINDOWS
7549 if (path.wide)
7550 fd = _wopen(path.wide, flags, mode);
7551 else
7552#endif
7553#ifdef HAVE_OPENAT
7554 if (dir_fd != DEFAULT_DIR_FD)
7555 fd = openat(dir_fd, path.narrow, flags, mode);
7556 else
7557#endif
7558 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007559 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007560
Larry Hastings9cf065c2012-06-22 16:30:09 -07007561 if (fd == -1) {
7562#ifdef MS_WINDOWS
7563 /* force use of posix_error here for exact backwards compatibility */
7564 if (path.wide)
7565 return_value = posix_error();
7566 else
7567#endif
7568 return_value = path_error("open", &path);
7569 goto exit;
7570 }
7571
7572 return_value = PyLong_FromLong((long)fd);
7573
7574exit:
7575 path_cleanup(&path);
7576 return return_value;
7577}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007579PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007580"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007581Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007582
Barry Warsaw53699e91996-12-10 23:23:01 +00007583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007584posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007585{
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 int fd, res;
7587 if (!PyArg_ParseTuple(args, "i:close", &fd))
7588 return NULL;
7589 if (!_PyVerify_fd(fd))
7590 return posix_error();
7591 Py_BEGIN_ALLOW_THREADS
7592 res = close(fd);
7593 Py_END_ALLOW_THREADS
7594 if (res < 0)
7595 return posix_error();
7596 Py_INCREF(Py_None);
7597 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007598}
7599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007600
Victor Stinner8c62be82010-05-06 00:08:46 +00007601PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007602"closerange(fd_low, fd_high)\n\n\
7603Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7604
7605static PyObject *
7606posix_closerange(PyObject *self, PyObject *args)
7607{
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 int fd_from, fd_to, i;
7609 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7610 return NULL;
7611 Py_BEGIN_ALLOW_THREADS
7612 for (i = fd_from; i < fd_to; i++)
7613 if (_PyVerify_fd(i))
7614 close(i);
7615 Py_END_ALLOW_THREADS
7616 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007617}
7618
7619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007620PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007621"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007622Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007623
Barry Warsaw53699e91996-12-10 23:23:01 +00007624static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007625posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007626{
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 int fd;
7628 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7629 return NULL;
7630 if (!_PyVerify_fd(fd))
7631 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 if (fd < 0)
7634 return posix_error();
7635 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007636}
7637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007639PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007640"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007641Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007642
Barry Warsaw53699e91996-12-10 23:23:01 +00007643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007644posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007645{
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 int fd, fd2, res;
7647 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7648 return NULL;
7649 if (!_PyVerify_fd_dup2(fd, fd2))
7650 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 if (res < 0)
7653 return posix_error();
7654 Py_INCREF(Py_None);
7655 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007656}
7657
Ross Lagerwall7807c352011-03-17 20:20:30 +02007658#ifdef HAVE_LOCKF
7659PyDoc_STRVAR(posix_lockf__doc__,
7660"lockf(fd, cmd, len)\n\n\
7661Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7662fd is an open file descriptor.\n\
7663cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7664F_TEST.\n\
7665len specifies the section of the file to lock.");
7666
7667static PyObject *
7668posix_lockf(PyObject *self, PyObject *args)
7669{
7670 int fd, cmd, res;
7671 off_t len;
7672 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7673 &fd, &cmd, _parse_off_t, &len))
7674 return NULL;
7675
7676 Py_BEGIN_ALLOW_THREADS
7677 res = lockf(fd, cmd, len);
7678 Py_END_ALLOW_THREADS
7679
7680 if (res < 0)
7681 return posix_error();
7682
7683 Py_RETURN_NONE;
7684}
7685#endif
7686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007688PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007689"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007690Set the current position of a file descriptor.\n\
7691Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007692
Barry Warsaw53699e91996-12-10 23:23:01 +00007693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007694posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007695{
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007697#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007699#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007701#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007702 PyObject *posobj;
7703 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007705#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7707 switch (how) {
7708 case 0: how = SEEK_SET; break;
7709 case 1: how = SEEK_CUR; break;
7710 case 2: how = SEEK_END; break;
7711 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007712#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007713
Ross Lagerwall8e749672011-03-17 21:54:07 +02007714#if !defined(HAVE_LARGEFILE_SUPPORT)
7715 pos = PyLong_AsLong(posobj);
7716#else
7717 pos = PyLong_AsLongLong(posobj);
7718#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 if (PyErr_Occurred())
7720 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007721
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 if (!_PyVerify_fd(fd))
7723 return posix_error();
7724 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007725#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007727#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007729#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 Py_END_ALLOW_THREADS
7731 if (res < 0)
7732 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007733
7734#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007736#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007738#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007739}
7740
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007742PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007743"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007744Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007745
Barry Warsaw53699e91996-12-10 23:23:01 +00007746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007747posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007748{
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 int fd, size;
7750 Py_ssize_t n;
7751 PyObject *buffer;
7752 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7753 return NULL;
7754 if (size < 0) {
7755 errno = EINVAL;
7756 return posix_error();
7757 }
7758 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7759 if (buffer == NULL)
7760 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007761 if (!_PyVerify_fd(fd)) {
7762 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007764 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 Py_BEGIN_ALLOW_THREADS
7766 n = read(fd, PyBytes_AS_STRING(buffer), size);
7767 Py_END_ALLOW_THREADS
7768 if (n < 0) {
7769 Py_DECREF(buffer);
7770 return posix_error();
7771 }
7772 if (n != size)
7773 _PyBytes_Resize(&buffer, n);
7774 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007775}
7776
Ross Lagerwall7807c352011-03-17 20:20:30 +02007777#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7778 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007779static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007780iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7781{
7782 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007783 Py_ssize_t blen, total = 0;
7784
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007785 *iov = PyMem_New(struct iovec, cnt);
7786 if (*iov == NULL) {
7787 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007788 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007789 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007790
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007791 *buf = PyMem_New(Py_buffer, cnt);
7792 if (*buf == NULL) {
7793 PyMem_Del(*iov);
7794 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007795 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007796 }
7797
7798 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007799 PyObject *item = PySequence_GetItem(seq, i);
7800 if (item == NULL)
7801 goto fail;
7802 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7803 Py_DECREF(item);
7804 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007805 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007806 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007807 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007808 blen = (*buf)[i].len;
7809 (*iov)[i].iov_len = blen;
7810 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007811 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007812 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007813
7814fail:
7815 PyMem_Del(*iov);
7816 for (j = 0; j < i; j++) {
7817 PyBuffer_Release(&(*buf)[j]);
7818 }
7819 PyMem_Del(*buf);
7820 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007821}
7822
7823static void
7824iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7825{
7826 int i;
7827 PyMem_Del(iov);
7828 for (i = 0; i < cnt; i++) {
7829 PyBuffer_Release(&buf[i]);
7830 }
7831 PyMem_Del(buf);
7832}
7833#endif
7834
Ross Lagerwall7807c352011-03-17 20:20:30 +02007835#ifdef HAVE_READV
7836PyDoc_STRVAR(posix_readv__doc__,
7837"readv(fd, buffers) -> bytesread\n\n\
7838Read from a file descriptor into a number of writable buffers. buffers\n\
7839is an arbitrary sequence of writable buffers.\n\
7840Returns the total number of bytes read.");
7841
7842static PyObject *
7843posix_readv(PyObject *self, PyObject *args)
7844{
7845 int fd, cnt;
7846 Py_ssize_t n;
7847 PyObject *seq;
7848 struct iovec *iov;
7849 Py_buffer *buf;
7850
7851 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7852 return NULL;
7853 if (!PySequence_Check(seq)) {
7854 PyErr_SetString(PyExc_TypeError,
7855 "readv() arg 2 must be a sequence");
7856 return NULL;
7857 }
7858 cnt = PySequence_Size(seq);
7859
7860 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7861 return NULL;
7862
7863 Py_BEGIN_ALLOW_THREADS
7864 n = readv(fd, iov, cnt);
7865 Py_END_ALLOW_THREADS
7866
7867 iov_cleanup(iov, buf, cnt);
7868 return PyLong_FromSsize_t(n);
7869}
7870#endif
7871
7872#ifdef HAVE_PREAD
7873PyDoc_STRVAR(posix_pread__doc__,
7874"pread(fd, buffersize, offset) -> string\n\n\
7875Read from a file descriptor, fd, at a position of offset. It will read up\n\
7876to buffersize number of bytes. The file offset remains unchanged.");
7877
7878static PyObject *
7879posix_pread(PyObject *self, PyObject *args)
7880{
7881 int fd, size;
7882 off_t offset;
7883 Py_ssize_t n;
7884 PyObject *buffer;
7885 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7886 return NULL;
7887
7888 if (size < 0) {
7889 errno = EINVAL;
7890 return posix_error();
7891 }
7892 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7893 if (buffer == NULL)
7894 return NULL;
7895 if (!_PyVerify_fd(fd)) {
7896 Py_DECREF(buffer);
7897 return posix_error();
7898 }
7899 Py_BEGIN_ALLOW_THREADS
7900 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7901 Py_END_ALLOW_THREADS
7902 if (n < 0) {
7903 Py_DECREF(buffer);
7904 return posix_error();
7905 }
7906 if (n != size)
7907 _PyBytes_Resize(&buffer, n);
7908 return buffer;
7909}
7910#endif
7911
7912PyDoc_STRVAR(posix_write__doc__,
7913"write(fd, string) -> byteswritten\n\n\
7914Write a string to a file descriptor.");
7915
7916static PyObject *
7917posix_write(PyObject *self, PyObject *args)
7918{
7919 Py_buffer pbuf;
7920 int fd;
7921 Py_ssize_t size, len;
7922
7923 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7924 return NULL;
7925 if (!_PyVerify_fd(fd)) {
7926 PyBuffer_Release(&pbuf);
7927 return posix_error();
7928 }
7929 len = pbuf.len;
7930 Py_BEGIN_ALLOW_THREADS
7931#if defined(MS_WIN64) || defined(MS_WINDOWS)
7932 if (len > INT_MAX)
7933 len = INT_MAX;
7934 size = write(fd, pbuf.buf, (int)len);
7935#else
7936 size = write(fd, pbuf.buf, len);
7937#endif
7938 Py_END_ALLOW_THREADS
7939 PyBuffer_Release(&pbuf);
7940 if (size < 0)
7941 return posix_error();
7942 return PyLong_FromSsize_t(size);
7943}
7944
7945#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007946PyDoc_STRVAR(posix_sendfile__doc__,
7947"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7948sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7949 -> byteswritten\n\
7950Copy nbytes bytes from file descriptor in to file descriptor out.");
7951
7952static PyObject *
7953posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7954{
7955 int in, out;
7956 Py_ssize_t ret;
7957 off_t offset;
7958
7959#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7960#ifndef __APPLE__
7961 Py_ssize_t len;
7962#endif
7963 PyObject *headers = NULL, *trailers = NULL;
7964 Py_buffer *hbuf, *tbuf;
7965 off_t sbytes;
7966 struct sf_hdtr sf;
7967 int flags = 0;
7968 sf.headers = NULL;
7969 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007970 static char *keywords[] = {"out", "in",
7971 "offset", "count",
7972 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007973
7974#ifdef __APPLE__
7975 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007976 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007977#else
7978 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007979 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007980#endif
7981 &headers, &trailers, &flags))
7982 return NULL;
7983 if (headers != NULL) {
7984 if (!PySequence_Check(headers)) {
7985 PyErr_SetString(PyExc_TypeError,
7986 "sendfile() headers must be a sequence or None");
7987 return NULL;
7988 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007989 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007990 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007991 if (sf.hdr_cnt > 0 &&
7992 !(i = iov_setup(&(sf.headers), &hbuf,
7993 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007994 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007995#ifdef __APPLE__
7996 sbytes += i;
7997#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007998 }
7999 }
8000 if (trailers != NULL) {
8001 if (!PySequence_Check(trailers)) {
8002 PyErr_SetString(PyExc_TypeError,
8003 "sendfile() trailers must be a sequence or None");
8004 return NULL;
8005 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008006 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008007 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008008 if (sf.trl_cnt > 0 &&
8009 !(i = iov_setup(&(sf.trailers), &tbuf,
8010 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008011 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008012#ifdef __APPLE__
8013 sbytes += i;
8014#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015 }
8016 }
8017
8018 Py_BEGIN_ALLOW_THREADS
8019#ifdef __APPLE__
8020 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8021#else
8022 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8023#endif
8024 Py_END_ALLOW_THREADS
8025
8026 if (sf.headers != NULL)
8027 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8028 if (sf.trailers != NULL)
8029 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8030
8031 if (ret < 0) {
8032 if ((errno == EAGAIN) || (errno == EBUSY)) {
8033 if (sbytes != 0) {
8034 // some data has been sent
8035 goto done;
8036 }
8037 else {
8038 // no data has been sent; upper application is supposed
8039 // to retry on EAGAIN or EBUSY
8040 return posix_error();
8041 }
8042 }
8043 return posix_error();
8044 }
8045 goto done;
8046
8047done:
8048 #if !defined(HAVE_LARGEFILE_SUPPORT)
8049 return Py_BuildValue("l", sbytes);
8050 #else
8051 return Py_BuildValue("L", sbytes);
8052 #endif
8053
8054#else
8055 Py_ssize_t count;
8056 PyObject *offobj;
8057 static char *keywords[] = {"out", "in",
8058 "offset", "count", NULL};
8059 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8060 keywords, &out, &in, &offobj, &count))
8061 return NULL;
8062#ifdef linux
8063 if (offobj == Py_None) {
8064 Py_BEGIN_ALLOW_THREADS
8065 ret = sendfile(out, in, NULL, count);
8066 Py_END_ALLOW_THREADS
8067 if (ret < 0)
8068 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008069 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 }
8071#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008072 if (!_parse_off_t(offobj, &offset))
8073 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 Py_BEGIN_ALLOW_THREADS
8075 ret = sendfile(out, in, &offset, count);
8076 Py_END_ALLOW_THREADS
8077 if (ret < 0)
8078 return posix_error();
8079 return Py_BuildValue("n", ret);
8080#endif
8081}
8082#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008083
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008084PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008085"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008086Like stat(), but for an open file descriptor.\n\
8087Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008088
Barry Warsaw53699e91996-12-10 23:23:01 +00008089static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008090posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008091{
Victor Stinner8c62be82010-05-06 00:08:46 +00008092 int fd;
8093 STRUCT_STAT st;
8094 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008095 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008097#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 /* on OpenVMS we must ensure that all bytes are written to the file */
8099 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008100#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 if (!_PyVerify_fd(fd))
8102 return posix_error();
8103 Py_BEGIN_ALLOW_THREADS
8104 res = FSTAT(fd, &st);
8105 Py_END_ALLOW_THREADS
8106 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008109#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008111#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 }
Tim Peters5aa91602002-01-30 05:46:57 +00008113
Victor Stinner4195b5c2012-02-08 23:03:19 +01008114 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008115}
8116
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008117PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008118"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008119Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008120connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008121
8122static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008123posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008124{
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 int fd;
8126 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8127 return NULL;
8128 if (!_PyVerify_fd(fd))
8129 return PyBool_FromLong(0);
8130 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008131}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008132
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008133#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008134PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008135"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008136Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008137
Barry Warsaw53699e91996-12-10 23:23:01 +00008138static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008139posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008140{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008141#if defined(PYOS_OS2)
8142 HFILE read, write;
8143 APIRET rc;
8144
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008145 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008146 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008147 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008148
8149 return Py_BuildValue("(ii)", read, write);
8150#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008151#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 int fds[2];
8153 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 if (res != 0)
8156 return posix_error();
8157 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008158#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 HANDLE read, write;
8160 int read_fd, write_fd;
8161 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008162 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (!ok)
8164 return win32_error("CreatePipe", NULL);
8165 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8166 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8167 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008168#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008169#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008170}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008171#endif /* HAVE_PIPE */
8172
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008173#ifdef HAVE_PIPE2
8174PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008175"pipe2(flags) -> (read_end, write_end)\n\n\
8176Create a pipe with flags set atomically.\n\
8177flags can be constructed by ORing together one or more of these values:\n\
8178O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008179");
8180
8181static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008182posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008183{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008184 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008185 int fds[2];
8186 int res;
8187
Charles-François Natali368f34b2011-06-06 19:49:47 +02008188 flags = PyLong_AsLong(arg);
8189 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008190 return NULL;
8191
8192 res = pipe2(fds, flags);
8193 if (res != 0)
8194 return posix_error();
8195 return Py_BuildValue("(ii)", fds[0], fds[1]);
8196}
8197#endif /* HAVE_PIPE2 */
8198
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199#ifdef HAVE_WRITEV
8200PyDoc_STRVAR(posix_writev__doc__,
8201"writev(fd, buffers) -> byteswritten\n\n\
8202Write the contents of buffers to a file descriptor, where buffers is an\n\
8203arbitrary sequence of buffers.\n\
8204Returns the total bytes written.");
8205
8206static PyObject *
8207posix_writev(PyObject *self, PyObject *args)
8208{
8209 int fd, cnt;
8210 Py_ssize_t res;
8211 PyObject *seq;
8212 struct iovec *iov;
8213 Py_buffer *buf;
8214 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8215 return NULL;
8216 if (!PySequence_Check(seq)) {
8217 PyErr_SetString(PyExc_TypeError,
8218 "writev() arg 2 must be a sequence");
8219 return NULL;
8220 }
8221 cnt = PySequence_Size(seq);
8222
8223 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8224 return NULL;
8225 }
8226
8227 Py_BEGIN_ALLOW_THREADS
8228 res = writev(fd, iov, cnt);
8229 Py_END_ALLOW_THREADS
8230
8231 iov_cleanup(iov, buf, cnt);
8232 return PyLong_FromSsize_t(res);
8233}
8234#endif
8235
8236#ifdef HAVE_PWRITE
8237PyDoc_STRVAR(posix_pwrite__doc__,
8238"pwrite(fd, string, offset) -> byteswritten\n\n\
8239Write string to a file descriptor, fd, from offset, leaving the file\n\
8240offset unchanged.");
8241
8242static PyObject *
8243posix_pwrite(PyObject *self, PyObject *args)
8244{
8245 Py_buffer pbuf;
8246 int fd;
8247 off_t offset;
8248 Py_ssize_t size;
8249
8250 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8251 return NULL;
8252
8253 if (!_PyVerify_fd(fd)) {
8254 PyBuffer_Release(&pbuf);
8255 return posix_error();
8256 }
8257 Py_BEGIN_ALLOW_THREADS
8258 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8259 Py_END_ALLOW_THREADS
8260 PyBuffer_Release(&pbuf);
8261 if (size < 0)
8262 return posix_error();
8263 return PyLong_FromSsize_t(size);
8264}
8265#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008266
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008267#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008268PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008269"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8270Create a FIFO (a POSIX named pipe).\n\
8271\n\
8272If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8273 and path should be relative; path will then be relative to that directory.\n\
8274dir_fd may not be implemented on your platform.\n\
8275 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008276
Barry Warsaw53699e91996-12-10 23:23:01 +00008277static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008278posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008279{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008280 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008282 int dir_fd = DEFAULT_DIR_FD;
8283 int result;
8284 PyObject *return_value = NULL;
8285 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8286
8287 memset(&path, 0, sizeof(path));
8288 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8289 path_converter, &path,
8290 &mode,
8291#ifdef HAVE_MKFIFOAT
8292 dir_fd_converter, &dir_fd
8293#else
8294 dir_fd_unavailable, &dir_fd
8295#endif
8296 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008298
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008300#ifdef HAVE_MKFIFOAT
8301 if (dir_fd != DEFAULT_DIR_FD)
8302 result = mkfifoat(dir_fd, path.narrow, mode);
8303 else
8304#endif
8305 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008306 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008307
8308 if (result < 0) {
8309 return_value = posix_error();
8310 goto exit;
8311 }
8312
8313 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008315
8316exit:
8317 path_cleanup(&path);
8318 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008319}
8320#endif
8321
Neal Norwitz11690112002-07-30 01:08:28 +00008322#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008323PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008324"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008325Create a filesystem node (file, device special file or named pipe)\n\
8326named filename. mode specifies both the permissions to use and the\n\
8327type of node to be created, being combined (bitwise OR) with one of\n\
8328S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008329device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008330os.makedev()), otherwise it is ignored.\n\
8331\n\
8332If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8333 and path should be relative; path will then be relative to that directory.\n\
8334dir_fd may not be implemented on your platform.\n\
8335 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008336
8337
8338static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008339posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008340{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 path_t path;
8342 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008344 int dir_fd = DEFAULT_DIR_FD;
8345 int result;
8346 PyObject *return_value = NULL;
8347 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8348
8349 memset(&path, 0, sizeof(path));
8350 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8351 path_converter, &path,
8352 &mode, &device,
8353#ifdef HAVE_MKNODAT
8354 dir_fd_converter, &dir_fd
8355#else
8356 dir_fd_unavailable, &dir_fd
8357#endif
8358 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008360
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008362#ifdef HAVE_MKNODAT
8363 if (dir_fd != DEFAULT_DIR_FD)
8364 result = mknodat(dir_fd, path.narrow, mode, device);
8365 else
8366#endif
8367 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008369
8370 if (result < 0) {
8371 return_value = posix_error();
8372 goto exit;
8373 }
8374
8375 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008377
8378exit:
8379 path_cleanup(&path);
8380 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008381}
8382#endif
8383
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008384#ifdef HAVE_DEVICE_MACROS
8385PyDoc_STRVAR(posix_major__doc__,
8386"major(device) -> major number\n\
8387Extracts a device major number from a raw device number.");
8388
8389static PyObject *
8390posix_major(PyObject *self, PyObject *args)
8391{
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 int device;
8393 if (!PyArg_ParseTuple(args, "i:major", &device))
8394 return NULL;
8395 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008396}
8397
8398PyDoc_STRVAR(posix_minor__doc__,
8399"minor(device) -> minor number\n\
8400Extracts a device minor number from a raw device number.");
8401
8402static PyObject *
8403posix_minor(PyObject *self, PyObject *args)
8404{
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 int device;
8406 if (!PyArg_ParseTuple(args, "i:minor", &device))
8407 return NULL;
8408 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008409}
8410
8411PyDoc_STRVAR(posix_makedev__doc__,
8412"makedev(major, minor) -> device number\n\
8413Composes a raw device number from the major and minor device numbers.");
8414
8415static PyObject *
8416posix_makedev(PyObject *self, PyObject *args)
8417{
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 int major, minor;
8419 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8420 return NULL;
8421 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008422}
8423#endif /* device macros */
8424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008425
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008426#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008427PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008428"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008429Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008430
Barry Warsaw53699e91996-12-10 23:23:01 +00008431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008432posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008433{
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 int fd;
8435 off_t length;
8436 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008437
Ross Lagerwall7807c352011-03-17 20:20:30 +02008438 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008440
Victor Stinner8c62be82010-05-06 00:08:46 +00008441 Py_BEGIN_ALLOW_THREADS
8442 res = ftruncate(fd, length);
8443 Py_END_ALLOW_THREADS
8444 if (res < 0)
8445 return posix_error();
8446 Py_INCREF(Py_None);
8447 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008448}
8449#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008450
Ross Lagerwall7807c352011-03-17 20:20:30 +02008451#ifdef HAVE_TRUNCATE
8452PyDoc_STRVAR(posix_truncate__doc__,
8453"truncate(path, length)\n\n\
8454Truncate the file given by path to length bytes.");
8455
8456static PyObject *
8457posix_truncate(PyObject *self, PyObject *args)
8458{
8459 PyObject *opath;
8460 const char *path;
8461 off_t length;
8462 int res;
8463
8464 if (!PyArg_ParseTuple(args, "O&O&:truncate",
8465 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
8466 return NULL;
8467 path = PyBytes_AsString(opath);
8468
8469 Py_BEGIN_ALLOW_THREADS
8470 res = truncate(path, length);
8471 Py_END_ALLOW_THREADS
8472 Py_DECREF(opath);
8473 if (res < 0)
8474 return posix_error();
8475 Py_RETURN_NONE;
8476}
8477#endif
8478
8479#ifdef HAVE_POSIX_FALLOCATE
8480PyDoc_STRVAR(posix_posix_fallocate__doc__,
8481"posix_fallocate(fd, offset, len)\n\n\
8482Ensures that enough disk space is allocated for the file specified by fd\n\
8483starting from offset and continuing for len bytes.");
8484
8485static PyObject *
8486posix_posix_fallocate(PyObject *self, PyObject *args)
8487{
8488 off_t len, offset;
8489 int res, fd;
8490
8491 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8492 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8493 return NULL;
8494
8495 Py_BEGIN_ALLOW_THREADS
8496 res = posix_fallocate(fd, offset, len);
8497 Py_END_ALLOW_THREADS
8498 if (res != 0) {
8499 errno = res;
8500 return posix_error();
8501 }
8502 Py_RETURN_NONE;
8503}
8504#endif
8505
8506#ifdef HAVE_POSIX_FADVISE
8507PyDoc_STRVAR(posix_posix_fadvise__doc__,
8508"posix_fadvise(fd, offset, len, advice)\n\n\
8509Announces an intention to access data in a specific pattern thus allowing\n\
8510the kernel to make optimizations.\n\
8511The advice applies to the region of the file specified by fd starting at\n\
8512offset and continuing for len bytes.\n\
8513advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8514POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8515POSIX_FADV_DONTNEED.");
8516
8517static PyObject *
8518posix_posix_fadvise(PyObject *self, PyObject *args)
8519{
8520 off_t len, offset;
8521 int res, fd, advice;
8522
8523 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8524 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8525 return NULL;
8526
8527 Py_BEGIN_ALLOW_THREADS
8528 res = posix_fadvise(fd, offset, len, advice);
8529 Py_END_ALLOW_THREADS
8530 if (res != 0) {
8531 errno = res;
8532 return posix_error();
8533 }
8534 Py_RETURN_NONE;
8535}
8536#endif
8537
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008538#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008539PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008540"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008541Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008542
Fred Drake762e2061999-08-26 17:23:54 +00008543/* Save putenv() parameters as values here, so we can collect them when they
8544 * get re-set with another call for the same key. */
8545static PyObject *posix_putenv_garbage;
8546
Tim Peters5aa91602002-01-30 05:46:57 +00008547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008548posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008549{
Victor Stinner84ae1182010-05-06 22:05:07 +00008550 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008551#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008552 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008553 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008554
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008556 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008557 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008559
Victor Stinner65170952011-11-22 22:16:17 +01008560 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008561 if (newstr == NULL) {
8562 PyErr_NoMemory();
8563 goto error;
8564 }
Victor Stinner65170952011-11-22 22:16:17 +01008565 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8566 PyErr_Format(PyExc_ValueError,
8567 "the environment variable is longer than %u characters",
8568 _MAX_ENV);
8569 goto error;
8570 }
8571
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008573 if (newenv == NULL)
8574 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008577 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008579#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008580 PyObject *os1, *os2;
8581 char *s1, *s2;
8582 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008583
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008584 if (!PyArg_ParseTuple(args,
8585 "O&O&:putenv",
8586 PyUnicode_FSConverter, &os1,
8587 PyUnicode_FSConverter, &os2))
8588 return NULL;
8589 s1 = PyBytes_AsString(os1);
8590 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008591
Victor Stinner65170952011-11-22 22:16:17 +01008592 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008593 if (newstr == NULL) {
8594 PyErr_NoMemory();
8595 goto error;
8596 }
8597
Victor Stinner8c62be82010-05-06 00:08:46 +00008598 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008600 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008601 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008603#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008604
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 /* Install the first arg and newstr in posix_putenv_garbage;
8606 * this will cause previous value to be collected. This has to
8607 * happen after the real putenv() call because the old value
8608 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008609 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 /* really not much we can do; just leak */
8611 PyErr_Clear();
8612 }
8613 else {
8614 Py_DECREF(newstr);
8615 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008616
Martin v. Löwis011e8422009-05-05 04:43:17 +00008617#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008618 Py_DECREF(os1);
8619 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008620#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008621 Py_RETURN_NONE;
8622
8623error:
8624#ifndef MS_WINDOWS
8625 Py_DECREF(os1);
8626 Py_DECREF(os2);
8627#endif
8628 Py_XDECREF(newstr);
8629 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008630}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008631#endif /* putenv */
8632
Guido van Rossumc524d952001-10-19 01:31:59 +00008633#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008634PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008635"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008636Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008637
8638static PyObject *
8639posix_unsetenv(PyObject *self, PyObject *args)
8640{
Victor Stinner65170952011-11-22 22:16:17 +01008641 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008642#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008643 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008644#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008645
8646 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008647
Victor Stinner65170952011-11-22 22:16:17 +01008648 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008649 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008650
Victor Stinner984890f2011-11-24 13:53:38 +01008651#ifdef HAVE_BROKEN_UNSETENV
8652 unsetenv(PyBytes_AS_STRING(name));
8653#else
Victor Stinner65170952011-11-22 22:16:17 +01008654 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008655 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008656 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008657 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008658 }
Victor Stinner984890f2011-11-24 13:53:38 +01008659#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008660
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 /* Remove the key from posix_putenv_garbage;
8662 * this will cause it to be collected. This has to
8663 * happen after the real unsetenv() call because the
8664 * old value was still accessible until then.
8665 */
Victor Stinner65170952011-11-22 22:16:17 +01008666 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 /* really not much we can do; just leak */
8668 PyErr_Clear();
8669 }
Victor Stinner65170952011-11-22 22:16:17 +01008670 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008671 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008672}
8673#endif /* unsetenv */
8674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008675PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008676"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008677Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008678
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008680posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008681{
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 int code;
8683 char *message;
8684 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8685 return NULL;
8686 message = strerror(code);
8687 if (message == NULL) {
8688 PyErr_SetString(PyExc_ValueError,
8689 "strerror() argument out of range");
8690 return NULL;
8691 }
Victor Stinner1b579672011-12-17 05:47:23 +01008692 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008693}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008694
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008695
Guido van Rossumc9641791998-08-04 15:26:23 +00008696#ifdef HAVE_SYS_WAIT_H
8697
Fred Drake106c1a02002-04-23 15:58:02 +00008698#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008699PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008700"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008701Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008702
8703static PyObject *
8704posix_WCOREDUMP(PyObject *self, PyObject *args)
8705{
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 WAIT_TYPE status;
8707 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008708
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8710 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008711
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008713}
8714#endif /* WCOREDUMP */
8715
8716#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008717PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008718"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008719Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008720job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008721
8722static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008723posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008724{
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 WAIT_TYPE status;
8726 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008727
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8729 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008730
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008732}
8733#endif /* WIFCONTINUED */
8734
Guido van Rossumc9641791998-08-04 15:26:23 +00008735#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008736PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008737"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008738Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008739
8740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008741posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008742{
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 WAIT_TYPE status;
8744 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008745
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8747 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008748
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008750}
8751#endif /* WIFSTOPPED */
8752
8753#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008754PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008755"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008756Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008757
8758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008759posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008760{
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 WAIT_TYPE status;
8762 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008763
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8765 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008766
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008768}
8769#endif /* WIFSIGNALED */
8770
8771#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008772PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008773"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008774Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008775system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008776
8777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008778posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008779{
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 WAIT_TYPE status;
8781 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008782
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8784 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008785
Victor Stinner8c62be82010-05-06 00:08:46 +00008786 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008787}
8788#endif /* WIFEXITED */
8789
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008790#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008791PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008792"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008793Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008794
8795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008796posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008797{
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 WAIT_TYPE status;
8799 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008800
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8802 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008803
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008805}
8806#endif /* WEXITSTATUS */
8807
8808#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008809PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008810"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008811Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008812value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008813
8814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008815posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008816{
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 WAIT_TYPE status;
8818 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008819
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8821 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008822
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008824}
8825#endif /* WTERMSIG */
8826
8827#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008828PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008829"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008830Return the signal that stopped the process that provided\n\
8831the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008832
8833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008834posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008835{
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 WAIT_TYPE status;
8837 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008838
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8840 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008841
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008843}
8844#endif /* WSTOPSIG */
8845
8846#endif /* HAVE_SYS_WAIT_H */
8847
8848
Thomas Wouters477c8d52006-05-27 19:21:47 +00008849#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008850#ifdef _SCO_DS
8851/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8852 needed definitions in sys/statvfs.h */
8853#define _SVID3
8854#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008855#include <sys/statvfs.h>
8856
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008857static PyObject*
8858_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8860 if (v == NULL)
8861 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008862
8863#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8865 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8866 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8867 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8868 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8869 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8870 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8871 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8872 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8873 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008874#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008875 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8876 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8877 PyStructSequence_SET_ITEM(v, 2,
8878 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8879 PyStructSequence_SET_ITEM(v, 3,
8880 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8881 PyStructSequence_SET_ITEM(v, 4,
8882 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8883 PyStructSequence_SET_ITEM(v, 5,
8884 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8885 PyStructSequence_SET_ITEM(v, 6,
8886 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8887 PyStructSequence_SET_ITEM(v, 7,
8888 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8889 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8890 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008891#endif
8892
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008894}
8895
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008896PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008897"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008898Perform an fstatvfs system call on the given fd.\n\
8899Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008900
8901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008902posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008903{
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 int fd, res;
8905 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008906
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8908 return NULL;
8909 Py_BEGIN_ALLOW_THREADS
8910 res = fstatvfs(fd, &st);
8911 Py_END_ALLOW_THREADS
8912 if (res != 0)
8913 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008914
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008916}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008917#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008918
8919
Thomas Wouters477c8d52006-05-27 19:21:47 +00008920#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008921#include <sys/statvfs.h>
8922
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008923PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008924"statvfs(path)\n\n\
8925Perform a statvfs system call on the given path.\n\
8926\n\
8927path may always be specified as a string.\n\
8928On some platforms, path may also be specified as an open file descriptor.\n\
8929 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008930
8931static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008932posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008933{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008934 static char *keywords[] = {"path", NULL};
8935 path_t path;
8936 int result;
8937 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008939
Larry Hastings9cf065c2012-06-22 16:30:09 -07008940 memset(&path, 0, sizeof(path));
8941#ifdef HAVE_FSTATVFS
8942 path.allow_fd = 1;
8943#endif
8944 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8945 path_converter, &path
8946 ))
8947 return NULL;
8948
8949 Py_BEGIN_ALLOW_THREADS
8950#ifdef HAVE_FSTATVFS
8951 if (path.fd != -1) {
8952#ifdef __APPLE__
8953 /* handle weak-linking on Mac OS X 10.3 */
8954 if (fstatvfs == NULL) {
8955 fd_specified("statvfs", path.fd);
8956 goto exit;
8957 }
8958#endif
8959 result = fstatvfs(path.fd, &st);
8960 }
8961 else
8962#endif
8963 result = statvfs(path.narrow, &st);
8964 Py_END_ALLOW_THREADS
8965
8966 if (result) {
8967 return_value = path_posix_error("statvfs", &path);
8968 goto exit;
8969 }
8970
8971 return_value = _pystatvfs_fromstructstatvfs(st);
8972
8973exit:
8974 path_cleanup(&path);
8975 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008976}
8977#endif /* HAVE_STATVFS */
8978
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008979#ifdef MS_WINDOWS
8980PyDoc_STRVAR(win32__getdiskusage__doc__,
8981"_getdiskusage(path) -> (total, free)\n\n\
8982Return disk usage statistics about the given path as (total, free) tuple.");
8983
8984static PyObject *
8985win32__getdiskusage(PyObject *self, PyObject *args)
8986{
8987 BOOL retval;
8988 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008989 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008990
Victor Stinner6139c1b2011-11-09 22:14:14 +01008991 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008992 return NULL;
8993
8994 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008995 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008996 Py_END_ALLOW_THREADS
8997 if (retval == 0)
8998 return PyErr_SetFromWindowsErr(0);
8999
9000 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9001}
9002#endif
9003
9004
Fred Drakec9680921999-12-13 16:37:25 +00009005/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9006 * It maps strings representing configuration variable names to
9007 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009008 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009009 * rarely-used constants. There are three separate tables that use
9010 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009011 *
9012 * This code is always included, even if none of the interfaces that
9013 * need it are included. The #if hackery needed to avoid it would be
9014 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009015 */
9016struct constdef {
9017 char *name;
9018 long value;
9019};
9020
Fred Drake12c6e2d1999-12-14 21:25:03 +00009021static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009022conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009023 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009024{
Christian Heimes217cfd12007-12-02 14:31:20 +00009025 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009026 *valuep = PyLong_AS_LONG(arg);
9027 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009028 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009029 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009030 /* look up the value in the table using a binary search */
9031 size_t lo = 0;
9032 size_t mid;
9033 size_t hi = tablesize;
9034 int cmp;
9035 const char *confname;
9036 if (!PyUnicode_Check(arg)) {
9037 PyErr_SetString(PyExc_TypeError,
9038 "configuration names must be strings or integers");
9039 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009041 confname = _PyUnicode_AsString(arg);
9042 if (confname == NULL)
9043 return 0;
9044 while (lo < hi) {
9045 mid = (lo + hi) / 2;
9046 cmp = strcmp(confname, table[mid].name);
9047 if (cmp < 0)
9048 hi = mid;
9049 else if (cmp > 0)
9050 lo = mid + 1;
9051 else {
9052 *valuep = table[mid].value;
9053 return 1;
9054 }
9055 }
9056 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9057 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009059}
9060
9061
9062#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9063static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009064#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009066#endif
9067#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009069#endif
Fred Drakec9680921999-12-13 16:37:25 +00009070#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
9073#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
9076#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
9094#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009096#endif
9097#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009115#ifdef _PC_ACL_ENABLED
9116 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9117#endif
9118#ifdef _PC_MIN_HOLE_SIZE
9119 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9120#endif
9121#ifdef _PC_ALLOC_SIZE_MIN
9122 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9123#endif
9124#ifdef _PC_REC_INCR_XFER_SIZE
9125 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9126#endif
9127#ifdef _PC_REC_MAX_XFER_SIZE
9128 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9129#endif
9130#ifdef _PC_REC_MIN_XFER_SIZE
9131 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9132#endif
9133#ifdef _PC_REC_XFER_ALIGN
9134 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9135#endif
9136#ifdef _PC_SYMLINK_MAX
9137 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9138#endif
9139#ifdef _PC_XATTR_ENABLED
9140 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9141#endif
9142#ifdef _PC_XATTR_EXISTS
9143 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9144#endif
9145#ifdef _PC_TIMESTAMP_RESOLUTION
9146 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9147#endif
Fred Drakec9680921999-12-13 16:37:25 +00009148};
9149
Fred Drakec9680921999-12-13 16:37:25 +00009150static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009151conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009152{
9153 return conv_confname(arg, valuep, posix_constants_pathconf,
9154 sizeof(posix_constants_pathconf)
9155 / sizeof(struct constdef));
9156}
9157#endif
9158
9159#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009160PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009161"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009162Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009163If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009164
9165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009166posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009167{
9168 PyObject *result = NULL;
9169 int name, fd;
9170
Fred Drake12c6e2d1999-12-14 21:25:03 +00009171 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9172 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009173 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009174
Stefan Krah0e803b32010-11-26 16:16:47 +00009175 errno = 0;
9176 limit = fpathconf(fd, name);
9177 if (limit == -1 && errno != 0)
9178 posix_error();
9179 else
9180 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009181 }
9182 return result;
9183}
9184#endif
9185
9186
9187#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009188PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009189"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009190Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009191If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009192
9193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009194posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009195{
9196 PyObject *result = NULL;
9197 int name;
9198 char *path;
9199
9200 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
9201 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009203
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 errno = 0;
9205 limit = pathconf(path, name);
9206 if (limit == -1 && errno != 0) {
9207 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009208 /* could be a path or name problem */
9209 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009210 else
Stefan Krah99439262010-11-26 12:58:05 +00009211 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 }
9213 else
9214 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009215 }
9216 return result;
9217}
9218#endif
9219
9220#ifdef HAVE_CONFSTR
9221static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009222#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009224#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009225#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009227#endif
9228#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009230#endif
Fred Draked86ed291999-12-15 15:34:33 +00009231#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009232 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009233#endif
9234#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009236#endif
9237#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009238 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009239#endif
9240#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009242#endif
Fred Drakec9680921999-12-13 16:37:25 +00009243#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009244 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009245#endif
9246#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009248#endif
9249#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009250 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009251#endif
9252#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009253 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009254#endif
9255#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009257#endif
9258#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009260#endif
9261#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009262 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009263#endif
9264#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009265 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009266#endif
Fred Draked86ed291999-12-15 15:34:33 +00009267#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009269#endif
Fred Drakec9680921999-12-13 16:37:25 +00009270#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009272#endif
Fred Draked86ed291999-12-15 15:34:33 +00009273#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009275#endif
9276#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009278#endif
9279#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009281#endif
9282#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009283 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009284#endif
Fred Drakec9680921999-12-13 16:37:25 +00009285#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009287#endif
9288#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009290#endif
9291#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009293#endif
9294#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009296#endif
9297#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009299#endif
9300#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009302#endif
9303#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009305#endif
9306#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009308#endif
9309#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009311#endif
9312#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009314#endif
9315#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009317#endif
9318#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009320#endif
9321#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009323#endif
9324#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009326#endif
9327#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009329#endif
9330#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009332#endif
Fred Draked86ed291999-12-15 15:34:33 +00009333#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009335#endif
9336#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009338#endif
9339#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009341#endif
9342#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009344#endif
9345#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009347#endif
9348#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
9351#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
9357#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
9363#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009365#endif
9366#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009368#endif
9369#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009371#endif
Fred Drakec9680921999-12-13 16:37:25 +00009372};
9373
9374static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009375conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009376{
9377 return conv_confname(arg, valuep, posix_constants_confstr,
9378 sizeof(posix_constants_confstr)
9379 / sizeof(struct constdef));
9380}
9381
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009382PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009383"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009384Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009385
9386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009387posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009388{
9389 PyObject *result = NULL;
9390 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009391 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009392 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009393
Victor Stinnercb043522010-09-10 23:49:04 +00009394 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9395 return NULL;
9396
9397 errno = 0;
9398 len = confstr(name, buffer, sizeof(buffer));
9399 if (len == 0) {
9400 if (errno) {
9401 posix_error();
9402 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009403 }
9404 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009405 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009406 }
9407 }
Victor Stinnercb043522010-09-10 23:49:04 +00009408
9409 if ((unsigned int)len >= sizeof(buffer)) {
9410 char *buf = PyMem_Malloc(len);
9411 if (buf == NULL)
9412 return PyErr_NoMemory();
9413 confstr(name, buf, len);
9414 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9415 PyMem_Free(buf);
9416 }
9417 else
9418 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009419 return result;
9420}
9421#endif
9422
9423
9424#ifdef HAVE_SYSCONF
9425static struct constdef posix_constants_sysconf[] = {
9426#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
Fred Draked86ed291999-12-15 15:34:33 +00009456#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009458#endif
9459#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009461#endif
Fred Drakec9680921999-12-13 16:37:25 +00009462#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
Fred Drakec9680921999-12-13 16:37:25 +00009465#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
9471#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009473#endif
9474#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009476#endif
9477#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009479#endif
Fred Draked86ed291999-12-15 15:34:33 +00009480#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009482#endif
Fred Drakec9680921999-12-13 16:37:25 +00009483#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009485#endif
9486#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009488#endif
9489#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009491#endif
9492#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009494#endif
9495#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009497#endif
Fred Draked86ed291999-12-15 15:34:33 +00009498#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009500#endif
Fred Drakec9680921999-12-13 16:37:25 +00009501#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009503#endif
9504#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
9528#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009530#endif
9531#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
9534#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
Fred Draked86ed291999-12-15 15:34:33 +00009570#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
Fred Drakec9680921999-12-13 16:37:25 +00009573#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
Fred Draked86ed291999-12-15 15:34:33 +00009582#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
Fred Drakec9680921999-12-13 16:37:25 +00009585#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
Fred Draked86ed291999-12-15 15:34:33 +00009588#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009590#endif
9591#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009593#endif
Fred Drakec9680921999-12-13 16:37:25 +00009594#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
Fred Draked86ed291999-12-15 15:34:33 +00009606#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
Fred Drakec9680921999-12-13 16:37:25 +00009609#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
Fred Draked86ed291999-12-15 15:34:33 +00009630#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
Fred Drakec9680921999-12-13 16:37:25 +00009633#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
Fred Draked86ed291999-12-15 15:34:33 +00009639#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
Fred Drakec9680921999-12-13 16:37:25 +00009642#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
Fred Draked86ed291999-12-15 15:34:33 +00009669#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
9672#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
Fred Drakec9680921999-12-13 16:37:25 +00009675#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
9690#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
Fred Draked86ed291999-12-15 15:34:33 +00009780#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009782#endif
Fred Drakec9680921999-12-13 16:37:25 +00009783#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918};
9919
9920static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009921conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009922{
9923 return conv_confname(arg, valuep, posix_constants_sysconf,
9924 sizeof(posix_constants_sysconf)
9925 / sizeof(struct constdef));
9926}
9927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009928PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009929"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009930Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009931
9932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009933posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009934{
9935 PyObject *result = NULL;
9936 int name;
9937
9938 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9939 int value;
9940
9941 errno = 0;
9942 value = sysconf(name);
9943 if (value == -1 && errno != 0)
9944 posix_error();
9945 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009946 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009947 }
9948 return result;
9949}
9950#endif
9951
9952
Fred Drakebec628d1999-12-15 18:31:10 +00009953/* This code is used to ensure that the tables of configuration value names
9954 * are in sorted order as required by conv_confname(), and also to build the
9955 * the exported dictionaries that are used to publish information about the
9956 * names available on the host platform.
9957 *
9958 * Sorting the table at runtime ensures that the table is properly ordered
9959 * when used, even for platforms we're not able to test on. It also makes
9960 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009961 */
Fred Drakebec628d1999-12-15 18:31:10 +00009962
9963static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009964cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009965{
9966 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009968 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009970
9971 return strcmp(c1->name, c2->name);
9972}
9973
9974static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009975setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009977{
Fred Drakebec628d1999-12-15 18:31:10 +00009978 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009979 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009980
9981 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9982 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009983 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009985
Barry Warsaw3155db32000-04-13 15:20:40 +00009986 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 PyObject *o = PyLong_FromLong(table[i].value);
9988 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9989 Py_XDECREF(o);
9990 Py_DECREF(d);
9991 return -1;
9992 }
9993 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009994 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009995 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009996}
9997
Fred Drakebec628d1999-12-15 18:31:10 +00009998/* Return -1 on failure, 0 on success. */
9999static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010000setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010001{
10002#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010003 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010004 sizeof(posix_constants_pathconf)
10005 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010006 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010007 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010008#endif
10009#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010010 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010011 sizeof(posix_constants_confstr)
10012 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010013 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010014 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010015#endif
10016#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010017 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010018 sizeof(posix_constants_sysconf)
10019 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010020 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010021 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010022#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010023 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010024}
Fred Draked86ed291999-12-15 15:34:33 +000010025
10026
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010027PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010028"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010029Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010030in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010031
10032static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010033posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010034{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010035 abort();
10036 /*NOTREACHED*/
10037 Py_FatalError("abort() called from Python code didn't abort!");
10038 return NULL;
10039}
Fred Drakebec628d1999-12-15 18:31:10 +000010040
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010041#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010042PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010043"startfile(filepath [, operation]) - Start a file with its associated\n\
10044application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010045\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010046When \"operation\" is not specified or \"open\", this acts like\n\
10047double-clicking the file in Explorer, or giving the file name as an\n\
10048argument to the DOS \"start\" command: the file is opened with whatever\n\
10049application (if any) its extension is associated.\n\
10050When another \"operation\" is given, it specifies what should be done with\n\
10051the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010052\n\
10053startfile returns as soon as the associated application is launched.\n\
10054There is no option to wait for the application to close, and no way\n\
10055to retrieve the application's exit status.\n\
10056\n\
10057The filepath is relative to the current directory. If you want to use\n\
10058an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010059the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010060
10061static PyObject *
10062win32_startfile(PyObject *self, PyObject *args)
10063{
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 PyObject *ofilepath;
10065 char *filepath;
10066 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010067 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010069
Victor Stinnereb5657a2011-09-30 01:44:27 +020010070 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 if (!PyArg_ParseTuple(args, "U|s:startfile",
10072 &unipath, &operation)) {
10073 PyErr_Clear();
10074 goto normal;
10075 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010076
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010078 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010080 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 PyErr_Clear();
10082 operation = NULL;
10083 goto normal;
10084 }
10085 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010086
Victor Stinnereb5657a2011-09-30 01:44:27 +020010087 wpath = PyUnicode_AsUnicode(unipath);
10088 if (wpath == NULL)
10089 goto normal;
10090 if (uoperation) {
10091 woperation = PyUnicode_AsUnicode(uoperation);
10092 if (woperation == NULL)
10093 goto normal;
10094 }
10095 else
10096 woperation = NULL;
10097
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010099 rc = ShellExecuteW((HWND)0, woperation, wpath,
10100 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 Py_END_ALLOW_THREADS
10102
Victor Stinnereb5657a2011-09-30 01:44:27 +020010103 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010105 win32_error_object("startfile", unipath);
10106 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 }
10108 Py_INCREF(Py_None);
10109 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010110
10111normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10113 PyUnicode_FSConverter, &ofilepath,
10114 &operation))
10115 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010116 if (win32_warn_bytes_api()) {
10117 Py_DECREF(ofilepath);
10118 return NULL;
10119 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 filepath = PyBytes_AsString(ofilepath);
10121 Py_BEGIN_ALLOW_THREADS
10122 rc = ShellExecute((HWND)0, operation, filepath,
10123 NULL, NULL, SW_SHOWNORMAL);
10124 Py_END_ALLOW_THREADS
10125 if (rc <= (HINSTANCE)32) {
10126 PyObject *errval = win32_error("startfile", filepath);
10127 Py_DECREF(ofilepath);
10128 return errval;
10129 }
10130 Py_DECREF(ofilepath);
10131 Py_INCREF(Py_None);
10132 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010133}
10134#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010135
Martin v. Löwis438b5342002-12-27 10:16:42 +000010136#ifdef HAVE_GETLOADAVG
10137PyDoc_STRVAR(posix_getloadavg__doc__,
10138"getloadavg() -> (float, float, float)\n\n\
10139Return the number of processes in the system run queue averaged over\n\
10140the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10141was unobtainable");
10142
10143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010144posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010145{
10146 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010147 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010148 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10149 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010150 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010151 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010152}
10153#endif
10154
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010155PyDoc_STRVAR(device_encoding__doc__,
10156"device_encoding(fd) -> str\n\n\
10157Return a string describing the encoding of the device\n\
10158if the output is a terminal; else return None.");
10159
10160static PyObject *
10161device_encoding(PyObject *self, PyObject *args)
10162{
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010164
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10166 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010167
10168 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010169}
10170
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010171#ifdef __VMS
10172/* Use openssl random routine */
10173#include <openssl/rand.h>
10174PyDoc_STRVAR(vms_urandom__doc__,
10175"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +000010176Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010177
10178static PyObject*
10179vms_urandom(PyObject *self, PyObject *args)
10180{
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 int howMany;
10182 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010183
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 /* Read arguments */
10185 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10186 return NULL;
10187 if (howMany < 0)
10188 return PyErr_Format(PyExc_ValueError,
10189 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010190
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 /* Allocate bytes */
10192 result = PyBytes_FromStringAndSize(NULL, howMany);
10193 if (result != NULL) {
10194 /* Get random data */
10195 if (RAND_pseudo_bytes((unsigned char*)
10196 PyBytes_AS_STRING(result),
10197 howMany) < 0) {
10198 Py_DECREF(result);
10199 return PyErr_Format(PyExc_ValueError,
10200 "RAND_pseudo_bytes");
10201 }
10202 }
10203 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010204}
10205#endif
10206
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010207#ifdef HAVE_SETRESUID
10208PyDoc_STRVAR(posix_setresuid__doc__,
10209"setresuid(ruid, euid, suid)\n\n\
10210Set the current process's real, effective, and saved user ids.");
10211
10212static PyObject*
10213posix_setresuid (PyObject *self, PyObject *args)
10214{
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 /* We assume uid_t is no larger than a long. */
10216 long ruid, euid, suid;
10217 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10218 return NULL;
10219 if (setresuid(ruid, euid, suid) < 0)
10220 return posix_error();
10221 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010222}
10223#endif
10224
10225#ifdef HAVE_SETRESGID
10226PyDoc_STRVAR(posix_setresgid__doc__,
10227"setresgid(rgid, egid, sgid)\n\n\
10228Set the current process's real, effective, and saved group ids.");
10229
10230static PyObject*
10231posix_setresgid (PyObject *self, PyObject *args)
10232{
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 /* We assume uid_t is no larger than a long. */
10234 long rgid, egid, sgid;
10235 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10236 return NULL;
10237 if (setresgid(rgid, egid, sgid) < 0)
10238 return posix_error();
10239 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010240}
10241#endif
10242
10243#ifdef HAVE_GETRESUID
10244PyDoc_STRVAR(posix_getresuid__doc__,
10245"getresuid() -> (ruid, euid, suid)\n\n\
10246Get tuple of the current process's real, effective, and saved user ids.");
10247
10248static PyObject*
10249posix_getresuid (PyObject *self, PyObject *noargs)
10250{
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 uid_t ruid, euid, suid;
10252 long l_ruid, l_euid, l_suid;
10253 if (getresuid(&ruid, &euid, &suid) < 0)
10254 return posix_error();
10255 /* Force the values into long's as we don't know the size of uid_t. */
10256 l_ruid = ruid;
10257 l_euid = euid;
10258 l_suid = suid;
10259 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010260}
10261#endif
10262
10263#ifdef HAVE_GETRESGID
10264PyDoc_STRVAR(posix_getresgid__doc__,
10265"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010266Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010267
10268static PyObject*
10269posix_getresgid (PyObject *self, PyObject *noargs)
10270{
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 uid_t rgid, egid, sgid;
10272 long l_rgid, l_egid, l_sgid;
10273 if (getresgid(&rgid, &egid, &sgid) < 0)
10274 return posix_error();
10275 /* Force the values into long's as we don't know the size of uid_t. */
10276 l_rgid = rgid;
10277 l_egid = egid;
10278 l_sgid = sgid;
10279 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010280}
10281#endif
10282
Benjamin Peterson9428d532011-09-14 11:45:52 -040010283#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010284
Benjamin Peterson799bd802011-08-31 22:15:17 -040010285PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010286"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10287Return the value of extended attribute attribute on path.\n\
10288\n\
10289path may be either a string or an open file descriptor.\n\
10290If follow_symlinks is False, and the last element of the path is a symbolic\n\
10291 link, getxattr will examine the symbolic link itself instead of the file\n\
10292 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010293
10294static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010295posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010296{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010297 path_t path;
10298 path_t attribute;
10299 int follow_symlinks = 1;
10300 PyObject *buffer = NULL;
10301 int i;
10302 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010303
Larry Hastings9cf065c2012-06-22 16:30:09 -070010304 memset(&path, 0, sizeof(path));
10305 memset(&attribute, 0, sizeof(attribute));
10306 path.allow_fd = 1;
10307 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10308 path_converter, &path,
10309 path_converter, &attribute,
10310 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010311 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010312
Larry Hastings9cf065c2012-06-22 16:30:09 -070010313 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10314 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010315
Larry Hastings9cf065c2012-06-22 16:30:09 -070010316 for (i = 0; ; i++) {
10317 void *ptr;
10318 ssize_t result;
10319 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10320 Py_ssize_t buffer_size = buffer_sizes[i];
10321 if (!buffer_size) {
10322 path_error("getxattr", &path);
10323 goto exit;
10324 }
10325 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10326 if (!buffer)
10327 goto exit;
10328 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010329
Larry Hastings9cf065c2012-06-22 16:30:09 -070010330 Py_BEGIN_ALLOW_THREADS;
10331 if (path.fd >= 0)
10332 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10333 else if (follow_symlinks)
10334 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10335 else
10336 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10337 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010338
Larry Hastings9cf065c2012-06-22 16:30:09 -070010339 if (result < 0) {
10340 Py_DECREF(buffer);
10341 buffer = NULL;
10342 if (errno == ERANGE)
10343 continue;
10344 path_error("getxattr", &path);
10345 goto exit;
10346 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010347
Larry Hastings9cf065c2012-06-22 16:30:09 -070010348 if (result != buffer_size) {
10349 /* Can only shrink. */
10350 _PyBytes_Resize(&buffer, result);
10351 }
10352 break;
10353 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010354
Larry Hastings9cf065c2012-06-22 16:30:09 -070010355exit:
10356 path_cleanup(&path);
10357 path_cleanup(&attribute);
10358 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010359}
10360
10361PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010362"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10363Set extended attribute attribute on path to value.\n\
10364path may be either a string or an open file descriptor.\n\
10365If follow_symlinks is False, and the last element of the path is a symbolic\n\
10366 link, setxattr will modify the symbolic link itself instead of the file\n\
10367 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010368
10369static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010370posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010371{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010372 path_t path;
10373 path_t attribute;
10374 Py_buffer value;
10375 int flags = 0;
10376 int follow_symlinks = 1;
10377 int result;
10378 PyObject *return_value = NULL;
10379 static char *keywords[] = {"path", "attribute", "value",
10380 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010381
Larry Hastings9cf065c2012-06-22 16:30:09 -070010382 memset(&path, 0, sizeof(path));
10383 path.allow_fd = 1;
10384 memset(&attribute, 0, sizeof(attribute));
10385 memset(&value, 0, sizeof(value));
10386 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10387 keywords,
10388 path_converter, &path,
10389 path_converter, &attribute,
10390 &value, &flags,
10391 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010392 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393
10394 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10395 goto exit;
10396
Benjamin Peterson799bd802011-08-31 22:15:17 -040010397 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010398 if (path.fd > -1)
10399 result = fsetxattr(path.fd, attribute.narrow,
10400 value.buf, value.len, flags);
10401 else if (follow_symlinks)
10402 result = setxattr(path.narrow, attribute.narrow,
10403 value.buf, value.len, flags);
10404 else
10405 result = lsetxattr(path.narrow, attribute.narrow,
10406 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010407 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010408
Larry Hastings9cf065c2012-06-22 16:30:09 -070010409 if (result) {
10410 return_value = path_error("setxattr", &path);
10411 goto exit;
10412 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010413
Larry Hastings9cf065c2012-06-22 16:30:09 -070010414 return_value = Py_None;
10415 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010416
Larry Hastings9cf065c2012-06-22 16:30:09 -070010417exit:
10418 path_cleanup(&path);
10419 path_cleanup(&attribute);
10420 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010421
Larry Hastings9cf065c2012-06-22 16:30:09 -070010422 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010423}
10424
10425PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010426"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10427Remove extended attribute attribute on path.\n\
10428path may be either a string or an open file descriptor.\n\
10429If follow_symlinks is False, and the last element of the path is a symbolic\n\
10430 link, removexattr will modify the symbolic link itself instead of the file\n\
10431 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010432
10433static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010434posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010435{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010436 path_t path;
10437 path_t attribute;
10438 int follow_symlinks = 1;
10439 int result;
10440 PyObject *return_value = NULL;
10441 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010442
Larry Hastings9cf065c2012-06-22 16:30:09 -070010443 memset(&path, 0, sizeof(path));
10444 memset(&attribute, 0, sizeof(attribute));
10445 path.allow_fd = 1;
10446 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10447 keywords,
10448 path_converter, &path,
10449 path_converter, &attribute,
10450 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010452
10453 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10454 goto exit;
10455
Benjamin Peterson799bd802011-08-31 22:15:17 -040010456 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010457 if (path.fd > -1)
10458 result = fremovexattr(path.fd, attribute.narrow);
10459 else if (follow_symlinks)
10460 result = removexattr(path.narrow, attribute.narrow);
10461 else
10462 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010464
Larry Hastings9cf065c2012-06-22 16:30:09 -070010465 if (result) {
10466 return_value = path_error("removexattr", &path);
10467 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010468 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010469
Larry Hastings9cf065c2012-06-22 16:30:09 -070010470 return_value = Py_None;
10471 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010472
Larry Hastings9cf065c2012-06-22 16:30:09 -070010473exit:
10474 path_cleanup(&path);
10475 path_cleanup(&attribute);
10476
10477 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010478}
10479
10480PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010481"listxattr(path='.', *, follow_symlinks=True)\n\n\
10482Return a list of extended attributes on path.\n\
10483\n\
10484path may be either None, a string, or an open file descriptor.\n\
10485if path is None, listxattr will examine the current directory.\n\
10486If follow_symlinks is False, and the last element of the path is a symbolic\n\
10487 link, listxattr will examine the symbolic link itself instead of the file\n\
10488 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010489
10490static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010491posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010492{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010493 path_t path;
10494 int follow_symlinks = 1;
10495 Py_ssize_t i;
10496 PyObject *result = NULL;
10497 char *buffer = NULL;
10498 char *name;
10499 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010500
Larry Hastings9cf065c2012-06-22 16:30:09 -070010501 memset(&path, 0, sizeof(path));
10502 path.allow_fd = 1;
10503 path.fd = -1;
10504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10505 path_converter, &path,
10506 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010507 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010508
Larry Hastings9cf065c2012-06-22 16:30:09 -070010509 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10510 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010511
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512 name = path.narrow ? path.narrow : ".";
10513 for (i = 0; ; i++) {
10514 char *start, *trace, *end;
10515 ssize_t length;
10516 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10517 Py_ssize_t buffer_size = buffer_sizes[i];
10518 if (!buffer_size) {
10519 // ERANGE
10520 path_error("listxattr", &path);
10521 break;
10522 }
10523 buffer = PyMem_MALLOC(buffer_size);
10524 if (!buffer) {
10525 PyErr_NoMemory();
10526 break;
10527 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010528
Larry Hastings9cf065c2012-06-22 16:30:09 -070010529 Py_BEGIN_ALLOW_THREADS;
10530 if (path.fd > -1)
10531 length = flistxattr(path.fd, buffer, buffer_size);
10532 else if (follow_symlinks)
10533 length = listxattr(name, buffer, buffer_size);
10534 else
10535 length = llistxattr(name, buffer, buffer_size);
10536 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010537
Larry Hastings9cf065c2012-06-22 16:30:09 -070010538 if (length < 0) {
10539 if (errno == ERANGE)
10540 continue;
10541 path_error("listxattr", &path);
10542 break;
10543 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010544
Larry Hastings9cf065c2012-06-22 16:30:09 -070010545 result = PyList_New(0);
10546 if (!result) {
10547 goto exit;
10548 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010549
Larry Hastings9cf065c2012-06-22 16:30:09 -070010550 end = buffer + length;
10551 for (trace = start = buffer; trace != end; trace++) {
10552 if (!*trace) {
10553 int error;
10554 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10555 trace - start);
10556 if (!attribute) {
10557 Py_DECREF(result);
10558 result = NULL;
10559 goto exit;
10560 }
10561 error = PyList_Append(result, attribute);
10562 Py_DECREF(attribute);
10563 if (error) {
10564 Py_DECREF(result);
10565 result = NULL;
10566 goto exit;
10567 }
10568 start = trace + 1;
10569 }
10570 }
10571 break;
10572 }
10573exit:
10574 path_cleanup(&path);
10575 if (buffer)
10576 PyMem_FREE(buffer);
10577 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010578}
10579
Benjamin Peterson9428d532011-09-14 11:45:52 -040010580#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010582
Georg Brandl2fb477c2012-02-21 00:33:36 +010010583PyDoc_STRVAR(posix_urandom__doc__,
10584"urandom(n) -> str\n\n\
10585Return n random bytes suitable for cryptographic use.");
10586
10587static PyObject *
10588posix_urandom(PyObject *self, PyObject *args)
10589{
10590 Py_ssize_t size;
10591 PyObject *result;
10592 int ret;
10593
10594 /* Read arguments */
10595 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10596 return NULL;
10597 if (size < 0)
10598 return PyErr_Format(PyExc_ValueError,
10599 "negative argument not allowed");
10600 result = PyBytes_FromStringAndSize(NULL, size);
10601 if (result == NULL)
10602 return NULL;
10603
10604 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10605 PyBytes_GET_SIZE(result));
10606 if (ret == -1) {
10607 Py_DECREF(result);
10608 return NULL;
10609 }
10610 return result;
10611}
10612
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010613/* Terminal size querying */
10614
10615static PyTypeObject TerminalSizeType;
10616
10617PyDoc_STRVAR(TerminalSize_docstring,
10618 "A tuple of (columns, lines) for holding terminal window size");
10619
10620static PyStructSequence_Field TerminalSize_fields[] = {
10621 {"columns", "width of the terminal window in characters"},
10622 {"lines", "height of the terminal window in characters"},
10623 {NULL, NULL}
10624};
10625
10626static PyStructSequence_Desc TerminalSize_desc = {
10627 "os.terminal_size",
10628 TerminalSize_docstring,
10629 TerminalSize_fields,
10630 2,
10631};
10632
10633#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10634PyDoc_STRVAR(termsize__doc__,
10635 "Return the size of the terminal window as (columns, lines).\n" \
10636 "\n" \
10637 "The optional argument fd (default standard output) specifies\n" \
10638 "which file descriptor should be queried.\n" \
10639 "\n" \
10640 "If the file descriptor is not connected to a terminal, an OSError\n" \
10641 "is thrown.\n" \
10642 "\n" \
10643 "This function will only be defined if an implementation is\n" \
10644 "available for this system.\n" \
10645 "\n" \
10646 "shutil.get_terminal_size is the high-level function which should \n" \
10647 "normally be used, os.get_terminal_size is the low-level implementation.");
10648
10649static PyObject*
10650get_terminal_size(PyObject *self, PyObject *args)
10651{
10652 int columns, lines;
10653 PyObject *termsize;
10654
10655 int fd = fileno(stdout);
10656 /* Under some conditions stdout may not be connected and
10657 * fileno(stdout) may point to an invalid file descriptor. For example
10658 * GUI apps don't have valid standard streams by default.
10659 *
10660 * If this happens, and the optional fd argument is not present,
10661 * the ioctl below will fail returning EBADF. This is what we want.
10662 */
10663
10664 if (!PyArg_ParseTuple(args, "|i", &fd))
10665 return NULL;
10666
10667#ifdef TERMSIZE_USE_IOCTL
10668 {
10669 struct winsize w;
10670 if (ioctl(fd, TIOCGWINSZ, &w))
10671 return PyErr_SetFromErrno(PyExc_OSError);
10672 columns = w.ws_col;
10673 lines = w.ws_row;
10674 }
10675#endif /* TERMSIZE_USE_IOCTL */
10676
10677#ifdef TERMSIZE_USE_CONIO
10678 {
10679 DWORD nhandle;
10680 HANDLE handle;
10681 CONSOLE_SCREEN_BUFFER_INFO csbi;
10682 switch (fd) {
10683 case 0: nhandle = STD_INPUT_HANDLE;
10684 break;
10685 case 1: nhandle = STD_OUTPUT_HANDLE;
10686 break;
10687 case 2: nhandle = STD_ERROR_HANDLE;
10688 break;
10689 default:
10690 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10691 }
10692 handle = GetStdHandle(nhandle);
10693 if (handle == NULL)
10694 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10695 if (handle == INVALID_HANDLE_VALUE)
10696 return PyErr_SetFromWindowsErr(0);
10697
10698 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10699 return PyErr_SetFromWindowsErr(0);
10700
10701 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10702 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10703 }
10704#endif /* TERMSIZE_USE_CONIO */
10705
10706 termsize = PyStructSequence_New(&TerminalSizeType);
10707 if (termsize == NULL)
10708 return NULL;
10709 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10710 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10711 if (PyErr_Occurred()) {
10712 Py_DECREF(termsize);
10713 return NULL;
10714 }
10715 return termsize;
10716}
10717#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10718
10719
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010720static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010721 {"access", (PyCFunction)posix_access,
10722 METH_VARARGS | METH_KEYWORDS,
10723 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010724#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010726#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727 {"chdir", (PyCFunction)posix_chdir,
10728 METH_VARARGS | METH_KEYWORDS,
10729 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010730#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010731 {"chflags", (PyCFunction)posix_chflags,
10732 METH_VARARGS | METH_KEYWORDS,
10733 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010734#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735 {"chmod", (PyCFunction)posix_chmod,
10736 METH_VARARGS | METH_KEYWORDS,
10737 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010738#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010740#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010741#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 {"chown", (PyCFunction)posix_chown,
10743 METH_VARARGS | METH_KEYWORDS,
10744 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010745#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010746#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010748#endif /* HAVE_LCHMOD */
10749#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010751#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010752#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010754#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010755#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010757#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010758#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010760#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010761#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010763#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010764#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10766 METH_NOARGS, posix_getcwd__doc__},
10767 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10768 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010769#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010770#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10771 {"link", (PyCFunction)posix_link,
10772 METH_VARARGS | METH_KEYWORDS,
10773 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010774#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 {"listdir", (PyCFunction)posix_listdir,
10776 METH_VARARGS | METH_KEYWORDS,
10777 posix_listdir__doc__},
10778 {"lstat", (PyCFunction)posix_lstat,
10779 METH_VARARGS | METH_KEYWORDS,
10780 posix_lstat__doc__},
10781 {"mkdir", (PyCFunction)posix_mkdir,
10782 METH_VARARGS | METH_KEYWORDS,
10783 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010784#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010786#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010787#ifdef HAVE_GETPRIORITY
10788 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10789#endif /* HAVE_GETPRIORITY */
10790#ifdef HAVE_SETPRIORITY
10791 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10792#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010793#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010794 {"readlink", (PyCFunction)posix_readlink,
10795 METH_VARARGS | METH_KEYWORDS,
10796 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010797#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010798#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010799 {"readlink", (PyCFunction)win_readlink,
10800 METH_VARARGS | METH_KEYWORDS,
10801 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010802#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010803 {"rename", (PyCFunction)posix_rename,
10804 METH_VARARGS | METH_KEYWORDS,
10805 posix_rename__doc__},
10806 {"replace", (PyCFunction)posix_replace,
10807 METH_VARARGS | METH_KEYWORDS,
10808 posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010809 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 {"stat", (PyCFunction)posix_stat,
10811 METH_VARARGS | METH_KEYWORDS,
10812 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814#if defined(HAVE_SYMLINK)
10815 {"symlink", (PyCFunction)posix_symlink,
10816 METH_VARARGS | METH_KEYWORDS,
10817 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010818#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010819#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010821#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010823#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010825#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 {"unlink", (PyCFunction)posix_unlink,
10827 METH_VARARGS | METH_KEYWORDS,
10828 posix_unlink__doc__},
10829 {"remove", (PyCFunction)posix_unlink,
10830 METH_VARARGS | METH_KEYWORDS,
10831 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010832 {"utime", (PyCFunction)posix_utime,
10833 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010834#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010836#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010838#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010840 {"execve", (PyCFunction)posix_execve,
10841 METH_VARARGS | METH_KEYWORDS,
10842 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010843#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010844#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10846 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010847#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10849 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010850#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010851#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010852#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010854#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010855#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010857#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010858#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010859#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010860 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10861 {"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 +020010862#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010863#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010864 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010865#endif
10866#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010867 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010868#endif
10869#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010870 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010871#endif
10872#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010873 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010874#endif
10875#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010876 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010877#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010878 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010879#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010880 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10881 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10882#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010883#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010884#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010886#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010887#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010889#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010890#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010892#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010893#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010895#endif /* HAVE_GETEUID */
10896#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010898#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010899#ifdef HAVE_GETGROUPLIST
10900 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10901#endif
Fred Drakec9680921999-12-13 16:37:25 +000010902#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010906#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010908#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010909#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010911#endif /* HAVE_GETPPID */
10912#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010914#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010915#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010917#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010918#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010920#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010921#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010923#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010924#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010926#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010927#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10929 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010930#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010931#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010933#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010934#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010936#endif /* HAVE_SETEUID */
10937#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010939#endif /* HAVE_SETEGID */
10940#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010942#endif /* HAVE_SETREUID */
10943#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010945#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010946#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010948#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010949#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010951#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010952#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010954#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010955#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010957#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010958#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010960#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010961#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010963#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010964#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010965 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010966#endif /* HAVE_WAIT3 */
10967#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010968 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010969#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010970#if defined(HAVE_WAITID) && !defined(__APPLE__)
10971 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10972#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010973#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010975#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010976#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010978#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010979#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010981#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010982#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010984#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010985#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010987#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010988#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010990#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010991 {"open", (PyCFunction)posix_open,\
10992 METH_VARARGS | METH_KEYWORDS,
10993 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10995 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10996 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10997 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10998 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010999#ifdef HAVE_LOCKF
11000 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11001#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11003 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011004#ifdef HAVE_READV
11005 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11006#endif
11007#ifdef HAVE_PREAD
11008 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011011#ifdef HAVE_WRITEV
11012 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11013#endif
11014#ifdef HAVE_PWRITE
11015 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11016#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011017#ifdef HAVE_SENDFILE
11018 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11019 posix_sendfile__doc__},
11020#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011021 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011023#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011025#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011026#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011027 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011028#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011029#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 {"mkfifo", (PyCFunction)posix_mkfifo,
11031 METH_VARARGS | METH_KEYWORDS,
11032 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011033#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011034#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011035 {"mknod", (PyCFunction)posix_mknod,
11036 METH_VARARGS | METH_KEYWORDS,
11037 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011038#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011039#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11041 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11042 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011043#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011044#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011046#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011047#ifdef HAVE_TRUNCATE
11048 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
11049#endif
11050#ifdef HAVE_POSIX_FALLOCATE
11051 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11052#endif
11053#ifdef HAVE_POSIX_FADVISE
11054 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11055#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011056#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011058#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011059#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011061#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011063#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011065#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011066#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011068#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011069#ifdef HAVE_SYNC
11070 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11071#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011072#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011074#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011075#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011076#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011078#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011079#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011081#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011082#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011084#endif /* WIFSTOPPED */
11085#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011087#endif /* WIFSIGNALED */
11088#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011090#endif /* WIFEXITED */
11091#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011093#endif /* WEXITSTATUS */
11094#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011096#endif /* WTERMSIG */
11097#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011099#endif /* WSTOPSIG */
11100#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011101#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011103#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011104#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011105 {"statvfs", (PyCFunction)posix_statvfs,
11106 METH_VARARGS | METH_KEYWORDS,
11107 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011108#endif
Fred Drakec9680921999-12-13 16:37:25 +000011109#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011122#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011124 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011125 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011126 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011127 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011128#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011129#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011131#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011132 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011133#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011135#endif
11136#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011138#endif
11139#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011141#endif
11142#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011144#endif
11145
Benjamin Peterson9428d532011-09-14 11:45:52 -040011146#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011147 {"setxattr", (PyCFunction)posix_setxattr,
11148 METH_VARARGS | METH_KEYWORDS,
11149 posix_setxattr__doc__},
11150 {"getxattr", (PyCFunction)posix_getxattr,
11151 METH_VARARGS | METH_KEYWORDS,
11152 posix_getxattr__doc__},
11153 {"removexattr", (PyCFunction)posix_removexattr,
11154 METH_VARARGS | METH_KEYWORDS,
11155 posix_removexattr__doc__},
11156 {"listxattr", (PyCFunction)posix_listxattr,
11157 METH_VARARGS | METH_KEYWORDS,
11158 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011159#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011160#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11161 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11162#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011164};
11165
11166
Barry Warsaw4a342091996-12-19 23:50:02 +000011167static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011168ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011169{
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011171}
11172
Guido van Rossumd48f2521997-12-05 22:19:34 +000011173#if defined(PYOS_OS2)
11174/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011175static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011176{
11177 APIRET rc;
11178 ULONG values[QSV_MAX+1];
11179 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011180 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011181
11182 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011183 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011184 Py_END_ALLOW_THREADS
11185
11186 if (rc != NO_ERROR) {
11187 os2_error(rc);
11188 return -1;
11189 }
11190
Fred Drake4d1e64b2002-04-15 19:40:07 +000011191 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11192 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11193 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11194 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11195 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11196 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11197 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011198
11199 switch (values[QSV_VERSION_MINOR]) {
11200 case 0: ver = "2.00"; break;
11201 case 10: ver = "2.10"; break;
11202 case 11: ver = "2.11"; break;
11203 case 30: ver = "3.00"; break;
11204 case 40: ver = "4.00"; break;
11205 case 50: ver = "5.00"; break;
11206 default:
Tim Peters885d4572001-11-28 20:27:42 +000011207 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011209 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011210 ver = &tmp[0];
11211 }
11212
11213 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011214 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011215 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011216
11217 /* Add Indicator of Which Drive was Used to Boot the System */
11218 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11219 tmp[1] = ':';
11220 tmp[2] = '\0';
11221
Fred Drake4d1e64b2002-04-15 19:40:07 +000011222 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011223}
11224#endif
11225
Brian Curtin52173d42010-12-02 18:29:18 +000011226#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011227static int
Brian Curtin52173d42010-12-02 18:29:18 +000011228enable_symlink()
11229{
11230 HANDLE tok;
11231 TOKEN_PRIVILEGES tok_priv;
11232 LUID luid;
11233 int meth_idx = 0;
11234
11235 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011236 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011237
11238 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011239 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011240
11241 tok_priv.PrivilegeCount = 1;
11242 tok_priv.Privileges[0].Luid = luid;
11243 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11244
11245 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11246 sizeof(TOKEN_PRIVILEGES),
11247 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011248 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011249
Brian Curtin3b4499c2010-12-28 14:31:47 +000011250 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11251 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011252}
11253#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11254
Barry Warsaw4a342091996-12-19 23:50:02 +000011255static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011256all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011257{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011258#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011260#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011261#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011263#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011264#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011266#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011267#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011269#endif
Fred Drakec9680921999-12-13 16:37:25 +000011270#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011273#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011275#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011276#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011278#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011279#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011281#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011282#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011284#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011285#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011287#endif
11288#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011290#endif
11291#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011293#endif
11294#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011296#endif
11297#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011299#endif
11300#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011302#endif
11303#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011305#endif
11306#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011308#endif
11309#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011311#endif
11312#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011314#endif
11315#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011317#endif
11318#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011320#endif
11321#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011323#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011324#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011326#endif
11327#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011329#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011330#ifdef O_XATTR
11331 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11332#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011333#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011335#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011336#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011338#endif
11339#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011341#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011342#ifdef O_EXEC
11343 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11344#endif
11345#ifdef O_SEARCH
11346 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11347#endif
11348#ifdef O_TTY_INIT
11349 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11350#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011351#ifdef PRIO_PROCESS
11352 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11353#endif
11354#ifdef PRIO_PGRP
11355 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11356#endif
11357#ifdef PRIO_USER
11358 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11359#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011360#ifdef O_CLOEXEC
11361 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11362#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011363#ifdef O_ACCMODE
11364 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11365#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011366
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011367
Jesus Cea94363612012-06-22 18:32:07 +020011368#ifdef SEEK_HOLE
11369 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11370#endif
11371#ifdef SEEK_DATA
11372 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11373#endif
11374
Tim Peters5aa91602002-01-30 05:46:57 +000011375/* MS Windows */
11376#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 /* Don't inherit in child processes. */
11378 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011379#endif
11380#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 /* Optimize for short life (keep in memory). */
11382 /* MS forgot to define this one with a non-underscore form too. */
11383 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011384#endif
11385#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 /* Automatically delete when last handle is closed. */
11387 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011388#endif
11389#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 /* Optimize for random access. */
11391 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011392#endif
11393#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 /* Optimize for sequential access. */
11395 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011396#endif
11397
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011398/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011399#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 /* Send a SIGIO signal whenever input or output
11401 becomes available on file descriptor */
11402 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011403#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011404#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 /* Direct disk access. */
11406 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011407#endif
11408#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 /* Must be a directory. */
11410 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011411#endif
11412#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 /* Do not follow links. */
11414 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011415#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011416#ifdef O_NOLINKS
11417 /* Fails if link count of the named file is greater than 1 */
11418 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11419#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011420#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 /* Do not update the access time. */
11422 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011423#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011424
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011426#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011428#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011429#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011431#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011432#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011434#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011435#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011437#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011438#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011440#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011441#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011443#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011444#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011446#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011447#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011449#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011450#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011452#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011453#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011455#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011456#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011458#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011459#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011461#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011462#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011464#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011465#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011467#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011468#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011470#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011471#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011473#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011474#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011476#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011477
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011478 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011479#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011480 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011481#endif /* ST_RDONLY */
11482#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011483 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011484#endif /* ST_NOSUID */
11485
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011486 /* FreeBSD sendfile() constants */
11487#ifdef SF_NODISKIO
11488 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11489#endif
11490#ifdef SF_MNOWAIT
11491 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11492#endif
11493#ifdef SF_SYNC
11494 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11495#endif
11496
Ross Lagerwall7807c352011-03-17 20:20:30 +020011497 /* constants for posix_fadvise */
11498#ifdef POSIX_FADV_NORMAL
11499 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11500#endif
11501#ifdef POSIX_FADV_SEQUENTIAL
11502 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11503#endif
11504#ifdef POSIX_FADV_RANDOM
11505 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11506#endif
11507#ifdef POSIX_FADV_NOREUSE
11508 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11509#endif
11510#ifdef POSIX_FADV_WILLNEED
11511 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11512#endif
11513#ifdef POSIX_FADV_DONTNEED
11514 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11515#endif
11516
11517 /* constants for waitid */
11518#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11519 if (ins(d, "P_PID", (long)P_PID)) return -1;
11520 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11521 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11522#endif
11523#ifdef WEXITED
11524 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11525#endif
11526#ifdef WNOWAIT
11527 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11528#endif
11529#ifdef WSTOPPED
11530 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11531#endif
11532#ifdef CLD_EXITED
11533 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11534#endif
11535#ifdef CLD_DUMPED
11536 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11537#endif
11538#ifdef CLD_TRAPPED
11539 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11540#endif
11541#ifdef CLD_CONTINUED
11542 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11543#endif
11544
11545 /* constants for lockf */
11546#ifdef F_LOCK
11547 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11548#endif
11549#ifdef F_TLOCK
11550 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11551#endif
11552#ifdef F_ULOCK
11553 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11554#endif
11555#ifdef F_TEST
11556 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11557#endif
11558
Guido van Rossum246bc171999-02-01 23:54:31 +000011559#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011560#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11562 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11563 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11564 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11565 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11566 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11567 if (ins(d, "P_PM", (long)P_PM)) return -1;
11568 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11569 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11570 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11571 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11572 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11573 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11574 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11575 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11576 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11577 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11578 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11579 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11580 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011581#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11583 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11584 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11585 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11586 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011587#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011588#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011589
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011590#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011591 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011592 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11593 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11594#ifdef SCHED_SPORADIC
11595 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11596#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011597#ifdef SCHED_BATCH
11598 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11599#endif
11600#ifdef SCHED_IDLE
11601 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11602#endif
11603#ifdef SCHED_RESET_ON_FORK
11604 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11605#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011606#ifdef SCHED_SYS
11607 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11608#endif
11609#ifdef SCHED_IA
11610 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11611#endif
11612#ifdef SCHED_FSS
11613 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11614#endif
11615#ifdef SCHED_FX
11616 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11617#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011618#endif
11619
Benjamin Peterson9428d532011-09-14 11:45:52 -040011620#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011621 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11622 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11623 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11624#endif
11625
Victor Stinner8b905bd2011-10-25 13:34:04 +020011626#ifdef RTLD_LAZY
11627 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11628#endif
11629#ifdef RTLD_NOW
11630 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11631#endif
11632#ifdef RTLD_GLOBAL
11633 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11634#endif
11635#ifdef RTLD_LOCAL
11636 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11637#endif
11638#ifdef RTLD_NODELETE
11639 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11640#endif
11641#ifdef RTLD_NOLOAD
11642 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11643#endif
11644#ifdef RTLD_DEEPBIND
11645 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11646#endif
11647
Guido van Rossumd48f2521997-12-05 22:19:34 +000011648#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011650#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011651 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011652}
11653
11654
Tim Peters5aa91602002-01-30 05:46:57 +000011655#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011656#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011657#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011658
11659#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011660#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011661#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011662
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011663#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011664#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011665#define MODNAME "posix"
11666#endif
11667
Martin v. Löwis1a214512008-06-11 05:26:20 +000011668static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011669 PyModuleDef_HEAD_INIT,
11670 MODNAME,
11671 posix__doc__,
11672 -1,
11673 posix_methods,
11674 NULL,
11675 NULL,
11676 NULL,
11677 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011678};
11679
11680
Larry Hastings9cf065c2012-06-22 16:30:09 -070011681static char *have_functions[] = {
11682
11683#ifdef HAVE_FACCESSAT
11684 "HAVE_FACCESSAT",
11685#endif
11686
11687#ifdef HAVE_FCHDIR
11688 "HAVE_FCHDIR",
11689#endif
11690
11691#ifdef HAVE_FCHMOD
11692 "HAVE_FCHMOD",
11693#endif
11694
11695#ifdef HAVE_FCHMODAT
11696 "HAVE_FCHMODAT",
11697#endif
11698
11699#ifdef HAVE_FCHOWN
11700 "HAVE_FCHOWN",
11701#endif
11702
11703#ifdef HAVE_FEXECVE
11704 "HAVE_FEXECVE",
11705#endif
11706
11707#ifdef HAVE_FDOPENDIR
11708 "HAVE_FDOPENDIR",
11709#endif
11710
11711#ifdef HAVE_FSTATAT
11712 "HAVE_FSTATAT",
11713#endif
11714
11715#ifdef HAVE_FSTATVFS
11716 "HAVE_FSTATVFS",
11717#endif
11718
11719#ifdef HAVE_FUTIMENS
11720 "HAVE_FUTIMENS",
11721#endif
11722
11723#ifdef HAVE_FUTIMES
11724 "HAVE_FUTIMES",
11725#endif
11726
11727#ifdef HAVE_FUTIMESAT
11728 "HAVE_FUTIMESAT",
11729#endif
11730
11731#ifdef HAVE_LINKAT
11732 "HAVE_LINKAT",
11733#endif
11734
11735#ifdef HAVE_LCHFLAGS
11736 "HAVE_LCHFLAGS",
11737#endif
11738
11739#ifdef HAVE_LCHMOD
11740 "HAVE_LCHMOD",
11741#endif
11742
11743#ifdef HAVE_LCHOWN
11744 "HAVE_LCHOWN",
11745#endif
11746
11747#ifdef HAVE_LSTAT
11748 "HAVE_LSTAT",
11749#endif
11750
11751#ifdef HAVE_LUTIMES
11752 "HAVE_LUTIMES",
11753#endif
11754
11755#ifdef HAVE_MKDIRAT
11756 "HAVE_MKDIRAT",
11757#endif
11758
11759#ifdef HAVE_MKFIFOAT
11760 "HAVE_MKFIFOAT",
11761#endif
11762
11763#ifdef HAVE_MKNODAT
11764 "HAVE_MKNODAT",
11765#endif
11766
11767#ifdef HAVE_OPENAT
11768 "HAVE_OPENAT",
11769#endif
11770
11771#ifdef HAVE_READLINKAT
11772 "HAVE_READLINKAT",
11773#endif
11774
11775#ifdef HAVE_RENAMEAT
11776 "HAVE_RENAMEAT",
11777#endif
11778
11779#ifdef HAVE_SYMLINKAT
11780 "HAVE_SYMLINKAT",
11781#endif
11782
11783#ifdef HAVE_UNLINKAT
11784 "HAVE_UNLINKAT",
11785#endif
11786
11787#ifdef HAVE_UTIMENSAT
11788 "HAVE_UTIMENSAT",
11789#endif
11790
11791#ifdef MS_WINDOWS
11792 "MS_WINDOWS",
11793#endif
11794
11795 NULL
11796};
11797
11798
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011799PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011800INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011801{
Victor Stinner8c62be82010-05-06 00:08:46 +000011802 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011803 PyObject *list;
11804 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011805
Brian Curtin52173d42010-12-02 18:29:18 +000011806#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011807 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011808#endif
11809
Victor Stinner8c62be82010-05-06 00:08:46 +000011810 m = PyModule_Create(&posixmodule);
11811 if (m == NULL)
11812 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011813
Victor Stinner8c62be82010-05-06 00:08:46 +000011814 /* Initialize environ dictionary */
11815 v = convertenviron();
11816 Py_XINCREF(v);
11817 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11818 return NULL;
11819 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011820
Victor Stinner8c62be82010-05-06 00:08:46 +000011821 if (all_ins(m))
11822 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011823
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 if (setup_confname_tables(m))
11825 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011826
Victor Stinner8c62be82010-05-06 00:08:46 +000011827 Py_INCREF(PyExc_OSError);
11828 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011829
Benjamin Peterson2740af82011-08-02 17:41:34 -050011830#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011831 if (PyType_Ready(&cpu_set_type) < 0)
11832 return NULL;
11833 Py_INCREF(&cpu_set_type);
11834 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011835#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011836
Guido van Rossumb3d39562000-01-31 18:41:26 +000011837#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 if (posix_putenv_garbage == NULL)
11839 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011840#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011841
Victor Stinner8c62be82010-05-06 00:08:46 +000011842 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011843#if defined(HAVE_WAITID) && !defined(__APPLE__)
11844 waitid_result_desc.name = MODNAME ".waitid_result";
11845 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11846#endif
11847
Victor Stinner8c62be82010-05-06 00:08:46 +000011848 stat_result_desc.name = MODNAME ".stat_result";
11849 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11850 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11851 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11852 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11853 structseq_new = StatResultType.tp_new;
11854 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011855
Victor Stinner8c62be82010-05-06 00:08:46 +000011856 statvfs_result_desc.name = MODNAME ".statvfs_result";
11857 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011858#ifdef NEED_TICKS_PER_SECOND
11859# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011860 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011861# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011862 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011863# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011864 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011865# endif
11866#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011867
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011868#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011869 sched_param_desc.name = MODNAME ".sched_param";
11870 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11871 SchedParamType.tp_new = sched_param_new;
11872#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011873
11874 /* initialize TerminalSize_info */
11875 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11876 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011877 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011878#if defined(HAVE_WAITID) && !defined(__APPLE__)
11879 Py_INCREF((PyObject*) &WaitidResultType);
11880 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11881#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011882 Py_INCREF((PyObject*) &StatResultType);
11883 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11884 Py_INCREF((PyObject*) &StatVFSResultType);
11885 PyModule_AddObject(m, "statvfs_result",
11886 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011887
11888#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011889 Py_INCREF(&SchedParamType);
11890 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011891#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011892
11893#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011894 /*
11895 * Step 2 of weak-linking support on Mac OS X.
11896 *
11897 * The code below removes functions that are not available on the
11898 * currently active platform.
11899 *
11900 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011901 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 * OSX 10.4.
11903 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011904#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011905 if (fstatvfs == NULL) {
11906 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11907 return NULL;
11908 }
11909 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011910#endif /* HAVE_FSTATVFS */
11911
11912#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011913 if (statvfs == NULL) {
11914 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11915 return NULL;
11916 }
11917 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011918#endif /* HAVE_STATVFS */
11919
11920# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011921 if (lchown == NULL) {
11922 if (PyObject_DelAttrString(m, "lchown") == -1) {
11923 return NULL;
11924 }
11925 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011926#endif /* HAVE_LCHOWN */
11927
11928
11929#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011930
11931 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11932
Larry Hastings6fe20b32012-04-19 15:07:49 -070011933 billion = PyLong_FromLong(1000000000);
11934 if (!billion)
11935 return NULL;
11936
Larry Hastings9cf065c2012-06-22 16:30:09 -070011937 /* suppress "function not used" warnings */
11938 {
11939 int ignored;
11940 fd_specified("", -1);
11941 follow_symlinks_specified("", 1);
11942 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11943 dir_fd_converter(Py_None, &ignored);
11944 dir_fd_unavailable(Py_None, &ignored);
11945 }
11946
11947 /*
11948 * provide list of locally available functions
11949 * so os.py can populate support_* lists
11950 */
11951 list = PyList_New(0);
11952 if (!list)
11953 return NULL;
11954 for (trace = have_functions; *trace; trace++) {
11955 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11956 if (!unicode)
11957 return NULL;
11958 if (PyList_Append(list, unicode))
11959 return NULL;
11960 Py_DECREF(unicode);
11961 }
11962 PyModule_AddObject(m, "_have_functions", list);
11963
11964 initialized = 1;
11965
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011967
Guido van Rossumb6775db1994-08-01 11:34:53 +000011968}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011969
11970#ifdef __cplusplus
11971}
11972#endif