blob: bfe32b81544699f50eff7dc52295318f9f7dcfb7 [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) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002433 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002434 !(attr & FILE_ATTRIBUTE_READONLY) ||
2435 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2436#else
2437
2438 Py_BEGIN_ALLOW_THREADS
2439#ifdef HAVE_FACCESSAT
2440 if ((dir_fd != DEFAULT_DIR_FD) ||
2441 effective_ids ||
2442 !follow_symlinks) {
2443 int flags = 0;
2444 if (!follow_symlinks)
2445 flags |= AT_SYMLINK_NOFOLLOW;
2446 if (effective_ids)
2447 flags |= AT_EACCESS;
2448 result = faccessat(dir_fd, path.narrow, mode, flags);
2449 }
2450 else
2451#endif
2452 result = access(path.narrow, mode);
2453 Py_END_ALLOW_THREADS
2454 return_value = PyBool_FromLong(!result);
2455#endif
2456
2457#ifndef HAVE_FACCESSAT
2458exit:
2459#endif
2460 path_cleanup(&path);
2461 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002462}
2463
Guido van Rossumd371ff11999-01-25 16:12:23 +00002464#ifndef F_OK
2465#define F_OK 0
2466#endif
2467#ifndef R_OK
2468#define R_OK 4
2469#endif
2470#ifndef W_OK
2471#define W_OK 2
2472#endif
2473#ifndef X_OK
2474#define X_OK 1
2475#endif
2476
2477#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484{
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 int id;
2486 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2489 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002491#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002492 /* file descriptor 0 only, the default input device (stdin) */
2493 if (id == 0) {
2494 ret = ttyname();
2495 }
2496 else {
2497 ret = NULL;
2498 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (ret == NULL)
2503 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002504 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002508#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002510"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512
2513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002514posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515{
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 char *ret;
2517 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518
Greg Wardb48bc172000-03-01 21:51:56 +00002519#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (ret == NULL)
2525 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002526 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527}
2528#endif
2529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532Change the current working directory to the specified path.\n\
2533\n\
2534path may always be specified as a string.\n\
2535On some platforms, path may also be specified as an open file descriptor.\n\
2536 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 path_t path;
2542 int result;
2543 PyObject *return_value = NULL;
2544 static char *keywords[] = {"path", NULL};
2545
2546 memset(&path, 0, sizeof(path));
2547#ifdef HAVE_FCHDIR
2548 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2551 path_converter, &path
2552 ))
2553 return NULL;
2554
2555 Py_BEGIN_ALLOW_THREADS
2556#ifdef MS_WINDOWS
2557 if (path.wide)
2558 result = win32_wchdir(path.wide);
2559 else
2560 result = win32_chdir(path.narrow);
2561 result = !result; /* on unix, success = 0, on windows, success = !0 */
2562#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2563 result = _chdir2(path.narrow);
2564#else
2565#ifdef HAVE_FCHDIR
2566 if (path.fd != -1)
2567 result = fchdir(path.fd);
2568 else
2569#endif
2570 result = chdir(path.narrow);
2571#endif
2572 Py_END_ALLOW_THREADS
2573
2574 if (result) {
2575 return_value = path_error("chdir", &path);
2576 goto exit;
2577 }
2578
2579 return_value = Py_None;
2580 Py_INCREF(Py_None);
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__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087"rmdir(path, *, dir_fd=None)\n\n\
4088Remove a directory.\n\
4089\n\
4090If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4091 and path should be relative; path will then be relative to that directory.\n\
4092dir_fd may not be implemented on your platform.\n\
4093 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Barry Warsaw53699e91996-12-10 23:23:01 +00004095static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004096posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004097{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004098 path_t path;
4099 int dir_fd = DEFAULT_DIR_FD;
4100 static char *keywords[] = {"path", "dir_fd", NULL};
4101 int result;
4102 PyObject *return_value = NULL;
4103
4104 memset(&path, 0, sizeof(path));
4105 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4106 path_converter, &path,
4107#ifdef HAVE_UNLINKAT
4108 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004109#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004111#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004112 ))
4113 return NULL;
4114
4115 Py_BEGIN_ALLOW_THREADS
4116#ifdef MS_WINDOWS
4117 if (path.wide)
4118 result = RemoveDirectoryW(path.wide);
4119 else
4120 result = RemoveDirectoryA(path.narrow);
4121 result = !result; /* Windows, success=1, UNIX, success=0 */
4122#else
4123#ifdef HAVE_UNLINKAT
4124 if (dir_fd != DEFAULT_DIR_FD)
4125 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4126 else
4127#endif
4128 result = rmdir(path.narrow);
4129#endif
4130 Py_END_ALLOW_THREADS
4131
4132 if (result) {
4133 return_value = path_error("rmdir", &path);
4134 goto exit;
4135 }
4136
4137 return_value = Py_None;
4138 Py_INCREF(Py_None);
4139
4140exit:
4141 path_cleanup(&path);
4142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143}
4144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004146#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004147PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004148"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004149Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Barry Warsaw53699e91996-12-10 23:23:01 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004153{
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 wchar_t *command;
4157 if (!PyArg_ParseTuple(args, "u:system", &command))
4158 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004159
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 Py_BEGIN_ALLOW_THREADS
4161 sts = _wsystem(command);
4162 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004163#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 PyObject *command_obj;
4165 char *command;
4166 if (!PyArg_ParseTuple(args, "O&:system",
4167 PyUnicode_FSConverter, &command_obj))
4168 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 command = PyBytes_AsString(command_obj);
4171 Py_BEGIN_ALLOW_THREADS
4172 sts = system(command);
4173 Py_END_ALLOW_THREADS
4174 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004175#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004178#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004182"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Barry Warsaw53699e91996-12-10 23:23:01 +00004185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004186posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004187{
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 int i;
4189 if (!PyArg_ParseTuple(args, "i:umask", &i))
4190 return NULL;
4191 i = (int)umask(i);
4192 if (i < 0)
4193 return posix_error();
4194 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004195}
4196
Brian Curtind40e6f72010-07-08 21:39:08 +00004197#ifdef MS_WINDOWS
4198
4199/* override the default DeleteFileW behavior so that directory
4200symlinks can be removed with this function, the same as with
4201Unix symlinks */
4202BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4203{
4204 WIN32_FILE_ATTRIBUTE_DATA info;
4205 WIN32_FIND_DATAW find_data;
4206 HANDLE find_data_handle;
4207 int is_directory = 0;
4208 int is_link = 0;
4209
4210 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4211 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004212
Brian Curtind40e6f72010-07-08 21:39:08 +00004213 /* Get WIN32_FIND_DATA structure for the path to determine if
4214 it is a symlink */
4215 if(is_directory &&
4216 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4217 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4218
4219 if(find_data_handle != INVALID_HANDLE_VALUE) {
4220 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4221 FindClose(find_data_handle);
4222 }
4223 }
4224 }
4225
4226 if (is_directory && is_link)
4227 return RemoveDirectoryW(lpFileName);
4228
4229 return DeleteFileW(lpFileName);
4230}
4231#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004232
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004235Remove a file (same as remove()).\n\
4236\n\
4237If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4238 and path should be relative; path will then be relative to that directory.\n\
4239dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004240 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004243"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244Remove a file (same as unlink()).\n\
4245\n\
4246If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4247 and path should be relative; path will then be relative to that directory.\n\
4248dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Barry Warsaw53699e91996-12-10 23:23:01 +00004251static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004252posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004253{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 path_t path;
4255 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257 int result;
4258 PyObject *return_value = NULL;
4259
4260 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262 path_converter, &path,
4263#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004265#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004266 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004267#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269 return NULL;
4270
4271 Py_BEGIN_ALLOW_THREADS
4272#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 if (path.wide)
4274 result = Py_DeleteFileW(path.wide);
4275 else
4276 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277 result = !result; /* Windows, success=1, UNIX, success=0 */
4278#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004279#ifdef HAVE_UNLINKAT
4280 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004281 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004282 else
4283#endif /* HAVE_UNLINKAT */
4284 result = unlink(path.narrow);
4285#endif
4286 Py_END_ALLOW_THREADS
4287
4288 if (result) {
4289 return_value = path_error("unlink", &path);
4290 goto exit;
4291 }
4292
4293 return_value = Py_None;
4294 Py_INCREF(Py_None);
4295
4296exit:
4297 path_cleanup(&path);
4298 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004299}
4300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Guido van Rossumb6775db1994-08-01 11:34:53 +00004302#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004303PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004304"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004306
Barry Warsaw53699e91996-12-10 23:23:01 +00004307static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004308posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004309{
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 struct utsname u;
4311 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00004312
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 Py_BEGIN_ALLOW_THREADS
4314 res = uname(&u);
4315 Py_END_ALLOW_THREADS
4316 if (res < 0)
4317 return posix_error();
4318 return Py_BuildValue("(sssss)",
4319 u.sysname,
4320 u.nodename,
4321 u.release,
4322 u.version,
4323 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004325#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004326
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004327
Larry Hastings9cf065c2012-06-22 16:30:09 -07004328PyDoc_STRVAR(posix_utime__doc__,
4329"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4330Set the access and modified time of path.\n\
4331\n\
4332path may always be specified as a string.\n\
4333On some platforms, path may also be specified as an open file descriptor.\n\
4334 If this functionality is unavailable, using it raises an exception.\n\
4335\n\
4336If times is not None, it must be a tuple (atime, mtime);\n\
4337 atime and mtime should be expressed as float seconds since the epoch.\n\
4338If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4339 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4340 since the epoch.\n\
4341If both times and ns are None, utime uses the current time.\n\
4342Specifying tuples for both times and ns is an error.\n\
4343\n\
4344If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4345 and path should be relative; path will then be relative to that directory.\n\
4346If follow_symlinks is False, and the last element of the path is a symbolic\n\
4347 link, utime will modify the symbolic link itself instead of the file the\n\
4348 link points to.\n\
4349It is an error to use dir_fd or follow_symlinks when specifying path\n\
4350 as an open file descriptor.\n\
4351dir_fd and follow_symlinks may not be available on your platform.\n\
4352 If they are unavailable, using them will raise a NotImplementedError.");
4353
4354typedef struct {
4355 int now;
4356 time_t atime_s;
4357 long atime_ns;
4358 time_t mtime_s;
4359 long mtime_ns;
4360} utime_t;
4361
4362/*
4363 * these macros assume that "utime" is a pointer to a utime_t
4364 * they also intentionally leak the declaration of a pointer named "time"
4365 */
4366#define UTIME_TO_TIMESPEC \
4367 struct timespec ts[2]; \
4368 struct timespec *time; \
4369 if (utime->now) \
4370 time = NULL; \
4371 else { \
4372 ts[0].tv_sec = utime->atime_s; \
4373 ts[0].tv_nsec = utime->atime_ns; \
4374 ts[1].tv_sec = utime->mtime_s; \
4375 ts[1].tv_nsec = utime->mtime_ns; \
4376 time = ts; \
4377 } \
4378
4379#define UTIME_TO_TIMEVAL \
4380 struct timeval tv[2]; \
4381 struct timeval *time; \
4382 if (utime->now) \
4383 time = NULL; \
4384 else { \
4385 tv[0].tv_sec = utime->atime_s; \
4386 tv[0].tv_usec = utime->atime_ns / 1000; \
4387 tv[1].tv_sec = utime->mtime_s; \
4388 tv[1].tv_usec = utime->mtime_ns / 1000; \
4389 time = tv; \
4390 } \
4391
4392#define UTIME_TO_UTIMBUF \
4393 struct utimbuf u[2]; \
4394 struct utimbuf *time; \
4395 if (utime->now) \
4396 time = NULL; \
4397 else { \
4398 u.actime = utime->atime_s; \
4399 u.modtime = utime->mtime_s; \
4400 time = u; \
4401 }
4402
4403#define UTIME_TO_TIME_T \
4404 time_t timet[2]; \
4405 struct timet time; \
4406 if (utime->now) \
4407 time = NULL; \
4408 else { \
4409 timet[0] = utime->atime_s; \
4410 timet[1] = utime->mtime_s; \
4411 time = &timet; \
4412 } \
4413
4414
4415#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4416
4417#if UTIME_HAVE_DIR_FD
4418
4419static int
4420utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4421{
4422#ifdef HAVE_UTIMENSAT
4423 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4424 UTIME_TO_TIMESPEC;
4425 return utimensat(dir_fd, path, time, flags);
4426#elif defined(HAVE_FUTIMESAT)
4427 UTIME_TO_TIMEVAL;
4428 /*
4429 * follow_symlinks will never be false here;
4430 * we only allow !follow_symlinks and dir_fd together
4431 * if we have utimensat()
4432 */
4433 assert(follow_symlinks);
4434 return futimesat(dir_fd, path, time);
4435#endif
4436}
4437
4438#endif
4439
4440#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4441
4442#if UTIME_HAVE_FD
4443
4444static int
4445utime_fd(utime_t *utime, int fd)
4446{
4447#ifdef HAVE_FUTIMENS
4448 UTIME_TO_TIMESPEC;
4449 return futimens(fd, time);
4450#else
4451 UTIME_TO_TIMEVAL;
4452 return futimes(fd, time);
4453#endif
4454}
4455
4456#endif
4457
4458
4459#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4460 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4461
4462#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4463
4464static int
4465utime_nofollow_symlinks(utime_t *utime, char *path)
4466{
4467#ifdef HAVE_UTIMENSAT
4468 UTIME_TO_TIMESPEC;
4469 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4470#else
4471 UTIME_TO_TIMEVAL;
4472 return lutimes(path, time);
4473#endif
4474}
4475
4476#endif
4477
4478#ifndef MS_WINDOWS
4479
4480static int
4481utime_default(utime_t *utime, char *path)
4482{
4483#ifdef HAVE_UTIMENSAT
4484 UTIME_TO_TIMESPEC;
4485 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4486#elif defined(HAVE_UTIMES)
4487 UTIME_TO_TIMEVAL;
4488 return utimes(path, time);
4489#elif defined(HAVE_UTIME_H)
4490 UTIME_TO_UTIMBUF;
4491 return utime(path, time);
4492#else
4493 UTIME_TO_TIME_T;
4494 return utime(path, time);
4495#endif
4496}
4497
4498#endif
4499
Larry Hastings76ad59b2012-05-03 00:30:07 -07004500static int
4501split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4502{
4503 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004504 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004505 divmod = PyNumber_Divmod(py_long, billion);
4506 if (!divmod)
4507 goto exit;
4508 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4509 if ((*s == -1) && PyErr_Occurred())
4510 goto exit;
4511 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004512 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004513 goto exit;
4514
4515 result = 1;
4516exit:
4517 Py_XDECREF(divmod);
4518 return result;
4519}
4520
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521static PyObject *
4522posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004523{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004525 PyObject *times = NULL;
4526 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 int dir_fd = DEFAULT_DIR_FD;
4528 int follow_symlinks = 1;
4529 char *keywords[] = {"path", "times", "ns", "dir_fd",
4530 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004531
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004533
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534#ifdef MS_WINDOWS
4535 HANDLE hFile;
4536 FILETIME atime, mtime;
4537#else
4538 int result;
4539#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004540
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004542
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 memset(&path, 0, sizeof(path));
4544#if UTIME_HAVE_FD
4545 path.allow_fd = 1;
4546#endif
4547 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4548 "O&|O$OO&p:utime", keywords,
4549 path_converter, &path,
4550 &times, &ns,
4551#if UTIME_HAVE_DIR_FD
4552 dir_fd_converter, &dir_fd,
4553#else
4554 dir_fd_unavailable, &dir_fd,
4555#endif
4556 &follow_symlinks
4557 ))
4558 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004559
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 if (times && (times != Py_None) && ns) {
4561 PyErr_SetString(PyExc_ValueError,
4562 "utime: you may specify either 'times'"
4563 " or 'ns' but not both");
4564 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 }
4566
4567 if (times && (times != Py_None)) {
4568 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569 PyErr_SetString(PyExc_TypeError,
4570 "utime: 'times' must be either"
4571 " a tuple of two ints or None");
4572 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004573 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004575 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004577 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 &utime.mtime_s, &utime.mtime_ns) == -1) {
4579 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004580 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004581 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004583 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 PyErr_SetString(PyExc_TypeError,
4585 "utime: 'ns' must be a tuple of two ints");
4586 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004589 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004591 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 &utime.mtime_s, &utime.mtime_ns)) {
4593 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004594 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 }
4596 else {
4597 /* times and ns are both None/unspecified. use "now". */
4598 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004599 }
4600
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4602 if (follow_symlinks_specified("utime", follow_symlinks))
4603 goto exit;
4604#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004605
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4607 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4608 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4609 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611#if !defined(HAVE_UTIMENSAT)
4612 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
4613 PyErr_SetString(PyExc_RuntimeError,
4614 "utime: cannot use dir_fd and follow_symlinks "
4615 "together on this platform");
4616 goto exit;
4617 }
4618#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004620#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 Py_BEGIN_ALLOW_THREADS
4622 if (path.wide)
4623 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 NULL, OPEN_EXISTING,
4625 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 else
4627 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 NULL, OPEN_EXISTING,
4629 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 Py_END_ALLOW_THREADS
4631 if (hFile == INVALID_HANDLE_VALUE) {
4632 win32_error_object("utime", path.object);
4633 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004634 }
4635
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004637 SYSTEMTIME now;
4638 GetSystemTime(&now);
4639 if (!SystemTimeToFileTime(&now, &mtime) ||
4640 !SystemTimeToFileTime(&now, &atime)) {
4641 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004643 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004644 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004645 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4647 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004648 }
4649 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4650 /* Avoid putting the file name into the error here,
4651 as that may confuse the user into believing that
4652 something is wrong with the file, when it also
4653 could be the time stamp that gives a problem. */
4654 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004656 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004657#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004659
Larry Hastings9cf065c2012-06-22 16:30:09 -07004660#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4661 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4662 result = utime_nofollow_symlinks(&utime, path.narrow);
4663 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004664#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665
4666#if UTIME_HAVE_DIR_FD
4667 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4668 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4669 else
4670#endif
4671
4672#if UTIME_HAVE_FD
4673 if (path.fd != -1)
4674 result = utime_fd(&utime, path.fd);
4675 else
4676#endif
4677
4678 result = utime_default(&utime, path.narrow);
4679
4680 Py_END_ALLOW_THREADS
4681
4682 if (result < 0) {
4683 /* see previous comment about not putting filename in error here */
4684 return_value = posix_error();
4685 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004686 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004687
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004688#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689
4690 Py_INCREF(Py_None);
4691 return_value = Py_None;
4692
4693exit:
4694 path_cleanup(&path);
4695#ifdef MS_WINDOWS
4696 if (hFile != INVALID_HANDLE_VALUE)
4697 CloseHandle(hFile);
4698#endif
4699 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004700}
4701
Guido van Rossum3b066191991-06-04 19:40:25 +00004702/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004703
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004704PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004705"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004706Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004707
Barry Warsaw53699e91996-12-10 23:23:01 +00004708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004709posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004710{
Victor Stinner8c62be82010-05-06 00:08:46 +00004711 int sts;
4712 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4713 return NULL;
4714 _exit(sts);
4715 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004716}
4717
Martin v. Löwis114619e2002-10-07 06:44:21 +00004718#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4719static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004720free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004721{
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 Py_ssize_t i;
4723 for (i = 0; i < count; i++)
4724 PyMem_Free(array[i]);
4725 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004726}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004727
Antoine Pitrou69f71142009-05-24 21:25:49 +00004728static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004729int fsconvert_strdup(PyObject *o, char**out)
4730{
Victor Stinner8c62be82010-05-06 00:08:46 +00004731 PyObject *bytes;
4732 Py_ssize_t size;
4733 if (!PyUnicode_FSConverter(o, &bytes))
4734 return 0;
4735 size = PyBytes_GET_SIZE(bytes);
4736 *out = PyMem_Malloc(size+1);
4737 if (!*out)
4738 return 0;
4739 memcpy(*out, PyBytes_AsString(bytes), size+1);
4740 Py_DECREF(bytes);
4741 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004742}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004743#endif
4744
Ross Lagerwall7807c352011-03-17 20:20:30 +02004745#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004746static char**
4747parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4748{
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 char **envlist;
4750 Py_ssize_t i, pos, envc;
4751 PyObject *keys=NULL, *vals=NULL;
4752 PyObject *key, *val, *key2, *val2;
4753 char *p, *k, *v;
4754 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004755
Victor Stinner8c62be82010-05-06 00:08:46 +00004756 i = PyMapping_Size(env);
4757 if (i < 0)
4758 return NULL;
4759 envlist = PyMem_NEW(char *, i + 1);
4760 if (envlist == NULL) {
4761 PyErr_NoMemory();
4762 return NULL;
4763 }
4764 envc = 0;
4765 keys = PyMapping_Keys(env);
4766 vals = PyMapping_Values(env);
4767 if (!keys || !vals)
4768 goto error;
4769 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4770 PyErr_Format(PyExc_TypeError,
4771 "env.keys() or env.values() is not a list");
4772 goto error;
4773 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004774
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 for (pos = 0; pos < i; pos++) {
4776 key = PyList_GetItem(keys, pos);
4777 val = PyList_GetItem(vals, pos);
4778 if (!key || !val)
4779 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004780
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 if (PyUnicode_FSConverter(key, &key2) == 0)
4782 goto error;
4783 if (PyUnicode_FSConverter(val, &val2) == 0) {
4784 Py_DECREF(key2);
4785 goto error;
4786 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004787
4788#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4790 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004792 k = PyBytes_AsString(key2);
4793 v = PyBytes_AsString(val2);
4794 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004795
Victor Stinner8c62be82010-05-06 00:08:46 +00004796 p = PyMem_NEW(char, len);
4797 if (p == NULL) {
4798 PyErr_NoMemory();
4799 Py_DECREF(key2);
4800 Py_DECREF(val2);
4801 goto error;
4802 }
4803 PyOS_snprintf(p, len, "%s=%s", k, v);
4804 envlist[envc++] = p;
4805 Py_DECREF(key2);
4806 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004807#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004808 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004809#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 }
4811 Py_DECREF(vals);
4812 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004813
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 envlist[envc] = 0;
4815 *envc_ptr = envc;
4816 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004817
4818error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 Py_XDECREF(keys);
4820 Py_XDECREF(vals);
4821 while (--envc >= 0)
4822 PyMem_DEL(envlist[envc]);
4823 PyMem_DEL(envlist);
4824 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004825}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004826
Ross Lagerwall7807c352011-03-17 20:20:30 +02004827static char**
4828parse_arglist(PyObject* argv, Py_ssize_t *argc)
4829{
4830 int i;
4831 char **argvlist = PyMem_NEW(char *, *argc+1);
4832 if (argvlist == NULL) {
4833 PyErr_NoMemory();
4834 return NULL;
4835 }
4836 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004837 PyObject* item = PySequence_ITEM(argv, i);
4838 if (item == NULL)
4839 goto fail;
4840 if (!fsconvert_strdup(item, &argvlist[i])) {
4841 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004842 goto fail;
4843 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004844 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004845 }
4846 argvlist[*argc] = NULL;
4847 return argvlist;
4848fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004849 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004850 free_string_array(argvlist, *argc);
4851 return NULL;
4852}
4853#endif
4854
4855#ifdef HAVE_EXECV
4856PyDoc_STRVAR(posix_execv__doc__,
4857"execv(path, args)\n\n\
4858Execute an executable path with arguments, replacing current process.\n\
4859\n\
4860 path: path of executable file\n\
4861 args: tuple or list of strings");
4862
4863static PyObject *
4864posix_execv(PyObject *self, PyObject *args)
4865{
4866 PyObject *opath;
4867 char *path;
4868 PyObject *argv;
4869 char **argvlist;
4870 Py_ssize_t argc;
4871
4872 /* execv has two arguments: (path, argv), where
4873 argv is a list or tuple of strings. */
4874
4875 if (!PyArg_ParseTuple(args, "O&O:execv",
4876 PyUnicode_FSConverter,
4877 &opath, &argv))
4878 return NULL;
4879 path = PyBytes_AsString(opath);
4880 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4881 PyErr_SetString(PyExc_TypeError,
4882 "execv() arg 2 must be a tuple or list");
4883 Py_DECREF(opath);
4884 return NULL;
4885 }
4886 argc = PySequence_Size(argv);
4887 if (argc < 1) {
4888 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4889 Py_DECREF(opath);
4890 return NULL;
4891 }
4892
4893 argvlist = parse_arglist(argv, &argc);
4894 if (argvlist == NULL) {
4895 Py_DECREF(opath);
4896 return NULL;
4897 }
4898
4899 execv(path, argvlist);
4900
4901 /* If we get here it's definitely an error */
4902
4903 free_string_array(argvlist, argc);
4904 Py_DECREF(opath);
4905 return posix_error();
4906}
4907
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004909"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910Execute a path with arguments and environment, replacing current process.\n\
4911\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 path: path of executable file\n\
4913 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 env: dictionary of strings mapping to strings\n\
4915\n\
4916On some platforms, you may specify an open file descriptor for path;\n\
4917 execve will execute the program the file descriptor is open to.\n\
4918 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004919
Barry Warsaw53699e91996-12-10 23:23:01 +00004920static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004922{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004923 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004927 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004928 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 /* execve has three arguments: (path, argv, env), where
4931 argv is a list or tuple of strings and env is a dictionary
4932 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004933
Larry Hastings9cf065c2012-06-22 16:30:09 -07004934 memset(&path, 0, sizeof(path));
4935#ifdef HAVE_FEXECVE
4936 path.allow_fd = 1;
4937#endif
4938 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4939 path_converter, &path,
4940 &argv, &env
4941 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 "execve: argv must be a tuple or list");
4947 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 if (!PyMapping_Check(env)) {
4951 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 "execve: environment must be a mapping object");
4953 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004955
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 envlist = parse_envlist(env, &envc);
4962 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 goto fail;
4964
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965#ifdef HAVE_FEXECVE
4966 if (path.fd > -1)
4967 fexecve(path.fd, argvlist, envlist);
4968 else
4969#endif
4970 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971
4972 /* If we get here it's definitely an error */
4973
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975
4976 while (--envc >= 0)
4977 PyMem_DEL(envlist[envc]);
4978 PyMem_DEL(envlist);
4979 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 if (argvlist)
4981 free_string_array(argvlist, argc);
4982 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004983 return NULL;
4984}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985#endif /* HAVE_EXECV */
4986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004987
Guido van Rossuma1065681999-01-25 23:20:23 +00004988#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004991Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004992\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 mode: mode of process creation\n\
4994 path: path of executable file\n\
4995 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004996
4997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004998posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004999{
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 PyObject *opath;
5001 char *path;
5002 PyObject *argv;
5003 char **argvlist;
5004 int mode, i;
5005 Py_ssize_t argc;
5006 Py_intptr_t spawnval;
5007 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 /* spawnv has three arguments: (mode, path, argv), where
5010 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005011
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5013 PyUnicode_FSConverter,
5014 &opath, &argv))
5015 return NULL;
5016 path = PyBytes_AsString(opath);
5017 if (PyList_Check(argv)) {
5018 argc = PyList_Size(argv);
5019 getitem = PyList_GetItem;
5020 }
5021 else if (PyTuple_Check(argv)) {
5022 argc = PyTuple_Size(argv);
5023 getitem = PyTuple_GetItem;
5024 }
5025 else {
5026 PyErr_SetString(PyExc_TypeError,
5027 "spawnv() arg 2 must be a tuple or list");
5028 Py_DECREF(opath);
5029 return NULL;
5030 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 argvlist = PyMem_NEW(char *, argc+1);
5033 if (argvlist == NULL) {
5034 Py_DECREF(opath);
5035 return PyErr_NoMemory();
5036 }
5037 for (i = 0; i < argc; i++) {
5038 if (!fsconvert_strdup((*getitem)(argv, i),
5039 &argvlist[i])) {
5040 free_string_array(argvlist, i);
5041 PyErr_SetString(
5042 PyExc_TypeError,
5043 "spawnv() arg 2 must contain only strings");
5044 Py_DECREF(opath);
5045 return NULL;
5046 }
5047 }
5048 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005049
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005050#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 Py_BEGIN_ALLOW_THREADS
5052 spawnval = spawnv(mode, path, argvlist);
5053 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005054#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 if (mode == _OLD_P_OVERLAY)
5056 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005057
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 Py_BEGIN_ALLOW_THREADS
5059 spawnval = _spawnv(mode, path, argvlist);
5060 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005061#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 free_string_array(argvlist, argc);
5064 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005065
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 if (spawnval == -1)
5067 return posix_error();
5068 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005069#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005071#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005073#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005074}
5075
5076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005078"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005079Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005080\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 mode: mode of process creation\n\
5082 path: path of executable file\n\
5083 args: tuple or list of arguments\n\
5084 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005085
5086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005087posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005088{
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 PyObject *opath;
5090 char *path;
5091 PyObject *argv, *env;
5092 char **argvlist;
5093 char **envlist;
5094 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005095 int mode;
5096 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 Py_intptr_t spawnval;
5098 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5099 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005100
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 /* spawnve has four arguments: (mode, path, argv, env), where
5102 argv is a list or tuple of strings and env is a dictionary
5103 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005104
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5106 PyUnicode_FSConverter,
5107 &opath, &argv, &env))
5108 return NULL;
5109 path = PyBytes_AsString(opath);
5110 if (PyList_Check(argv)) {
5111 argc = PyList_Size(argv);
5112 getitem = PyList_GetItem;
5113 }
5114 else if (PyTuple_Check(argv)) {
5115 argc = PyTuple_Size(argv);
5116 getitem = PyTuple_GetItem;
5117 }
5118 else {
5119 PyErr_SetString(PyExc_TypeError,
5120 "spawnve() arg 2 must be a tuple or list");
5121 goto fail_0;
5122 }
5123 if (!PyMapping_Check(env)) {
5124 PyErr_SetString(PyExc_TypeError,
5125 "spawnve() arg 3 must be a mapping object");
5126 goto fail_0;
5127 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005128
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 argvlist = PyMem_NEW(char *, argc+1);
5130 if (argvlist == NULL) {
5131 PyErr_NoMemory();
5132 goto fail_0;
5133 }
5134 for (i = 0; i < argc; i++) {
5135 if (!fsconvert_strdup((*getitem)(argv, i),
5136 &argvlist[i]))
5137 {
5138 lastarg = i;
5139 goto fail_1;
5140 }
5141 }
5142 lastarg = argc;
5143 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005144
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 envlist = parse_envlist(env, &envc);
5146 if (envlist == NULL)
5147 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005149#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 Py_BEGIN_ALLOW_THREADS
5151 spawnval = spawnve(mode, path, argvlist, envlist);
5152 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005153#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 if (mode == _OLD_P_OVERLAY)
5155 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005156
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 Py_BEGIN_ALLOW_THREADS
5158 spawnval = _spawnve(mode, path, argvlist, envlist);
5159 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160#endif
Tim Peters25059d32001-12-07 20:35:43 +00005161
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 if (spawnval == -1)
5163 (void) posix_error();
5164 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005165#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005167#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005169#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005170
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 while (--envc >= 0)
5172 PyMem_DEL(envlist[envc]);
5173 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005174 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005176 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 Py_DECREF(opath);
5178 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005179}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005180
5181/* OS/2 supports spawnvp & spawnvpe natively */
5182#if defined(PYOS_OS2)
5183PyDoc_STRVAR(posix_spawnvp__doc__,
5184"spawnvp(mode, file, args)\n\n\
5185Execute the program 'file' in a new process, using the environment\n\
5186search path to find the file.\n\
5187\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 mode: mode of process creation\n\
5189 file: executable file name\n\
5190 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005191
5192static PyObject *
5193posix_spawnvp(PyObject *self, PyObject *args)
5194{
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 PyObject *opath;
5196 char *path;
5197 PyObject *argv;
5198 char **argvlist;
5199 int mode, i, argc;
5200 Py_intptr_t spawnval;
5201 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 /* spawnvp has three arguments: (mode, path, argv), where
5204 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5207 PyUnicode_FSConverter,
5208 &opath, &argv))
5209 return NULL;
5210 path = PyBytes_AsString(opath);
5211 if (PyList_Check(argv)) {
5212 argc = PyList_Size(argv);
5213 getitem = PyList_GetItem;
5214 }
5215 else if (PyTuple_Check(argv)) {
5216 argc = PyTuple_Size(argv);
5217 getitem = PyTuple_GetItem;
5218 }
5219 else {
5220 PyErr_SetString(PyExc_TypeError,
5221 "spawnvp() arg 2 must be a tuple or list");
5222 Py_DECREF(opath);
5223 return NULL;
5224 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005225
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 argvlist = PyMem_NEW(char *, argc+1);
5227 if (argvlist == NULL) {
5228 Py_DECREF(opath);
5229 return PyErr_NoMemory();
5230 }
5231 for (i = 0; i < argc; i++) {
5232 if (!fsconvert_strdup((*getitem)(argv, i),
5233 &argvlist[i])) {
5234 free_string_array(argvlist, i);
5235 PyErr_SetString(
5236 PyExc_TypeError,
5237 "spawnvp() arg 2 must contain only strings");
5238 Py_DECREF(opath);
5239 return NULL;
5240 }
5241 }
5242 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005243
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005245#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005249#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005251
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 free_string_array(argvlist, argc);
5253 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005254
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 if (spawnval == -1)
5256 return posix_error();
5257 else
5258 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005259}
5260
5261
5262PyDoc_STRVAR(posix_spawnvpe__doc__,
5263"spawnvpe(mode, file, args, env)\n\n\
5264Execute the program 'file' in a new process, using the environment\n\
5265search path to find the file.\n\
5266\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 mode: mode of process creation\n\
5268 file: executable file name\n\
5269 args: tuple or list of arguments\n\
5270 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005271
5272static PyObject *
5273posix_spawnvpe(PyObject *self, PyObject *args)
5274{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005275 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 char *path;
5277 PyObject *argv, *env;
5278 char **argvlist;
5279 char **envlist;
5280 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005281 int mode;
5282 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 Py_intptr_t spawnval;
5284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5285 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005286
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 /* spawnvpe has four arguments: (mode, path, argv, env), where
5288 argv is a list or tuple of strings and env is a dictionary
5289 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5292 PyUnicode_FSConverter,
5293 &opath, &argv, &env))
5294 return NULL;
5295 path = PyBytes_AsString(opath);
5296 if (PyList_Check(argv)) {
5297 argc = PyList_Size(argv);
5298 getitem = PyList_GetItem;
5299 }
5300 else if (PyTuple_Check(argv)) {
5301 argc = PyTuple_Size(argv);
5302 getitem = PyTuple_GetItem;
5303 }
5304 else {
5305 PyErr_SetString(PyExc_TypeError,
5306 "spawnvpe() arg 2 must be a tuple or list");
5307 goto fail_0;
5308 }
5309 if (!PyMapping_Check(env)) {
5310 PyErr_SetString(PyExc_TypeError,
5311 "spawnvpe() arg 3 must be a mapping object");
5312 goto fail_0;
5313 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 argvlist = PyMem_NEW(char *, argc+1);
5316 if (argvlist == NULL) {
5317 PyErr_NoMemory();
5318 goto fail_0;
5319 }
5320 for (i = 0; i < argc; i++) {
5321 if (!fsconvert_strdup((*getitem)(argv, i),
5322 &argvlist[i]))
5323 {
5324 lastarg = i;
5325 goto fail_1;
5326 }
5327 }
5328 lastarg = argc;
5329 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005330
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 envlist = parse_envlist(env, &envc);
5332 if (envlist == NULL)
5333 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005334
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005336#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005338#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005340#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005342
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 if (spawnval == -1)
5344 (void) posix_error();
5345 else
5346 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 while (--envc >= 0)
5349 PyMem_DEL(envlist[envc]);
5350 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005351 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005353 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 Py_DECREF(opath);
5355 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005356}
5357#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005358#endif /* HAVE_SPAWNV */
5359
5360
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005361#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005364Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5365\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005366Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005367
5368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005369posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 pid_t pid;
5372 int result = 0;
5373 _PyImport_AcquireLock();
5374 pid = fork1();
5375 if (pid == 0) {
5376 /* child: this clobbers and resets the import lock. */
5377 PyOS_AfterFork();
5378 } else {
5379 /* parent: release the import lock. */
5380 result = _PyImport_ReleaseLock();
5381 }
5382 if (pid == -1)
5383 return posix_error();
5384 if (result < 0) {
5385 /* Don't clobber the OSError if the fork failed. */
5386 PyErr_SetString(PyExc_RuntimeError,
5387 "not holding the import lock");
5388 return NULL;
5389 }
5390 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005391}
5392#endif
5393
5394
Guido van Rossumad0ee831995-03-01 10:34:45 +00005395#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005397"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005398Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005402posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005403{
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 pid_t pid;
5405 int result = 0;
5406 _PyImport_AcquireLock();
5407 pid = fork();
5408 if (pid == 0) {
5409 /* child: this clobbers and resets the import lock. */
5410 PyOS_AfterFork();
5411 } else {
5412 /* parent: release the import lock. */
5413 result = _PyImport_ReleaseLock();
5414 }
5415 if (pid == -1)
5416 return posix_error();
5417 if (result < 0) {
5418 /* Don't clobber the OSError if the fork failed. */
5419 PyErr_SetString(PyExc_RuntimeError,
5420 "not holding the import lock");
5421 return NULL;
5422 }
5423 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005424}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005426
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005427#ifdef HAVE_SCHED_H
5428
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005429#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5430
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005431PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5432"sched_get_priority_max(policy)\n\n\
5433Get the maximum scheduling priority for *policy*.");
5434
5435static PyObject *
5436posix_sched_get_priority_max(PyObject *self, PyObject *args)
5437{
5438 int policy, max;
5439
5440 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5441 return NULL;
5442 max = sched_get_priority_max(policy);
5443 if (max < 0)
5444 return posix_error();
5445 return PyLong_FromLong(max);
5446}
5447
5448PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5449"sched_get_priority_min(policy)\n\n\
5450Get the minimum scheduling priority for *policy*.");
5451
5452static PyObject *
5453posix_sched_get_priority_min(PyObject *self, PyObject *args)
5454{
5455 int policy, min;
5456
5457 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5458 return NULL;
5459 min = sched_get_priority_min(policy);
5460 if (min < 0)
5461 return posix_error();
5462 return PyLong_FromLong(min);
5463}
5464
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005465#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5466
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005467#ifdef HAVE_SCHED_SETSCHEDULER
5468
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005469PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5470"sched_getscheduler(pid)\n\n\
5471Get the scheduling policy for the process with a PID of *pid*.\n\
5472Passing a PID of 0 returns the scheduling policy for the calling process.");
5473
5474static PyObject *
5475posix_sched_getscheduler(PyObject *self, PyObject *args)
5476{
5477 pid_t pid;
5478 int policy;
5479
5480 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5481 return NULL;
5482 policy = sched_getscheduler(pid);
5483 if (policy < 0)
5484 return posix_error();
5485 return PyLong_FromLong(policy);
5486}
5487
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005488#endif
5489
5490#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492static PyObject *
5493sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5494{
5495 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005496 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005497
5498 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5499 return NULL;
5500 res = PyStructSequence_New(type);
5501 if (!res)
5502 return NULL;
5503 Py_INCREF(priority);
5504 PyStructSequence_SET_ITEM(res, 0, priority);
5505 return res;
5506}
5507
5508PyDoc_STRVAR(sched_param__doc__,
5509"sched_param(sched_priority): A scheduling parameter.\n\n\
5510Current has only one field: sched_priority");
5511
5512static PyStructSequence_Field sched_param_fields[] = {
5513 {"sched_priority", "the scheduling priority"},
5514 {0}
5515};
5516
5517static PyStructSequence_Desc sched_param_desc = {
5518 "sched_param", /* name */
5519 sched_param__doc__, /* doc */
5520 sched_param_fields,
5521 1
5522};
5523
5524static int
5525convert_sched_param(PyObject *param, struct sched_param *res)
5526{
5527 long priority;
5528
5529 if (Py_TYPE(param) != &SchedParamType) {
5530 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5531 return 0;
5532 }
5533 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5534 if (priority == -1 && PyErr_Occurred())
5535 return 0;
5536 if (priority > INT_MAX || priority < INT_MIN) {
5537 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5538 return 0;
5539 }
5540 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5541 return 1;
5542}
5543
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005544#endif
5545
5546#ifdef HAVE_SCHED_SETSCHEDULER
5547
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5549"sched_setscheduler(pid, policy, param)\n\n\
5550Set the scheduling policy, *policy*, for *pid*.\n\
5551If *pid* is 0, the calling process is changed.\n\
5552*param* is an instance of sched_param.");
5553
5554static PyObject *
5555posix_sched_setscheduler(PyObject *self, PyObject *args)
5556{
5557 pid_t pid;
5558 int policy;
5559 struct sched_param param;
5560
5561 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5562 &pid, &policy, &convert_sched_param, &param))
5563 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005564
5565 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005566 ** sched_setscheduler() returns 0 in Linux, but the previous
5567 ** scheduling policy under Solaris/Illumos, and others.
5568 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005569 */
5570 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571 return posix_error();
5572 Py_RETURN_NONE;
5573}
5574
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005575#endif
5576
5577#ifdef HAVE_SCHED_SETPARAM
5578
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579PyDoc_STRVAR(posix_sched_getparam__doc__,
5580"sched_getparam(pid) -> sched_param\n\n\
5581Returns scheduling parameters for the process with *pid* as an instance of the\n\
5582sched_param class. A PID of 0 means the calling process.");
5583
5584static PyObject *
5585posix_sched_getparam(PyObject *self, PyObject *args)
5586{
5587 pid_t pid;
5588 struct sched_param param;
5589 PyObject *res, *priority;
5590
5591 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5592 return NULL;
5593 if (sched_getparam(pid, &param))
5594 return posix_error();
5595 res = PyStructSequence_New(&SchedParamType);
5596 if (!res)
5597 return NULL;
5598 priority = PyLong_FromLong(param.sched_priority);
5599 if (!priority) {
5600 Py_DECREF(res);
5601 return NULL;
5602 }
5603 PyStructSequence_SET_ITEM(res, 0, priority);
5604 return res;
5605}
5606
5607PyDoc_STRVAR(posix_sched_setparam__doc__,
5608"sched_setparam(pid, param)\n\n\
5609Set scheduling parameters for a process with PID *pid*.\n\
5610A PID of 0 means the calling process.");
5611
5612static PyObject *
5613posix_sched_setparam(PyObject *self, PyObject *args)
5614{
5615 pid_t pid;
5616 struct sched_param param;
5617
5618 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5619 &pid, &convert_sched_param, &param))
5620 return NULL;
5621 if (sched_setparam(pid, &param))
5622 return posix_error();
5623 Py_RETURN_NONE;
5624}
5625
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005626#endif
5627
5628#ifdef HAVE_SCHED_RR_GET_INTERVAL
5629
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005630PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5631"sched_rr_get_interval(pid) -> float\n\n\
5632Return the round-robin quantum for the process with PID *pid* in seconds.");
5633
5634static PyObject *
5635posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5636{
5637 pid_t pid;
5638 struct timespec interval;
5639
5640 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5641 return NULL;
5642 if (sched_rr_get_interval(pid, &interval))
5643 return posix_error();
5644 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5645}
5646
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005647#endif
5648
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005649PyDoc_STRVAR(posix_sched_yield__doc__,
5650"sched_yield()\n\n\
5651Voluntarily relinquish the CPU.");
5652
5653static PyObject *
5654posix_sched_yield(PyObject *self, PyObject *noargs)
5655{
5656 if (sched_yield())
5657 return posix_error();
5658 Py_RETURN_NONE;
5659}
5660
Benjamin Peterson2740af82011-08-02 17:41:34 -05005661#ifdef HAVE_SCHED_SETAFFINITY
5662
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005663typedef struct {
5664 PyObject_HEAD;
5665 Py_ssize_t size;
5666 int ncpus;
5667 cpu_set_t *set;
5668} Py_cpu_set;
5669
5670static PyTypeObject cpu_set_type;
5671
5672static void
5673cpu_set_dealloc(Py_cpu_set *set)
5674{
5675 assert(set->set);
5676 CPU_FREE(set->set);
5677 Py_TYPE(set)->tp_free(set);
5678}
5679
5680static Py_cpu_set *
5681make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5682{
5683 Py_cpu_set *set;
5684
5685 if (size < 0) {
5686 PyErr_SetString(PyExc_ValueError, "negative size");
5687 return NULL;
5688 }
5689 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5690 if (!set)
5691 return NULL;
5692 set->ncpus = size;
5693 set->size = CPU_ALLOC_SIZE(size);
5694 set->set = CPU_ALLOC(size);
5695 if (!set->set) {
5696 type->tp_free(set);
5697 PyErr_NoMemory();
5698 return NULL;
5699 }
5700 CPU_ZERO_S(set->size, set->set);
5701 return set;
5702}
5703
5704static PyObject *
5705cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5706{
5707 int size;
5708
5709 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5710 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5711 return NULL;
5712 return (PyObject *)make_new_cpu_set(type, size);
5713}
5714
5715static PyObject *
5716cpu_set_repr(Py_cpu_set *set)
5717{
5718 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005719}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005720
5721static Py_ssize_t
5722cpu_set_len(Py_cpu_set *set)
5723{
5724 return set->ncpus;
5725}
5726
5727static int
5728_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5729{
5730 int cpu;
5731 if (!PyArg_ParseTuple(args, requester, &cpu))
5732 return -1;
5733 if (cpu < 0) {
5734 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5735 return -1;
5736 }
5737 if (cpu >= set->ncpus) {
5738 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5739 return -1;
5740 }
5741 return cpu;
5742}
5743
5744PyDoc_STRVAR(cpu_set_set_doc,
5745"cpu_set.set(i)\n\n\
5746Add CPU *i* to the set.");
5747
5748static PyObject *
5749cpu_set_set(Py_cpu_set *set, PyObject *args)
5750{
5751 int cpu = _get_cpu(set, "i|set", args);
5752 if (cpu == -1)
5753 return NULL;
5754 CPU_SET_S(cpu, set->size, set->set);
5755 Py_RETURN_NONE;
5756}
5757
5758PyDoc_STRVAR(cpu_set_count_doc,
5759"cpu_set.count() -> int\n\n\
5760Return the number of CPUs active in the set.");
5761
5762static PyObject *
5763cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5764{
5765 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5766}
5767
5768PyDoc_STRVAR(cpu_set_clear_doc,
5769"cpu_set.clear(i)\n\n\
5770Remove CPU *i* from the set.");
5771
5772static PyObject *
5773cpu_set_clear(Py_cpu_set *set, PyObject *args)
5774{
5775 int cpu = _get_cpu(set, "i|clear", args);
5776 if (cpu == -1)
5777 return NULL;
5778 CPU_CLR_S(cpu, set->size, set->set);
5779 Py_RETURN_NONE;
5780}
5781
5782PyDoc_STRVAR(cpu_set_isset_doc,
5783"cpu_set.isset(i) -> bool\n\n\
5784Test if CPU *i* is in the set.");
5785
5786static PyObject *
5787cpu_set_isset(Py_cpu_set *set, PyObject *args)
5788{
5789 int cpu = _get_cpu(set, "i|isset", args);
5790 if (cpu == -1)
5791 return NULL;
5792 if (CPU_ISSET_S(cpu, set->size, set->set))
5793 Py_RETURN_TRUE;
5794 Py_RETURN_FALSE;
5795}
5796
5797PyDoc_STRVAR(cpu_set_zero_doc,
5798"cpu_set.zero()\n\n\
5799Clear the cpu_set.");
5800
5801static PyObject *
5802cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5803{
5804 CPU_ZERO_S(set->size, set->set);
5805 Py_RETURN_NONE;
5806}
5807
5808static PyObject *
5809cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5810{
5811 int eq;
5812
Brian Curtindfc80e32011-08-10 20:28:54 -05005813 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5814 Py_RETURN_NOTIMPLEMENTED;
5815
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005816 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5817 if ((op == Py_EQ) ? eq : !eq)
5818 Py_RETURN_TRUE;
5819 else
5820 Py_RETURN_FALSE;
5821}
5822
5823#define CPU_SET_BINOP(name, op) \
5824 static PyObject * \
5825 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5826 if (res) { \
5827 Py_INCREF(res); \
5828 } \
5829 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005830 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831 if (!res) \
5832 return NULL; \
5833 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005834 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005835 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005836 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005837 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005838 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005839 op(res->size, res->set, left->set, right->set); \
5840 return (PyObject *)res; \
5841 } \
5842 static PyObject * \
5843 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5844 return do_cpu_set_##name(left, right, NULL); \
5845 } \
5846 static PyObject * \
5847 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5848 return do_cpu_set_##name(left, right, left); \
5849 } \
5850
5851CPU_SET_BINOP(and, CPU_AND_S)
5852CPU_SET_BINOP(or, CPU_OR_S)
5853CPU_SET_BINOP(xor, CPU_XOR_S)
5854#undef CPU_SET_BINOP
5855
5856PyDoc_STRVAR(cpu_set_doc,
5857"cpu_set(size)\n\n\
5858Create an empty mask of CPUs.");
5859
5860static PyNumberMethods cpu_set_as_number = {
5861 0, /*nb_add*/
5862 0, /*nb_subtract*/
5863 0, /*nb_multiply*/
5864 0, /*nb_remainder*/
5865 0, /*nb_divmod*/
5866 0, /*nb_power*/
5867 0, /*nb_negative*/
5868 0, /*nb_positive*/
5869 0, /*nb_absolute*/
5870 0, /*nb_bool*/
5871 0, /*nb_invert*/
5872 0, /*nb_lshift*/
5873 0, /*nb_rshift*/
5874 (binaryfunc)cpu_set_and, /*nb_and*/
5875 (binaryfunc)cpu_set_xor, /*nb_xor*/
5876 (binaryfunc)cpu_set_or, /*nb_or*/
5877 0, /*nb_int*/
5878 0, /*nb_reserved*/
5879 0, /*nb_float*/
5880 0, /*nb_inplace_add*/
5881 0, /*nb_inplace_subtract*/
5882 0, /*nb_inplace_multiply*/
5883 0, /*nb_inplace_remainder*/
5884 0, /*nb_inplace_power*/
5885 0, /*nb_inplace_lshift*/
5886 0, /*nb_inplace_rshift*/
5887 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5888 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5889 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5890};
5891
5892static PySequenceMethods cpu_set_as_sequence = {
5893 (lenfunc)cpu_set_len, /* sq_length */
5894};
5895
5896static PyMethodDef cpu_set_methods[] = {
5897 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5898 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5899 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5900 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5901 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5902 {NULL, NULL} /* sentinel */
5903};
5904
5905static PyTypeObject cpu_set_type = {
5906 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5907 "posix.cpu_set", /* tp_name */
5908 sizeof(Py_cpu_set), /* tp_basicsize */
5909 0, /* tp_itemsize */
5910 /* methods */
5911 (destructor)cpu_set_dealloc, /* tp_dealloc */
5912 0, /* tp_print */
5913 0, /* tp_getattr */
5914 0, /* tp_setattr */
5915 0, /* tp_reserved */
5916 (reprfunc)cpu_set_repr, /* tp_repr */
5917 &cpu_set_as_number, /* tp_as_number */
5918 &cpu_set_as_sequence, /* tp_as_sequence */
5919 0, /* tp_as_mapping */
5920 PyObject_HashNotImplemented, /* tp_hash */
5921 0, /* tp_call */
5922 0, /* tp_str */
5923 PyObject_GenericGetAttr, /* tp_getattro */
5924 0, /* tp_setattro */
5925 0, /* tp_as_buffer */
5926 Py_TPFLAGS_DEFAULT, /* tp_flags */
5927 cpu_set_doc, /* tp_doc */
5928 0, /* tp_traverse */
5929 0, /* tp_clear */
5930 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5931 0, /* tp_weaklistoffset */
5932 0, /* tp_iter */
5933 0, /* tp_iternext */
5934 cpu_set_methods, /* tp_methods */
5935 0, /* tp_members */
5936 0, /* tp_getset */
5937 0, /* tp_base */
5938 0, /* tp_dict */
5939 0, /* tp_descr_get */
5940 0, /* tp_descr_set */
5941 0, /* tp_dictoffset */
5942 0, /* tp_init */
5943 PyType_GenericAlloc, /* tp_alloc */
5944 cpu_set_new, /* tp_new */
5945 PyObject_Del, /* tp_free */
5946};
5947
5948PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5949"sched_setaffinity(pid, cpu_set)\n\n\
5950Set the affinity of the process with PID *pid* to *cpu_set*.");
5951
5952static PyObject *
5953posix_sched_setaffinity(PyObject *self, PyObject *args)
5954{
5955 pid_t pid;
5956 Py_cpu_set *cpu_set;
5957
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005958 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005959 &pid, &cpu_set_type, &cpu_set))
5960 return NULL;
5961 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5962 return posix_error();
5963 Py_RETURN_NONE;
5964}
5965
5966PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5967"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5968Return the affinity of the process with PID *pid*.\n\
5969The returned cpu_set will be of size *ncpus*.");
5970
5971static PyObject *
5972posix_sched_getaffinity(PyObject *self, PyObject *args)
5973{
5974 pid_t pid;
5975 int ncpus;
5976 Py_cpu_set *res;
5977
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005978 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005979 &pid, &ncpus))
5980 return NULL;
5981 res = make_new_cpu_set(&cpu_set_type, ncpus);
5982 if (!res)
5983 return NULL;
5984 if (sched_getaffinity(pid, res->size, res->set)) {
5985 Py_DECREF(res);
5986 return posix_error();
5987 }
5988 return (PyObject *)res;
5989}
5990
Benjamin Peterson2740af82011-08-02 17:41:34 -05005991#endif /* HAVE_SCHED_SETAFFINITY */
5992
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993#endif /* HAVE_SCHED_H */
5994
Neal Norwitzb59798b2003-03-21 01:43:31 +00005995/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005996/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5997#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005998#define DEV_PTY_FILE "/dev/ptc"
5999#define HAVE_DEV_PTMX
6000#else
6001#define DEV_PTY_FILE "/dev/ptmx"
6002#endif
6003
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006004#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005#ifdef HAVE_PTY_H
6006#include <pty.h>
6007#else
6008#ifdef HAVE_LIBUTIL_H
6009#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006010#else
6011#ifdef HAVE_UTIL_H
6012#include <util.h>
6013#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014#endif /* HAVE_LIBUTIL_H */
6015#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006016#ifdef HAVE_STROPTS_H
6017#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006018#endif
6019#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006025
6026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006027posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006028{
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006030#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006032#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006035#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#endif
6038#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006039
Thomas Wouters70c21a12000-07-14 14:28:33 +00006040#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6042 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006043#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6045 if (slave_name == NULL)
6046 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006047
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 slave_fd = open(slave_name, O_RDWR);
6049 if (slave_fd < 0)
6050 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006051#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6053 if (master_fd < 0)
6054 return posix_error();
6055 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6056 /* change permission of slave */
6057 if (grantpt(master_fd) < 0) {
6058 PyOS_setsig(SIGCHLD, sig_saved);
6059 return posix_error();
6060 }
6061 /* unlock slave */
6062 if (unlockpt(master_fd) < 0) {
6063 PyOS_setsig(SIGCHLD, sig_saved);
6064 return posix_error();
6065 }
6066 PyOS_setsig(SIGCHLD, sig_saved);
6067 slave_name = ptsname(master_fd); /* get name of slave */
6068 if (slave_name == NULL)
6069 return posix_error();
6070 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6071 if (slave_fd < 0)
6072 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006073#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6075 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006076#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006078#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006079#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006080#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006081
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006083
Fred Drake8cef4cf2000-06-28 16:40:38 +00006084}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006085#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006086
6087#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006089"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006090Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6091Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006093
6094static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006095posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006096{
Victor Stinner8c62be82010-05-06 00:08:46 +00006097 int master_fd = -1, result = 0;
6098 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006099
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 _PyImport_AcquireLock();
6101 pid = forkpty(&master_fd, NULL, NULL, NULL);
6102 if (pid == 0) {
6103 /* child: this clobbers and resets the import lock. */
6104 PyOS_AfterFork();
6105 } else {
6106 /* parent: release the import lock. */
6107 result = _PyImport_ReleaseLock();
6108 }
6109 if (pid == -1)
6110 return posix_error();
6111 if (result < 0) {
6112 /* Don't clobber the OSError if the fork failed. */
6113 PyErr_SetString(PyExc_RuntimeError,
6114 "not holding the import lock");
6115 return NULL;
6116 }
6117 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006118}
6119#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006120
Ross Lagerwall7807c352011-03-17 20:20:30 +02006121
Guido van Rossumad0ee831995-03-01 10:34:45 +00006122#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006128posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006129{
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006131}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006132#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Guido van Rossumad0ee831995-03-01 10:34:45 +00006135#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006139
Barry Warsaw53699e91996-12-10 23:23:01 +00006140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006141posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006144}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006145#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006147
Guido van Rossumad0ee831995-03-01 10:34:45 +00006148#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Barry Warsaw53699e91996-12-10 23:23:01 +00006153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006155{
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006157}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006158#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006162"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006164
Barry Warsaw53699e91996-12-10 23:23:01 +00006165static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006166posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006167{
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006169}
6170
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006171#ifdef HAVE_GETGROUPLIST
6172PyDoc_STRVAR(posix_getgrouplist__doc__,
6173"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6174Returns a list of groups to which a user belongs.\n\n\
6175 user: username to lookup\n\
6176 group: base group id of the user");
6177
6178static PyObject *
6179posix_getgrouplist(PyObject *self, PyObject *args)
6180{
6181#ifdef NGROUPS_MAX
6182#define MAX_GROUPS NGROUPS_MAX
6183#else
6184 /* defined to be 16 on Solaris7, so this should be a small number */
6185#define MAX_GROUPS 64
6186#endif
6187
6188 const char *user;
6189 int i, ngroups;
6190 PyObject *list;
6191#ifdef __APPLE__
6192 int *groups, basegid;
6193#else
6194 gid_t *groups, basegid;
6195#endif
6196 ngroups = MAX_GROUPS;
6197
6198 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6199 return NULL;
6200
6201#ifdef __APPLE__
6202 groups = PyMem_Malloc(ngroups * sizeof(int));
6203#else
6204 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6205#endif
6206 if (groups == NULL)
6207 return PyErr_NoMemory();
6208
6209 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6210 PyMem_Del(groups);
6211 return posix_error();
6212 }
6213
6214 list = PyList_New(ngroups);
6215 if (list == NULL) {
6216 PyMem_Del(groups);
6217 return NULL;
6218 }
6219
6220 for (i = 0; i < ngroups; i++) {
6221 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6222 if (o == NULL) {
6223 Py_DECREF(list);
6224 PyMem_Del(groups);
6225 return NULL;
6226 }
6227 PyList_SET_ITEM(list, i, o);
6228 }
6229
6230 PyMem_Del(groups);
6231
6232 return list;
6233}
6234#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006235
Fred Drakec9680921999-12-13 16:37:25 +00006236#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006238"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006240
6241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006242posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006243{
6244 PyObject *result = NULL;
6245
Fred Drakec9680921999-12-13 16:37:25 +00006246#ifdef NGROUPS_MAX
6247#define MAX_GROUPS NGROUPS_MAX
6248#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006250#define MAX_GROUPS 64
6251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006254 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006255 * This is a helper variable to store the intermediate result when
6256 * that happens.
6257 *
6258 * To keep the code readable the OSX behaviour is unconditional,
6259 * according to the POSIX spec this should be safe on all unix-y
6260 * systems.
6261 */
6262 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006263 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006264
Victor Stinner8c62be82010-05-06 00:08:46 +00006265 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006266 if (n < 0) {
6267 if (errno == EINVAL) {
6268 n = getgroups(0, NULL);
6269 if (n == -1) {
6270 return posix_error();
6271 }
6272 if (n == 0) {
6273 /* Avoid malloc(0) */
6274 alt_grouplist = grouplist;
6275 } else {
6276 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6277 if (alt_grouplist == NULL) {
6278 errno = EINVAL;
6279 return posix_error();
6280 }
6281 n = getgroups(n, alt_grouplist);
6282 if (n == -1) {
6283 PyMem_Free(alt_grouplist);
6284 return posix_error();
6285 }
6286 }
6287 } else {
6288 return posix_error();
6289 }
6290 }
6291 result = PyList_New(n);
6292 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 int i;
6294 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006295 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006297 Py_DECREF(result);
6298 result = NULL;
6299 break;
Fred Drakec9680921999-12-13 16:37:25 +00006300 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006302 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006303 }
6304
6305 if (alt_grouplist != grouplist) {
6306 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006308
Fred Drakec9680921999-12-13 16:37:25 +00006309 return result;
6310}
6311#endif
6312
Antoine Pitroub7572f02009-12-02 20:46:48 +00006313#ifdef HAVE_INITGROUPS
6314PyDoc_STRVAR(posix_initgroups__doc__,
6315"initgroups(username, gid) -> None\n\n\
6316Call the system initgroups() to initialize the group access list with all of\n\
6317the groups of which the specified username is a member, plus the specified\n\
6318group id.");
6319
6320static PyObject *
6321posix_initgroups(PyObject *self, PyObject *args)
6322{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006323 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006325 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006327
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006328 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6329 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006331 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006332
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006333 res = initgroups(username, (gid_t) gid);
6334 Py_DECREF(oname);
6335 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006337
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 Py_INCREF(Py_None);
6339 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006340}
6341#endif
6342
Martin v. Löwis606edc12002-06-13 21:09:11 +00006343#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006344PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006345"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006346Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006347
6348static PyObject *
6349posix_getpgid(PyObject *self, PyObject *args)
6350{
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 pid_t pid, pgid;
6352 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6353 return NULL;
6354 pgid = getpgid(pid);
6355 if (pgid < 0)
6356 return posix_error();
6357 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006358}
6359#endif /* HAVE_GETPGID */
6360
6361
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006364"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006366
Barry Warsaw53699e91996-12-10 23:23:01 +00006367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006368posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006369{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006372#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006374#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006375}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006380PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006381"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006382Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006383
Barry Warsaw53699e91996-12-10 23:23:01 +00006384static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006385posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006386{
Guido van Rossum64933891994-10-20 21:56:42 +00006387#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006389#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006391#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 return posix_error();
6393 Py_INCREF(Py_None);
6394 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006395}
6396
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#endif /* HAVE_SETPGRP */
6398
Guido van Rossumad0ee831995-03-01 10:34:45 +00006399#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006400
6401#ifdef MS_WINDOWS
6402#include <tlhelp32.h>
6403
6404static PyObject*
6405win32_getppid()
6406{
6407 HANDLE snapshot;
6408 pid_t mypid;
6409 PyObject* result = NULL;
6410 BOOL have_record;
6411 PROCESSENTRY32 pe;
6412
6413 mypid = getpid(); /* This function never fails */
6414
6415 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6416 if (snapshot == INVALID_HANDLE_VALUE)
6417 return PyErr_SetFromWindowsErr(GetLastError());
6418
6419 pe.dwSize = sizeof(pe);
6420 have_record = Process32First(snapshot, &pe);
6421 while (have_record) {
6422 if (mypid == (pid_t)pe.th32ProcessID) {
6423 /* We could cache the ulong value in a static variable. */
6424 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6425 break;
6426 }
6427
6428 have_record = Process32Next(snapshot, &pe);
6429 }
6430
6431 /* If our loop exits and our pid was not found (result will be NULL)
6432 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6433 * error anyway, so let's raise it. */
6434 if (!result)
6435 result = PyErr_SetFromWindowsErr(GetLastError());
6436
6437 CloseHandle(snapshot);
6438
6439 return result;
6440}
6441#endif /*MS_WINDOWS*/
6442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006445Return the parent's process id. If the parent process has already exited,\n\
6446Windows machines will still return its id; others systems will return the id\n\
6447of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006448
Barry Warsaw53699e91996-12-10 23:23:01 +00006449static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006450posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006451{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006452#ifdef MS_WINDOWS
6453 return win32_getppid();
6454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457}
6458#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Fred Drake12c6e2d1999-12-14 21:25:03 +00006461#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006462PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006463"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006464Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465
6466static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006467posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006468{
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006470#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006471 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006472 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006473
6474 if (GetUserNameW(user_name, &num_chars)) {
6475 /* num_chars is the number of unicode chars plus null terminator */
6476 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006477 }
6478 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006479 result = PyErr_SetFromWindowsErr(GetLastError());
6480#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 char *name;
6482 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 errno = 0;
6485 name = getlogin();
6486 if (name == NULL) {
6487 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006488 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006489 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006490 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 }
6492 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006493 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006495#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006496 return result;
6497}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006499
Guido van Rossumad0ee831995-03-01 10:34:45 +00006500#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006502"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006503Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Barry Warsaw53699e91996-12-10 23:23:01 +00006505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006506posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006507{
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006509}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006510#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Guido van Rossumad0ee831995-03-01 10:34:45 +00006513#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006515"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006517
Barry Warsaw53699e91996-12-10 23:23:01 +00006518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006519posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006520{
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 pid_t pid;
6522 int sig;
6523 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6524 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006525#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006526 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6527 APIRET rc;
6528 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006529 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006530
6531 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6532 APIRET rc;
6533 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006534 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006535
6536 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006537 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006538#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 if (kill(pid, sig) == -1)
6540 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006541#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 Py_INCREF(Py_None);
6543 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006544}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006545#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006546
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006547#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006549"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006551
6552static PyObject *
6553posix_killpg(PyObject *self, PyObject *args)
6554{
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 int sig;
6556 pid_t pgid;
6557 /* XXX some man pages make the `pgid` parameter an int, others
6558 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6559 take the same type. Moreover, pid_t is always at least as wide as
6560 int (else compilation of this module fails), which is safe. */
6561 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6562 return NULL;
6563 if (killpg(pgid, sig) == -1)
6564 return posix_error();
6565 Py_INCREF(Py_None);
6566 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006567}
6568#endif
6569
Brian Curtineb24d742010-04-12 17:16:38 +00006570#ifdef MS_WINDOWS
6571PyDoc_STRVAR(win32_kill__doc__,
6572"kill(pid, sig)\n\n\
6573Kill a process with a signal.");
6574
6575static PyObject *
6576win32_kill(PyObject *self, PyObject *args)
6577{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006578 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 DWORD pid, sig, err;
6580 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6583 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006584
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 /* Console processes which share a common console can be sent CTRL+C or
6586 CTRL+BREAK events, provided they handle said events. */
6587 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6588 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6589 err = GetLastError();
6590 PyErr_SetFromWindowsErr(err);
6591 }
6592 else
6593 Py_RETURN_NONE;
6594 }
Brian Curtineb24d742010-04-12 17:16:38 +00006595
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6597 attempt to open and terminate the process. */
6598 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6599 if (handle == NULL) {
6600 err = GetLastError();
6601 return PyErr_SetFromWindowsErr(err);
6602 }
Brian Curtineb24d742010-04-12 17:16:38 +00006603
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 if (TerminateProcess(handle, sig) == 0) {
6605 err = GetLastError();
6606 result = PyErr_SetFromWindowsErr(err);
6607 } else {
6608 Py_INCREF(Py_None);
6609 result = Py_None;
6610 }
Brian Curtineb24d742010-04-12 17:16:38 +00006611
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 CloseHandle(handle);
6613 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006614}
6615#endif /* MS_WINDOWS */
6616
Guido van Rossumc0125471996-06-28 18:55:32 +00006617#ifdef HAVE_PLOCK
6618
6619#ifdef HAVE_SYS_LOCK_H
6620#include <sys/lock.h>
6621#endif
6622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006624"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006626
Barry Warsaw53699e91996-12-10 23:23:01 +00006627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006628posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006629{
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 int op;
6631 if (!PyArg_ParseTuple(args, "i:plock", &op))
6632 return NULL;
6633 if (plock(op) == -1)
6634 return posix_error();
6635 Py_INCREF(Py_None);
6636 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006637}
6638#endif
6639
Guido van Rossumb6775db1994-08-01 11:34:53 +00006640#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006642"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006643Set the current process's user id.");
6644
Barry Warsaw53699e91996-12-10 23:23:01 +00006645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006646posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006647{
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 long uid_arg;
6649 uid_t uid;
6650 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6651 return NULL;
6652 uid = uid_arg;
6653 if (uid != uid_arg) {
6654 PyErr_SetString(PyExc_OverflowError, "user id too big");
6655 return NULL;
6656 }
6657 if (setuid(uid) < 0)
6658 return posix_error();
6659 Py_INCREF(Py_None);
6660 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006661}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006662#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006665#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Set the current process's effective user id.");
6669
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006670static PyObject *
6671posix_seteuid (PyObject *self, PyObject *args)
6672{
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 long euid_arg;
6674 uid_t euid;
6675 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6676 return NULL;
6677 euid = euid_arg;
6678 if (euid != euid_arg) {
6679 PyErr_SetString(PyExc_OverflowError, "user id too big");
6680 return NULL;
6681 }
6682 if (seteuid(euid) < 0) {
6683 return posix_error();
6684 } else {
6685 Py_INCREF(Py_None);
6686 return Py_None;
6687 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETEUID */
6690
6691#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006693"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006694Set the current process's effective group id.");
6695
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006696static PyObject *
6697posix_setegid (PyObject *self, PyObject *args)
6698{
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 long egid_arg;
6700 gid_t egid;
6701 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6702 return NULL;
6703 egid = egid_arg;
6704 if (egid != egid_arg) {
6705 PyErr_SetString(PyExc_OverflowError, "group id too big");
6706 return NULL;
6707 }
6708 if (setegid(egid) < 0) {
6709 return posix_error();
6710 } else {
6711 Py_INCREF(Py_None);
6712 return Py_None;
6713 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETEGID */
6716
6717#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006719"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720Set the current process's real and effective user ids.");
6721
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006722static PyObject *
6723posix_setreuid (PyObject *self, PyObject *args)
6724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 long ruid_arg, euid_arg;
6726 uid_t ruid, euid;
6727 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6728 return NULL;
6729 if (ruid_arg == -1)
6730 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6731 else
6732 ruid = ruid_arg; /* otherwise, assign from our long */
6733 if (euid_arg == -1)
6734 euid = (uid_t)-1;
6735 else
6736 euid = euid_arg;
6737 if ((euid_arg != -1 && euid != euid_arg) ||
6738 (ruid_arg != -1 && ruid != ruid_arg)) {
6739 PyErr_SetString(PyExc_OverflowError, "user id too big");
6740 return NULL;
6741 }
6742 if (setreuid(ruid, euid) < 0) {
6743 return posix_error();
6744 } else {
6745 Py_INCREF(Py_None);
6746 return Py_None;
6747 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006748}
6749#endif /* HAVE_SETREUID */
6750
6751#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006753"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754Set the current process's real and effective group ids.");
6755
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006756static PyObject *
6757posix_setregid (PyObject *self, PyObject *args)
6758{
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 long rgid_arg, egid_arg;
6760 gid_t rgid, egid;
6761 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6762 return NULL;
6763 if (rgid_arg == -1)
6764 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6765 else
6766 rgid = rgid_arg; /* otherwise, assign from our long */
6767 if (egid_arg == -1)
6768 egid = (gid_t)-1;
6769 else
6770 egid = egid_arg;
6771 if ((egid_arg != -1 && egid != egid_arg) ||
6772 (rgid_arg != -1 && rgid != rgid_arg)) {
6773 PyErr_SetString(PyExc_OverflowError, "group id too big");
6774 return NULL;
6775 }
6776 if (setregid(rgid, egid) < 0) {
6777 return posix_error();
6778 } else {
6779 Py_INCREF(Py_None);
6780 return Py_None;
6781 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006782}
6783#endif /* HAVE_SETREGID */
6784
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006787"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006789
Barry Warsaw53699e91996-12-10 23:23:01 +00006790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006791posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006792{
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 long gid_arg;
6794 gid_t gid;
6795 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6796 return NULL;
6797 gid = gid_arg;
6798 if (gid != gid_arg) {
6799 PyErr_SetString(PyExc_OverflowError, "group id too big");
6800 return NULL;
6801 }
6802 if (setgid(gid) < 0)
6803 return posix_error();
6804 Py_INCREF(Py_None);
6805 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006806}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006807#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006808
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006809#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006813
6814static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006815posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 int i, len;
6818 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (!PySequence_Check(groups)) {
6821 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6822 return NULL;
6823 }
6824 len = PySequence_Size(groups);
6825 if (len > MAX_GROUPS) {
6826 PyErr_SetString(PyExc_ValueError, "too many groups");
6827 return NULL;
6828 }
6829 for(i = 0; i < len; i++) {
6830 PyObject *elem;
6831 elem = PySequence_GetItem(groups, i);
6832 if (!elem)
6833 return NULL;
6834 if (!PyLong_Check(elem)) {
6835 PyErr_SetString(PyExc_TypeError,
6836 "groups must be integers");
6837 Py_DECREF(elem);
6838 return NULL;
6839 } else {
6840 unsigned long x = PyLong_AsUnsignedLong(elem);
6841 if (PyErr_Occurred()) {
6842 PyErr_SetString(PyExc_TypeError,
6843 "group id too big");
6844 Py_DECREF(elem);
6845 return NULL;
6846 }
6847 grouplist[i] = x;
6848 /* read back the value to see if it fitted in gid_t */
6849 if (grouplist[i] != x) {
6850 PyErr_SetString(PyExc_TypeError,
6851 "group id too big");
6852 Py_DECREF(elem);
6853 return NULL;
6854 }
6855 }
6856 Py_DECREF(elem);
6857 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006858
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 if (setgroups(len, grouplist) < 0)
6860 return posix_error();
6861 Py_INCREF(Py_None);
6862 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006863}
6864#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006865
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6867static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006868wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869{
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 PyObject *result;
6871 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006872 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 if (pid == -1)
6875 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 if (struct_rusage == NULL) {
6878 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6879 if (m == NULL)
6880 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006881 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 Py_DECREF(m);
6883 if (struct_rusage == NULL)
6884 return NULL;
6885 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6888 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6889 if (!result)
6890 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891
6892#ifndef doubletime
6893#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6894#endif
6895
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006897 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006899 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6902 SET_INT(result, 2, ru->ru_maxrss);
6903 SET_INT(result, 3, ru->ru_ixrss);
6904 SET_INT(result, 4, ru->ru_idrss);
6905 SET_INT(result, 5, ru->ru_isrss);
6906 SET_INT(result, 6, ru->ru_minflt);
6907 SET_INT(result, 7, ru->ru_majflt);
6908 SET_INT(result, 8, ru->ru_nswap);
6909 SET_INT(result, 9, ru->ru_inblock);
6910 SET_INT(result, 10, ru->ru_oublock);
6911 SET_INT(result, 11, ru->ru_msgsnd);
6912 SET_INT(result, 12, ru->ru_msgrcv);
6913 SET_INT(result, 13, ru->ru_nsignals);
6914 SET_INT(result, 14, ru->ru_nvcsw);
6915 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916#undef SET_INT
6917
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 if (PyErr_Occurred()) {
6919 Py_DECREF(result);
6920 return NULL;
6921 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924}
6925#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6926
6927#ifdef HAVE_WAIT3
6928PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006929"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006930Wait for completion of a child process.");
6931
6932static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006933posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934{
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 pid_t pid;
6936 int options;
6937 struct rusage ru;
6938 WAIT_TYPE status;
6939 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940
Victor Stinner4195b5c2012-02-08 23:03:19 +01006941 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 Py_BEGIN_ALLOW_THREADS
6945 pid = wait3(&status, options, &ru);
6946 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947
Victor Stinner4195b5c2012-02-08 23:03:19 +01006948 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949}
6950#endif /* HAVE_WAIT3 */
6951
6952#ifdef HAVE_WAIT4
6953PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006954"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006955Wait for completion of a given child process.");
6956
6957static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006958posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959{
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 pid_t pid;
6961 int options;
6962 struct rusage ru;
6963 WAIT_TYPE status;
6964 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965
Victor Stinner4195b5c2012-02-08 23:03:19 +01006966 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006968
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 Py_BEGIN_ALLOW_THREADS
6970 pid = wait4(pid, &status, options, &ru);
6971 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner4195b5c2012-02-08 23:03:19 +01006973 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006974}
6975#endif /* HAVE_WAIT4 */
6976
Ross Lagerwall7807c352011-03-17 20:20:30 +02006977#if defined(HAVE_WAITID) && !defined(__APPLE__)
6978PyDoc_STRVAR(posix_waitid__doc__,
6979"waitid(idtype, id, options) -> waitid_result\n\n\
6980Wait for the completion of one or more child processes.\n\n\
6981idtype can be P_PID, P_PGID or P_ALL.\n\
6982id specifies the pid to wait on.\n\
6983options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6984or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6985Returns either waitid_result or None if WNOHANG is specified and there are\n\
6986no children in a waitable state.");
6987
6988static PyObject *
6989posix_waitid(PyObject *self, PyObject *args)
6990{
6991 PyObject *result;
6992 idtype_t idtype;
6993 id_t id;
6994 int options, res;
6995 siginfo_t si;
6996 si.si_pid = 0;
6997 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6998 return NULL;
6999 Py_BEGIN_ALLOW_THREADS
7000 res = waitid(idtype, id, &si, options);
7001 Py_END_ALLOW_THREADS
7002 if (res == -1)
7003 return posix_error();
7004
7005 if (si.si_pid == 0)
7006 Py_RETURN_NONE;
7007
7008 result = PyStructSequence_New(&WaitidResultType);
7009 if (!result)
7010 return NULL;
7011
7012 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
7013 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
7014 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7015 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7016 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7017 if (PyErr_Occurred()) {
7018 Py_DECREF(result);
7019 return NULL;
7020 }
7021
7022 return result;
7023}
7024#endif
7025
Guido van Rossumb6775db1994-08-01 11:34:53 +00007026#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007027PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007028"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Barry Warsaw53699e91996-12-10 23:23:01 +00007031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007032posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007033{
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 pid_t pid;
7035 int options;
7036 WAIT_TYPE status;
7037 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007038
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7040 return NULL;
7041 Py_BEGIN_ALLOW_THREADS
7042 pid = waitpid(pid, &status, options);
7043 Py_END_ALLOW_THREADS
7044 if (pid == -1)
7045 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007046
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007048}
7049
Tim Petersab034fa2002-02-01 11:27:43 +00007050#elif defined(HAVE_CWAIT)
7051
7052/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007053PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007054"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007056
7057static PyObject *
7058posix_waitpid(PyObject *self, PyObject *args)
7059{
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 Py_intptr_t pid;
7061 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007062
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7064 return NULL;
7065 Py_BEGIN_ALLOW_THREADS
7066 pid = _cwait(&status, pid, options);
7067 Py_END_ALLOW_THREADS
7068 if (pid == -1)
7069 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007070
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 /* shift the status left a byte so this is more like the POSIX waitpid */
7072 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007073}
7074#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Guido van Rossumad0ee831995-03-01 10:34:45 +00007076#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007079Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007080
Barry Warsaw53699e91996-12-10 23:23:01 +00007081static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007082posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007083{
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 pid_t pid;
7085 WAIT_TYPE status;
7086 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007087
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 Py_BEGIN_ALLOW_THREADS
7089 pid = wait(&status);
7090 Py_END_ALLOW_THREADS
7091 if (pid == -1)
7092 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007095}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007096#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7100PyDoc_STRVAR(readlink__doc__,
7101"readlink(path, *, dir_fd=None) -> path\n\n\
7102Return a string representing the path to which the symbolic link points.\n\
7103\n\
7104If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7105 and path should be relative; path will then be relative to that directory.\n\
7106dir_fd may not be implemented on your platform.\n\
7107 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007108#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007109
Guido van Rossumb6775db1994-08-01 11:34:53 +00007110#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007111
Barry Warsaw53699e91996-12-10 23:23:01 +00007112static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007114{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115 path_t path;
7116 int dir_fd = DEFAULT_DIR_FD;
7117 char buffer[MAXPATHLEN];
7118 ssize_t length;
7119 PyObject *return_value = NULL;
7120 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007121
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 memset(&path, 0, sizeof(path));
7123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7124 path_converter, &path,
7125#ifdef HAVE_READLINKAT
7126 dir_fd_converter, &dir_fd
7127#else
7128 dir_fd_unavailable, &dir_fd
7129#endif
7130 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007132
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134#ifdef HAVE_READLINKAT
7135 if (dir_fd != DEFAULT_DIR_FD)
7136 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007137 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138#endif
7139 length = readlink(path.narrow, buffer, sizeof(buffer));
7140 Py_END_ALLOW_THREADS
7141
7142 if (length < 0) {
7143 return_value = path_posix_error("readlink", &path);
7144 goto exit;
7145 }
7146
7147 if (PyUnicode_Check(path.object))
7148 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7149 else
7150 return_value = PyBytes_FromStringAndSize(buffer, length);
7151exit:
7152 path_cleanup(&path);
7153 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007154}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155
7156
Guido van Rossumb6775db1994-08-01 11:34:53 +00007157#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007159
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007161PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007162"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7163Create a symbolic link pointing to src named dst.\n\n\
7164target_is_directory is required on Windows if the target is to be\n\
7165 interpreted as a directory. (On Windows, symlink requires\n\
7166 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7167 target_is_directory is ignored on non-Windows platforms.\n\
7168\n\
7169If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7170 and path should be relative; path will then be relative to that directory.\n\
7171dir_fd may not be implemented on your platform.\n\
7172 If it is unavailable, using it will raise a NotImplementedError.");
7173
7174#if defined(MS_WINDOWS)
7175
7176/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7177static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7178static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7179static int
7180check_CreateSymbolicLink()
7181{
7182 HINSTANCE hKernel32;
7183 /* only recheck */
7184 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7185 return 1;
7186 hKernel32 = GetModuleHandleW(L"KERNEL32");
7187 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7188 "CreateSymbolicLinkW");
7189 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7190 "CreateSymbolicLinkA");
7191 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7192}
7193
7194#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007195
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007196static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007198{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007199 path_t src;
7200 path_t dst;
7201 int dir_fd = DEFAULT_DIR_FD;
7202 int target_is_directory = 0;
7203 static char *keywords[] = {"src", "dst", "target_is_directory",
7204 "dir_fd", NULL};
7205 PyObject *return_value;
7206#ifdef MS_WINDOWS
7207 DWORD result;
7208#else
7209 int result;
7210#endif
7211
7212 memset(&src, 0, sizeof(src));
7213 src.argument_name = "src";
7214 memset(&dst, 0, sizeof(dst));
7215 dst.argument_name = "dst";
7216
7217#ifdef MS_WINDOWS
7218 if (!check_CreateSymbolicLink()) {
7219 PyErr_SetString(PyExc_NotImplementedError,
7220 "CreateSymbolicLink functions not found");
7221 return NULL;
7222 }
7223 if (!win32_can_symlink) {
7224 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7225 return NULL;
7226 }
7227#endif
7228
7229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7230 keywords,
7231 path_converter, &src,
7232 path_converter, &dst,
7233 &target_is_directory,
7234#ifdef HAVE_SYMLINKAT
7235 dir_fd_converter, &dir_fd
7236#else
7237 dir_fd_unavailable, &dir_fd
7238#endif
7239 ))
7240 return NULL;
7241
7242 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7243 PyErr_SetString(PyExc_ValueError,
7244 "symlink: src and dst must be the same type");
7245 return_value = NULL;
7246 goto exit;
7247 }
7248
7249#ifdef MS_WINDOWS
7250 Py_BEGIN_ALLOW_THREADS
7251 if (dst.wide)
7252 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7253 target_is_directory);
7254 else
7255 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7256 target_is_directory);
7257 Py_END_ALLOW_THREADS
7258
7259 if (!result) {
7260 return_value = win32_error_object("symlink", src.object);
7261 goto exit;
7262 }
7263
7264#else
7265
7266 Py_BEGIN_ALLOW_THREADS
7267#if HAVE_SYMLINKAT
7268 if (dir_fd != DEFAULT_DIR_FD)
7269 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7270 else
7271#endif
7272 result = symlink(src.narrow, dst.narrow);
7273 Py_END_ALLOW_THREADS
7274
7275 if (result) {
7276 return_value = path_error("symlink", &dst);
7277 goto exit;
7278 }
7279#endif
7280
7281 return_value = Py_None;
7282 Py_INCREF(Py_None);
7283 goto exit; /* silence "unused label" warning */
7284exit:
7285 path_cleanup(&src);
7286 path_cleanup(&dst);
7287 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007288}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007289
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007290#endif /* HAVE_SYMLINK */
7291
Larry Hastings9cf065c2012-06-22 16:30:09 -07007292
Brian Curtind40e6f72010-07-08 21:39:08 +00007293#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7294
Brian Curtind40e6f72010-07-08 21:39:08 +00007295static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007296win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007297{
7298 wchar_t *path;
7299 DWORD n_bytes_returned;
7300 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007301 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007302 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007303 HANDLE reparse_point_handle;
7304
7305 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7306 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7307 wchar_t *print_name;
7308
Larry Hastings9cf065c2012-06-22 16:30:09 -07007309 static char *keywords[] = {"path", "dir_fd", NULL};
7310
7311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7312 &po,
7313 dir_fd_unavailable, &dir_fd
7314 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007315 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007316
Victor Stinnereb5657a2011-09-30 01:44:27 +02007317 path = PyUnicode_AsUnicode(po);
7318 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007319 return NULL;
7320
7321 /* First get a handle to the reparse point */
7322 Py_BEGIN_ALLOW_THREADS
7323 reparse_point_handle = CreateFileW(
7324 path,
7325 0,
7326 0,
7327 0,
7328 OPEN_EXISTING,
7329 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7330 0);
7331 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007332
Brian Curtind40e6f72010-07-08 21:39:08 +00007333 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007334 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007335
Brian Curtind40e6f72010-07-08 21:39:08 +00007336 Py_BEGIN_ALLOW_THREADS
7337 /* New call DeviceIoControl to read the reparse point */
7338 io_result = DeviceIoControl(
7339 reparse_point_handle,
7340 FSCTL_GET_REPARSE_POINT,
7341 0, 0, /* in buffer */
7342 target_buffer, sizeof(target_buffer),
7343 &n_bytes_returned,
7344 0 /* we're not using OVERLAPPED_IO */
7345 );
7346 CloseHandle(reparse_point_handle);
7347 Py_END_ALLOW_THREADS
7348
7349 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007350 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007351
7352 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7353 {
7354 PyErr_SetString(PyExc_ValueError,
7355 "not a symbolic link");
7356 return NULL;
7357 }
Brian Curtin74e45612010-07-09 15:58:59 +00007358 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7359 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7360
7361 result = PyUnicode_FromWideChar(print_name,
7362 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007363 return result;
7364}
7365
7366#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7367
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007368
7369#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007370#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7371static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007372system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007373{
7374 ULONG value = 0;
7375
7376 Py_BEGIN_ALLOW_THREADS
7377 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7378 Py_END_ALLOW_THREADS
7379
7380 return value;
7381}
7382
7383static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007384posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007385{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007386 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 return Py_BuildValue("ddddd",
7388 (double)0 /* t.tms_utime / HZ */,
7389 (double)0 /* t.tms_stime / HZ */,
7390 (double)0 /* t.tms_cutime / HZ */,
7391 (double)0 /* t.tms_cstime / HZ */,
7392 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007393}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007394#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007395#define NEED_TICKS_PER_SECOND
7396static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007398posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007399{
Victor Stinner8c62be82010-05-06 00:08:46 +00007400 struct tms t;
7401 clock_t c;
7402 errno = 0;
7403 c = times(&t);
7404 if (c == (clock_t) -1)
7405 return posix_error();
7406 return Py_BuildValue("ddddd",
7407 (double)t.tms_utime / ticks_per_second,
7408 (double)t.tms_stime / ticks_per_second,
7409 (double)t.tms_cutime / ticks_per_second,
7410 (double)t.tms_cstime / ticks_per_second,
7411 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007412}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007413#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007414#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007415
7416
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007418#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00007419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007420posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 FILETIME create, exit, kernel, user;
7423 HANDLE hProc;
7424 hProc = GetCurrentProcess();
7425 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7426 /* The fields of a FILETIME structure are the hi and lo part
7427 of a 64-bit value expressed in 100 nanosecond units.
7428 1e7 is one second in such units; 1e-7 the inverse.
7429 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7430 */
7431 return Py_BuildValue(
7432 "ddddd",
7433 (double)(user.dwHighDateTime*429.4967296 +
7434 user.dwLowDateTime*1e-7),
7435 (double)(kernel.dwHighDateTime*429.4967296 +
7436 kernel.dwLowDateTime*1e-7),
7437 (double)0,
7438 (double)0,
7439 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007440}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007441#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442
7443#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007444PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007445"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007446Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007447#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007448
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007449
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007450#ifdef HAVE_GETSID
7451PyDoc_STRVAR(posix_getsid__doc__,
7452"getsid(pid) -> sid\n\n\
7453Call the system call getsid().");
7454
7455static PyObject *
7456posix_getsid(PyObject *self, PyObject *args)
7457{
Victor Stinner8c62be82010-05-06 00:08:46 +00007458 pid_t pid;
7459 int sid;
7460 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7461 return NULL;
7462 sid = getsid(pid);
7463 if (sid < 0)
7464 return posix_error();
7465 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007466}
7467#endif /* HAVE_GETSID */
7468
7469
Guido van Rossumb6775db1994-08-01 11:34:53 +00007470#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007471PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007472"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007473Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007474
Barry Warsaw53699e91996-12-10 23:23:01 +00007475static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007476posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007477{
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 if (setsid() < 0)
7479 return posix_error();
7480 Py_INCREF(Py_None);
7481 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007482}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007483#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007484
Guido van Rossumb6775db1994-08-01 11:34:53 +00007485#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007486PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007487"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007488Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007489
Barry Warsaw53699e91996-12-10 23:23:01 +00007490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007491posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007492{
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 pid_t pid;
7494 int pgrp;
7495 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7496 return NULL;
7497 if (setpgid(pid, pgrp) < 0)
7498 return posix_error();
7499 Py_INCREF(Py_None);
7500 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007501}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007502#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007504
Guido van Rossumb6775db1994-08-01 11:34:53 +00007505#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007506PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007507"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007508Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007509
Barry Warsaw53699e91996-12-10 23:23:01 +00007510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007511posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007512{
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 int fd;
7514 pid_t pgid;
7515 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7516 return NULL;
7517 pgid = tcgetpgrp(fd);
7518 if (pgid < 0)
7519 return posix_error();
7520 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007521}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007522#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007524
Guido van Rossumb6775db1994-08-01 11:34:53 +00007525#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007526PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007527"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007528Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007529
Barry Warsaw53699e91996-12-10 23:23:01 +00007530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007531posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007532{
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 int fd;
7534 pid_t pgid;
7535 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7536 return NULL;
7537 if (tcsetpgrp(fd, pgid) < 0)
7538 return posix_error();
7539 Py_INCREF(Py_None);
7540 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007541}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007542#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007543
Guido van Rossum687dd131993-05-17 08:34:16 +00007544/* Functions acting on file descriptors */
7545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007546PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007547"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7548Open a file for low level IO. Returns a file handle (integer).\n\
7549\n\
7550If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7551 and path should be relative; path will then be relative to that directory.\n\
7552dir_fd may not be implemented on your platform.\n\
7553 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007554
Barry Warsaw53699e91996-12-10 23:23:01 +00007555static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007556posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007557{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007558 path_t path;
7559 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007561 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007563 PyObject *return_value = NULL;
7564 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007565
Larry Hastings9cf065c2012-06-22 16:30:09 -07007566 memset(&path, 0, sizeof(path));
7567 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7568 path_converter, &path,
7569 &flags, &mode,
7570#ifdef HAVE_OPENAT
7571 dir_fd_converter, &dir_fd
7572#else
7573 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007575 ))
7576 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007577
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007579#ifdef MS_WINDOWS
7580 if (path.wide)
7581 fd = _wopen(path.wide, flags, mode);
7582 else
7583#endif
7584#ifdef HAVE_OPENAT
7585 if (dir_fd != DEFAULT_DIR_FD)
7586 fd = openat(dir_fd, path.narrow, flags, mode);
7587 else
7588#endif
7589 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007591
Larry Hastings9cf065c2012-06-22 16:30:09 -07007592 if (fd == -1) {
7593#ifdef MS_WINDOWS
7594 /* force use of posix_error here for exact backwards compatibility */
7595 if (path.wide)
7596 return_value = posix_error();
7597 else
7598#endif
7599 return_value = path_error("open", &path);
7600 goto exit;
7601 }
7602
7603 return_value = PyLong_FromLong((long)fd);
7604
7605exit:
7606 path_cleanup(&path);
7607 return return_value;
7608}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007610PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007611"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007613
Barry Warsaw53699e91996-12-10 23:23:01 +00007614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007615posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007616{
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 int fd, res;
7618 if (!PyArg_ParseTuple(args, "i:close", &fd))
7619 return NULL;
7620 if (!_PyVerify_fd(fd))
7621 return posix_error();
7622 Py_BEGIN_ALLOW_THREADS
7623 res = close(fd);
7624 Py_END_ALLOW_THREADS
7625 if (res < 0)
7626 return posix_error();
7627 Py_INCREF(Py_None);
7628 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007629}
7630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Victor Stinner8c62be82010-05-06 00:08:46 +00007632PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007633"closerange(fd_low, fd_high)\n\n\
7634Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7635
7636static PyObject *
7637posix_closerange(PyObject *self, PyObject *args)
7638{
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 int fd_from, fd_to, i;
7640 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7641 return NULL;
7642 Py_BEGIN_ALLOW_THREADS
7643 for (i = fd_from; i < fd_to; i++)
7644 if (_PyVerify_fd(i))
7645 close(i);
7646 Py_END_ALLOW_THREADS
7647 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007648}
7649
7650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007651PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007652"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007653Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Barry Warsaw53699e91996-12-10 23:23:01 +00007655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007656posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007657{
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 int fd;
7659 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7660 return NULL;
7661 if (!_PyVerify_fd(fd))
7662 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 if (fd < 0)
7665 return posix_error();
7666 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007667}
7668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007670PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007671"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007672Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007673
Barry Warsaw53699e91996-12-10 23:23:01 +00007674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007675posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007676{
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 int fd, fd2, res;
7678 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7679 return NULL;
7680 if (!_PyVerify_fd_dup2(fd, fd2))
7681 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 if (res < 0)
7684 return posix_error();
7685 Py_INCREF(Py_None);
7686 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007687}
7688
Ross Lagerwall7807c352011-03-17 20:20:30 +02007689#ifdef HAVE_LOCKF
7690PyDoc_STRVAR(posix_lockf__doc__,
7691"lockf(fd, cmd, len)\n\n\
7692Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7693fd is an open file descriptor.\n\
7694cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7695F_TEST.\n\
7696len specifies the section of the file to lock.");
7697
7698static PyObject *
7699posix_lockf(PyObject *self, PyObject *args)
7700{
7701 int fd, cmd, res;
7702 off_t len;
7703 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7704 &fd, &cmd, _parse_off_t, &len))
7705 return NULL;
7706
7707 Py_BEGIN_ALLOW_THREADS
7708 res = lockf(fd, cmd, len);
7709 Py_END_ALLOW_THREADS
7710
7711 if (res < 0)
7712 return posix_error();
7713
7714 Py_RETURN_NONE;
7715}
7716#endif
7717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007719PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007720"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007721Set the current position of a file descriptor.\n\
7722Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007723
Barry Warsaw53699e91996-12-10 23:23:01 +00007724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007725posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007726{
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007728#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007730#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007732#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007733 PyObject *posobj;
7734 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007736#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7738 switch (how) {
7739 case 0: how = SEEK_SET; break;
7740 case 1: how = SEEK_CUR; break;
7741 case 2: how = SEEK_END; break;
7742 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007743#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007744
Ross Lagerwall8e749672011-03-17 21:54:07 +02007745#if !defined(HAVE_LARGEFILE_SUPPORT)
7746 pos = PyLong_AsLong(posobj);
7747#else
7748 pos = PyLong_AsLongLong(posobj);
7749#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 if (PyErr_Occurred())
7751 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007752
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 if (!_PyVerify_fd(fd))
7754 return posix_error();
7755 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007756#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007758#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007760#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 Py_END_ALLOW_THREADS
7762 if (res < 0)
7763 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007764
7765#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007769#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007770}
7771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007773PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007774"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007775Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007776
Barry Warsaw53699e91996-12-10 23:23:01 +00007777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007778posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007779{
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 int fd, size;
7781 Py_ssize_t n;
7782 PyObject *buffer;
7783 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7784 return NULL;
7785 if (size < 0) {
7786 errno = EINVAL;
7787 return posix_error();
7788 }
7789 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7790 if (buffer == NULL)
7791 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007792 if (!_PyVerify_fd(fd)) {
7793 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007795 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 Py_BEGIN_ALLOW_THREADS
7797 n = read(fd, PyBytes_AS_STRING(buffer), size);
7798 Py_END_ALLOW_THREADS
7799 if (n < 0) {
7800 Py_DECREF(buffer);
7801 return posix_error();
7802 }
7803 if (n != size)
7804 _PyBytes_Resize(&buffer, n);
7805 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007806}
7807
Ross Lagerwall7807c352011-03-17 20:20:30 +02007808#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7809 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007810static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007811iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7812{
7813 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007814 Py_ssize_t blen, total = 0;
7815
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007816 *iov = PyMem_New(struct iovec, cnt);
7817 if (*iov == NULL) {
7818 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007819 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007820 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007821
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007822 *buf = PyMem_New(Py_buffer, cnt);
7823 if (*buf == NULL) {
7824 PyMem_Del(*iov);
7825 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007826 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007827 }
7828
7829 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007830 PyObject *item = PySequence_GetItem(seq, i);
7831 if (item == NULL)
7832 goto fail;
7833 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7834 Py_DECREF(item);
7835 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007836 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007837 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007838 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007839 blen = (*buf)[i].len;
7840 (*iov)[i].iov_len = blen;
7841 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007842 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007843 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007844
7845fail:
7846 PyMem_Del(*iov);
7847 for (j = 0; j < i; j++) {
7848 PyBuffer_Release(&(*buf)[j]);
7849 }
7850 PyMem_Del(*buf);
7851 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007852}
7853
7854static void
7855iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7856{
7857 int i;
7858 PyMem_Del(iov);
7859 for (i = 0; i < cnt; i++) {
7860 PyBuffer_Release(&buf[i]);
7861 }
7862 PyMem_Del(buf);
7863}
7864#endif
7865
Ross Lagerwall7807c352011-03-17 20:20:30 +02007866#ifdef HAVE_READV
7867PyDoc_STRVAR(posix_readv__doc__,
7868"readv(fd, buffers) -> bytesread\n\n\
7869Read from a file descriptor into a number of writable buffers. buffers\n\
7870is an arbitrary sequence of writable buffers.\n\
7871Returns the total number of bytes read.");
7872
7873static PyObject *
7874posix_readv(PyObject *self, PyObject *args)
7875{
7876 int fd, cnt;
7877 Py_ssize_t n;
7878 PyObject *seq;
7879 struct iovec *iov;
7880 Py_buffer *buf;
7881
7882 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7883 return NULL;
7884 if (!PySequence_Check(seq)) {
7885 PyErr_SetString(PyExc_TypeError,
7886 "readv() arg 2 must be a sequence");
7887 return NULL;
7888 }
7889 cnt = PySequence_Size(seq);
7890
7891 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7892 return NULL;
7893
7894 Py_BEGIN_ALLOW_THREADS
7895 n = readv(fd, iov, cnt);
7896 Py_END_ALLOW_THREADS
7897
7898 iov_cleanup(iov, buf, cnt);
7899 return PyLong_FromSsize_t(n);
7900}
7901#endif
7902
7903#ifdef HAVE_PREAD
7904PyDoc_STRVAR(posix_pread__doc__,
7905"pread(fd, buffersize, offset) -> string\n\n\
7906Read from a file descriptor, fd, at a position of offset. It will read up\n\
7907to buffersize number of bytes. The file offset remains unchanged.");
7908
7909static PyObject *
7910posix_pread(PyObject *self, PyObject *args)
7911{
7912 int fd, size;
7913 off_t offset;
7914 Py_ssize_t n;
7915 PyObject *buffer;
7916 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7917 return NULL;
7918
7919 if (size < 0) {
7920 errno = EINVAL;
7921 return posix_error();
7922 }
7923 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7924 if (buffer == NULL)
7925 return NULL;
7926 if (!_PyVerify_fd(fd)) {
7927 Py_DECREF(buffer);
7928 return posix_error();
7929 }
7930 Py_BEGIN_ALLOW_THREADS
7931 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7932 Py_END_ALLOW_THREADS
7933 if (n < 0) {
7934 Py_DECREF(buffer);
7935 return posix_error();
7936 }
7937 if (n != size)
7938 _PyBytes_Resize(&buffer, n);
7939 return buffer;
7940}
7941#endif
7942
7943PyDoc_STRVAR(posix_write__doc__,
7944"write(fd, string) -> byteswritten\n\n\
7945Write a string to a file descriptor.");
7946
7947static PyObject *
7948posix_write(PyObject *self, PyObject *args)
7949{
7950 Py_buffer pbuf;
7951 int fd;
7952 Py_ssize_t size, len;
7953
7954 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7955 return NULL;
7956 if (!_PyVerify_fd(fd)) {
7957 PyBuffer_Release(&pbuf);
7958 return posix_error();
7959 }
7960 len = pbuf.len;
7961 Py_BEGIN_ALLOW_THREADS
7962#if defined(MS_WIN64) || defined(MS_WINDOWS)
7963 if (len > INT_MAX)
7964 len = INT_MAX;
7965 size = write(fd, pbuf.buf, (int)len);
7966#else
7967 size = write(fd, pbuf.buf, len);
7968#endif
7969 Py_END_ALLOW_THREADS
7970 PyBuffer_Release(&pbuf);
7971 if (size < 0)
7972 return posix_error();
7973 return PyLong_FromSsize_t(size);
7974}
7975
7976#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007977PyDoc_STRVAR(posix_sendfile__doc__,
7978"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7979sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7980 -> byteswritten\n\
7981Copy nbytes bytes from file descriptor in to file descriptor out.");
7982
7983static PyObject *
7984posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7985{
7986 int in, out;
7987 Py_ssize_t ret;
7988 off_t offset;
7989
7990#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7991#ifndef __APPLE__
7992 Py_ssize_t len;
7993#endif
7994 PyObject *headers = NULL, *trailers = NULL;
7995 Py_buffer *hbuf, *tbuf;
7996 off_t sbytes;
7997 struct sf_hdtr sf;
7998 int flags = 0;
7999 sf.headers = NULL;
8000 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008001 static char *keywords[] = {"out", "in",
8002 "offset", "count",
8003 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008004
8005#ifdef __APPLE__
8006 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008007 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008008#else
8009 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008010 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008011#endif
8012 &headers, &trailers, &flags))
8013 return NULL;
8014 if (headers != NULL) {
8015 if (!PySequence_Check(headers)) {
8016 PyErr_SetString(PyExc_TypeError,
8017 "sendfile() headers must be a sequence or None");
8018 return NULL;
8019 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008020 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008022 if (sf.hdr_cnt > 0 &&
8023 !(i = iov_setup(&(sf.headers), &hbuf,
8024 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008026#ifdef __APPLE__
8027 sbytes += i;
8028#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029 }
8030 }
8031 if (trailers != NULL) {
8032 if (!PySequence_Check(trailers)) {
8033 PyErr_SetString(PyExc_TypeError,
8034 "sendfile() trailers must be a sequence or None");
8035 return NULL;
8036 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008037 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008039 if (sf.trl_cnt > 0 &&
8040 !(i = iov_setup(&(sf.trailers), &tbuf,
8041 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008043#ifdef __APPLE__
8044 sbytes += i;
8045#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008046 }
8047 }
8048
8049 Py_BEGIN_ALLOW_THREADS
8050#ifdef __APPLE__
8051 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8052#else
8053 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8054#endif
8055 Py_END_ALLOW_THREADS
8056
8057 if (sf.headers != NULL)
8058 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8059 if (sf.trailers != NULL)
8060 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8061
8062 if (ret < 0) {
8063 if ((errno == EAGAIN) || (errno == EBUSY)) {
8064 if (sbytes != 0) {
8065 // some data has been sent
8066 goto done;
8067 }
8068 else {
8069 // no data has been sent; upper application is supposed
8070 // to retry on EAGAIN or EBUSY
8071 return posix_error();
8072 }
8073 }
8074 return posix_error();
8075 }
8076 goto done;
8077
8078done:
8079 #if !defined(HAVE_LARGEFILE_SUPPORT)
8080 return Py_BuildValue("l", sbytes);
8081 #else
8082 return Py_BuildValue("L", sbytes);
8083 #endif
8084
8085#else
8086 Py_ssize_t count;
8087 PyObject *offobj;
8088 static char *keywords[] = {"out", "in",
8089 "offset", "count", NULL};
8090 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8091 keywords, &out, &in, &offobj, &count))
8092 return NULL;
8093#ifdef linux
8094 if (offobj == Py_None) {
8095 Py_BEGIN_ALLOW_THREADS
8096 ret = sendfile(out, in, NULL, count);
8097 Py_END_ALLOW_THREADS
8098 if (ret < 0)
8099 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008100 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101 }
8102#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008103 if (!_parse_off_t(offobj, &offset))
8104 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105 Py_BEGIN_ALLOW_THREADS
8106 ret = sendfile(out, in, &offset, count);
8107 Py_END_ALLOW_THREADS
8108 if (ret < 0)
8109 return posix_error();
8110 return Py_BuildValue("n", ret);
8111#endif
8112}
8113#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008115PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008116"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008117Like stat(), but for an open file descriptor.\n\
8118Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008119
Barry Warsaw53699e91996-12-10 23:23:01 +00008120static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008121posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008122{
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 int fd;
8124 STRUCT_STAT st;
8125 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008126 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008128#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 /* on OpenVMS we must ensure that all bytes are written to the file */
8130 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 if (!_PyVerify_fd(fd))
8133 return posix_error();
8134 Py_BEGIN_ALLOW_THREADS
8135 res = FSTAT(fd, &st);
8136 Py_END_ALLOW_THREADS
8137 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008138#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008140#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008142#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 }
Tim Peters5aa91602002-01-30 05:46:57 +00008144
Victor Stinner4195b5c2012-02-08 23:03:19 +01008145 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008146}
8147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008148PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008149"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008150Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008151connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008152
8153static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008154posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008155{
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 int fd;
8157 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8158 return NULL;
8159 if (!_PyVerify_fd(fd))
8160 return PyBool_FromLong(0);
8161 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008162}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008163
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008164#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008165PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008166"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008167Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008168
Barry Warsaw53699e91996-12-10 23:23:01 +00008169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008170posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008171{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008172#if defined(PYOS_OS2)
8173 HFILE read, write;
8174 APIRET rc;
8175
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008176 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008177 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008178 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008179
8180 return Py_BuildValue("(ii)", read, write);
8181#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008182#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008183 int fds[2];
8184 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008186 if (res != 0)
8187 return posix_error();
8188 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008189#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 HANDLE read, write;
8191 int read_fd, write_fd;
8192 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 if (!ok)
8195 return win32_error("CreatePipe", NULL);
8196 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8197 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8198 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008199#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008200#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008201}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008202#endif /* HAVE_PIPE */
8203
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008204#ifdef HAVE_PIPE2
8205PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008206"pipe2(flags) -> (read_end, write_end)\n\n\
8207Create a pipe with flags set atomically.\n\
8208flags can be constructed by ORing together one or more of these values:\n\
8209O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008210");
8211
8212static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008213posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008214{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008215 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008216 int fds[2];
8217 int res;
8218
Charles-François Natali368f34b2011-06-06 19:49:47 +02008219 flags = PyLong_AsLong(arg);
8220 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008221 return NULL;
8222
8223 res = pipe2(fds, flags);
8224 if (res != 0)
8225 return posix_error();
8226 return Py_BuildValue("(ii)", fds[0], fds[1]);
8227}
8228#endif /* HAVE_PIPE2 */
8229
Ross Lagerwall7807c352011-03-17 20:20:30 +02008230#ifdef HAVE_WRITEV
8231PyDoc_STRVAR(posix_writev__doc__,
8232"writev(fd, buffers) -> byteswritten\n\n\
8233Write the contents of buffers to a file descriptor, where buffers is an\n\
8234arbitrary sequence of buffers.\n\
8235Returns the total bytes written.");
8236
8237static PyObject *
8238posix_writev(PyObject *self, PyObject *args)
8239{
8240 int fd, cnt;
8241 Py_ssize_t res;
8242 PyObject *seq;
8243 struct iovec *iov;
8244 Py_buffer *buf;
8245 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8246 return NULL;
8247 if (!PySequence_Check(seq)) {
8248 PyErr_SetString(PyExc_TypeError,
8249 "writev() arg 2 must be a sequence");
8250 return NULL;
8251 }
8252 cnt = PySequence_Size(seq);
8253
8254 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8255 return NULL;
8256 }
8257
8258 Py_BEGIN_ALLOW_THREADS
8259 res = writev(fd, iov, cnt);
8260 Py_END_ALLOW_THREADS
8261
8262 iov_cleanup(iov, buf, cnt);
8263 return PyLong_FromSsize_t(res);
8264}
8265#endif
8266
8267#ifdef HAVE_PWRITE
8268PyDoc_STRVAR(posix_pwrite__doc__,
8269"pwrite(fd, string, offset) -> byteswritten\n\n\
8270Write string to a file descriptor, fd, from offset, leaving the file\n\
8271offset unchanged.");
8272
8273static PyObject *
8274posix_pwrite(PyObject *self, PyObject *args)
8275{
8276 Py_buffer pbuf;
8277 int fd;
8278 off_t offset;
8279 Py_ssize_t size;
8280
8281 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8282 return NULL;
8283
8284 if (!_PyVerify_fd(fd)) {
8285 PyBuffer_Release(&pbuf);
8286 return posix_error();
8287 }
8288 Py_BEGIN_ALLOW_THREADS
8289 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8290 Py_END_ALLOW_THREADS
8291 PyBuffer_Release(&pbuf);
8292 if (size < 0)
8293 return posix_error();
8294 return PyLong_FromSsize_t(size);
8295}
8296#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008298#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008299PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008300"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8301Create a FIFO (a POSIX named pipe).\n\
8302\n\
8303If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8304 and path should be relative; path will then be relative to that directory.\n\
8305dir_fd may not be implemented on your platform.\n\
8306 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008307
Barry Warsaw53699e91996-12-10 23:23:01 +00008308static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008309posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008310{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008311 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008313 int dir_fd = DEFAULT_DIR_FD;
8314 int result;
8315 PyObject *return_value = NULL;
8316 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8317
8318 memset(&path, 0, sizeof(path));
8319 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8320 path_converter, &path,
8321 &mode,
8322#ifdef HAVE_MKFIFOAT
8323 dir_fd_converter, &dir_fd
8324#else
8325 dir_fd_unavailable, &dir_fd
8326#endif
8327 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008329
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008331#ifdef HAVE_MKFIFOAT
8332 if (dir_fd != DEFAULT_DIR_FD)
8333 result = mkfifoat(dir_fd, path.narrow, mode);
8334 else
8335#endif
8336 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008338
8339 if (result < 0) {
8340 return_value = posix_error();
8341 goto exit;
8342 }
8343
8344 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008346
8347exit:
8348 path_cleanup(&path);
8349 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008350}
8351#endif
8352
Neal Norwitz11690112002-07-30 01:08:28 +00008353#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008354PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008355"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008356Create a filesystem node (file, device special file or named pipe)\n\
8357named filename. mode specifies both the permissions to use and the\n\
8358type of node to be created, being combined (bitwise OR) with one of\n\
8359S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008360device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008361os.makedev()), otherwise it is ignored.\n\
8362\n\
8363If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8364 and path should be relative; path will then be relative to that directory.\n\
8365dir_fd may not be implemented on your platform.\n\
8366 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008367
8368
8369static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008370posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008371{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008372 path_t path;
8373 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008375 int dir_fd = DEFAULT_DIR_FD;
8376 int result;
8377 PyObject *return_value = NULL;
8378 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8379
8380 memset(&path, 0, sizeof(path));
8381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8382 path_converter, &path,
8383 &mode, &device,
8384#ifdef HAVE_MKNODAT
8385 dir_fd_converter, &dir_fd
8386#else
8387 dir_fd_unavailable, &dir_fd
8388#endif
8389 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008391
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008393#ifdef HAVE_MKNODAT
8394 if (dir_fd != DEFAULT_DIR_FD)
8395 result = mknodat(dir_fd, path.narrow, mode, device);
8396 else
8397#endif
8398 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008400
8401 if (result < 0) {
8402 return_value = posix_error();
8403 goto exit;
8404 }
8405
8406 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008408
8409exit:
8410 path_cleanup(&path);
8411 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008412}
8413#endif
8414
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008415#ifdef HAVE_DEVICE_MACROS
8416PyDoc_STRVAR(posix_major__doc__,
8417"major(device) -> major number\n\
8418Extracts a device major number from a raw device number.");
8419
8420static PyObject *
8421posix_major(PyObject *self, PyObject *args)
8422{
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 int device;
8424 if (!PyArg_ParseTuple(args, "i:major", &device))
8425 return NULL;
8426 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008427}
8428
8429PyDoc_STRVAR(posix_minor__doc__,
8430"minor(device) -> minor number\n\
8431Extracts a device minor number from a raw device number.");
8432
8433static PyObject *
8434posix_minor(PyObject *self, PyObject *args)
8435{
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 int device;
8437 if (!PyArg_ParseTuple(args, "i:minor", &device))
8438 return NULL;
8439 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008440}
8441
8442PyDoc_STRVAR(posix_makedev__doc__,
8443"makedev(major, minor) -> device number\n\
8444Composes a raw device number from the major and minor device numbers.");
8445
8446static PyObject *
8447posix_makedev(PyObject *self, PyObject *args)
8448{
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 int major, minor;
8450 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8451 return NULL;
8452 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008453}
8454#endif /* device macros */
8455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008456
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008457#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008458PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008459"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008460Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008461
Barry Warsaw53699e91996-12-10 23:23:01 +00008462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008463posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008464{
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 int fd;
8466 off_t length;
8467 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008468
Ross Lagerwall7807c352011-03-17 20:20:30 +02008469 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008471
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 Py_BEGIN_ALLOW_THREADS
8473 res = ftruncate(fd, length);
8474 Py_END_ALLOW_THREADS
8475 if (res < 0)
8476 return posix_error();
8477 Py_INCREF(Py_None);
8478 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008479}
8480#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008481
Ross Lagerwall7807c352011-03-17 20:20:30 +02008482#ifdef HAVE_TRUNCATE
8483PyDoc_STRVAR(posix_truncate__doc__,
8484"truncate(path, length)\n\n\
8485Truncate the file given by path to length bytes.");
8486
8487static PyObject *
8488posix_truncate(PyObject *self, PyObject *args)
8489{
8490 PyObject *opath;
8491 const char *path;
8492 off_t length;
8493 int res;
8494
8495 if (!PyArg_ParseTuple(args, "O&O&:truncate",
8496 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
8497 return NULL;
8498 path = PyBytes_AsString(opath);
8499
8500 Py_BEGIN_ALLOW_THREADS
8501 res = truncate(path, length);
8502 Py_END_ALLOW_THREADS
8503 Py_DECREF(opath);
8504 if (res < 0)
8505 return posix_error();
8506 Py_RETURN_NONE;
8507}
8508#endif
8509
8510#ifdef HAVE_POSIX_FALLOCATE
8511PyDoc_STRVAR(posix_posix_fallocate__doc__,
8512"posix_fallocate(fd, offset, len)\n\n\
8513Ensures that enough disk space is allocated for the file specified by fd\n\
8514starting from offset and continuing for len bytes.");
8515
8516static PyObject *
8517posix_posix_fallocate(PyObject *self, PyObject *args)
8518{
8519 off_t len, offset;
8520 int res, fd;
8521
8522 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8523 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8524 return NULL;
8525
8526 Py_BEGIN_ALLOW_THREADS
8527 res = posix_fallocate(fd, offset, len);
8528 Py_END_ALLOW_THREADS
8529 if (res != 0) {
8530 errno = res;
8531 return posix_error();
8532 }
8533 Py_RETURN_NONE;
8534}
8535#endif
8536
8537#ifdef HAVE_POSIX_FADVISE
8538PyDoc_STRVAR(posix_posix_fadvise__doc__,
8539"posix_fadvise(fd, offset, len, advice)\n\n\
8540Announces an intention to access data in a specific pattern thus allowing\n\
8541the kernel to make optimizations.\n\
8542The advice applies to the region of the file specified by fd starting at\n\
8543offset and continuing for len bytes.\n\
8544advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8545POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8546POSIX_FADV_DONTNEED.");
8547
8548static PyObject *
8549posix_posix_fadvise(PyObject *self, PyObject *args)
8550{
8551 off_t len, offset;
8552 int res, fd, advice;
8553
8554 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8555 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8556 return NULL;
8557
8558 Py_BEGIN_ALLOW_THREADS
8559 res = posix_fadvise(fd, offset, len, advice);
8560 Py_END_ALLOW_THREADS
8561 if (res != 0) {
8562 errno = res;
8563 return posix_error();
8564 }
8565 Py_RETURN_NONE;
8566}
8567#endif
8568
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008569#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008570PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008571"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008572Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008573
Fred Drake762e2061999-08-26 17:23:54 +00008574/* Save putenv() parameters as values here, so we can collect them when they
8575 * get re-set with another call for the same key. */
8576static PyObject *posix_putenv_garbage;
8577
Tim Peters5aa91602002-01-30 05:46:57 +00008578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008579posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008580{
Victor Stinner84ae1182010-05-06 22:05:07 +00008581 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008582#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008583 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008584 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008585
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008587 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008588 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008590
Victor Stinner65170952011-11-22 22:16:17 +01008591 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008592 if (newstr == NULL) {
8593 PyErr_NoMemory();
8594 goto error;
8595 }
Victor Stinner65170952011-11-22 22:16:17 +01008596 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8597 PyErr_Format(PyExc_ValueError,
8598 "the environment variable is longer than %u characters",
8599 _MAX_ENV);
8600 goto error;
8601 }
8602
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008604 if (newenv == NULL)
8605 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008606 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008608 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008609 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008610#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008611 PyObject *os1, *os2;
8612 char *s1, *s2;
8613 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008614
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008615 if (!PyArg_ParseTuple(args,
8616 "O&O&:putenv",
8617 PyUnicode_FSConverter, &os1,
8618 PyUnicode_FSConverter, &os2))
8619 return NULL;
8620 s1 = PyBytes_AsString(os1);
8621 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008622
Victor Stinner65170952011-11-22 22:16:17 +01008623 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008624 if (newstr == NULL) {
8625 PyErr_NoMemory();
8626 goto error;
8627 }
8628
Victor Stinner8c62be82010-05-06 00:08:46 +00008629 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008632 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008634#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008635
Victor Stinner8c62be82010-05-06 00:08:46 +00008636 /* Install the first arg and newstr in posix_putenv_garbage;
8637 * this will cause previous value to be collected. This has to
8638 * happen after the real putenv() call because the old value
8639 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008640 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 /* really not much we can do; just leak */
8642 PyErr_Clear();
8643 }
8644 else {
8645 Py_DECREF(newstr);
8646 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008647
Martin v. Löwis011e8422009-05-05 04:43:17 +00008648#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 Py_DECREF(os1);
8650 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008651#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008652 Py_RETURN_NONE;
8653
8654error:
8655#ifndef MS_WINDOWS
8656 Py_DECREF(os1);
8657 Py_DECREF(os2);
8658#endif
8659 Py_XDECREF(newstr);
8660 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008661}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008662#endif /* putenv */
8663
Guido van Rossumc524d952001-10-19 01:31:59 +00008664#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008665PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008666"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008667Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008668
8669static PyObject *
8670posix_unsetenv(PyObject *self, PyObject *args)
8671{
Victor Stinner65170952011-11-22 22:16:17 +01008672 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008673#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008674 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008675#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008676
8677 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008678
Victor Stinner65170952011-11-22 22:16:17 +01008679 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008680 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008681
Victor Stinner984890f2011-11-24 13:53:38 +01008682#ifdef HAVE_BROKEN_UNSETENV
8683 unsetenv(PyBytes_AS_STRING(name));
8684#else
Victor Stinner65170952011-11-22 22:16:17 +01008685 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008686 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008687 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008688 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008689 }
Victor Stinner984890f2011-11-24 13:53:38 +01008690#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008691
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 /* Remove the key from posix_putenv_garbage;
8693 * this will cause it to be collected. This has to
8694 * happen after the real unsetenv() call because the
8695 * old value was still accessible until then.
8696 */
Victor Stinner65170952011-11-22 22:16:17 +01008697 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 /* really not much we can do; just leak */
8699 PyErr_Clear();
8700 }
Victor Stinner65170952011-11-22 22:16:17 +01008701 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008702 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008703}
8704#endif /* unsetenv */
8705
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008706PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008707"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008708Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008709
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008711posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008712{
Victor Stinner8c62be82010-05-06 00:08:46 +00008713 int code;
8714 char *message;
8715 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8716 return NULL;
8717 message = strerror(code);
8718 if (message == NULL) {
8719 PyErr_SetString(PyExc_ValueError,
8720 "strerror() argument out of range");
8721 return NULL;
8722 }
Victor Stinner1b579672011-12-17 05:47:23 +01008723 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008724}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008725
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008726
Guido van Rossumc9641791998-08-04 15:26:23 +00008727#ifdef HAVE_SYS_WAIT_H
8728
Fred Drake106c1a02002-04-23 15:58:02 +00008729#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008730PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008731"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008732Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008733
8734static PyObject *
8735posix_WCOREDUMP(PyObject *self, PyObject *args)
8736{
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 WAIT_TYPE status;
8738 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008739
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8741 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008742
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008744}
8745#endif /* WCOREDUMP */
8746
8747#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008748PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008749"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008750Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008751job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008752
8753static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008754posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008755{
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 WAIT_TYPE status;
8757 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008758
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8760 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008761
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008763}
8764#endif /* WIFCONTINUED */
8765
Guido van Rossumc9641791998-08-04 15:26:23 +00008766#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008767PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008768"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008769Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008770
8771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008772posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008773{
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 WAIT_TYPE status;
8775 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008776
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8778 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008779
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008781}
8782#endif /* WIFSTOPPED */
8783
8784#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008785PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008786"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008787Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008788
8789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008790posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008791{
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 WAIT_TYPE status;
8793 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008794
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8796 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008797
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008799}
8800#endif /* WIFSIGNALED */
8801
8802#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008803PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008804"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008805Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008806system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008807
8808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008809posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008810{
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 WAIT_TYPE status;
8812 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008813
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8815 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008816
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008818}
8819#endif /* WIFEXITED */
8820
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008821#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008822PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008823"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008824Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008825
8826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008827posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008828{
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 WAIT_TYPE status;
8830 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008831
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8833 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008834
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008836}
8837#endif /* WEXITSTATUS */
8838
8839#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008840PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008841"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008842Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008843value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008844
8845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008846posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008847{
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 WAIT_TYPE status;
8849 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008850
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8852 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008853
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008855}
8856#endif /* WTERMSIG */
8857
8858#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008859PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008860"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008861Return the signal that stopped the process that provided\n\
8862the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008863
8864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008865posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008866{
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 WAIT_TYPE status;
8868 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008869
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8871 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008872
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008874}
8875#endif /* WSTOPSIG */
8876
8877#endif /* HAVE_SYS_WAIT_H */
8878
8879
Thomas Wouters477c8d52006-05-27 19:21:47 +00008880#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008881#ifdef _SCO_DS
8882/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8883 needed definitions in sys/statvfs.h */
8884#define _SVID3
8885#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008886#include <sys/statvfs.h>
8887
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008888static PyObject*
8889_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8891 if (v == NULL)
8892 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008893
8894#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8896 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8897 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8898 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8899 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8900 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8901 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8902 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8903 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8904 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008905#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8907 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8908 PyStructSequence_SET_ITEM(v, 2,
8909 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8910 PyStructSequence_SET_ITEM(v, 3,
8911 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8912 PyStructSequence_SET_ITEM(v, 4,
8913 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8914 PyStructSequence_SET_ITEM(v, 5,
8915 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8916 PyStructSequence_SET_ITEM(v, 6,
8917 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8918 PyStructSequence_SET_ITEM(v, 7,
8919 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8920 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8921 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008922#endif
8923
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008925}
8926
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008927PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008928"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008929Perform an fstatvfs system call on the given fd.\n\
8930Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008931
8932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008933posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008934{
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 int fd, res;
8936 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008937
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8939 return NULL;
8940 Py_BEGIN_ALLOW_THREADS
8941 res = fstatvfs(fd, &st);
8942 Py_END_ALLOW_THREADS
8943 if (res != 0)
8944 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008945
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008947}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008948#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008949
8950
Thomas Wouters477c8d52006-05-27 19:21:47 +00008951#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008952#include <sys/statvfs.h>
8953
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008954PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008955"statvfs(path)\n\n\
8956Perform a statvfs system call on the given path.\n\
8957\n\
8958path may always be specified as a string.\n\
8959On some platforms, path may also be specified as an open file descriptor.\n\
8960 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008961
8962static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008963posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008964{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008965 static char *keywords[] = {"path", NULL};
8966 path_t path;
8967 int result;
8968 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008970
Larry Hastings9cf065c2012-06-22 16:30:09 -07008971 memset(&path, 0, sizeof(path));
8972#ifdef HAVE_FSTATVFS
8973 path.allow_fd = 1;
8974#endif
8975 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8976 path_converter, &path
8977 ))
8978 return NULL;
8979
8980 Py_BEGIN_ALLOW_THREADS
8981#ifdef HAVE_FSTATVFS
8982 if (path.fd != -1) {
8983#ifdef __APPLE__
8984 /* handle weak-linking on Mac OS X 10.3 */
8985 if (fstatvfs == NULL) {
8986 fd_specified("statvfs", path.fd);
8987 goto exit;
8988 }
8989#endif
8990 result = fstatvfs(path.fd, &st);
8991 }
8992 else
8993#endif
8994 result = statvfs(path.narrow, &st);
8995 Py_END_ALLOW_THREADS
8996
8997 if (result) {
8998 return_value = path_posix_error("statvfs", &path);
8999 goto exit;
9000 }
9001
9002 return_value = _pystatvfs_fromstructstatvfs(st);
9003
9004exit:
9005 path_cleanup(&path);
9006 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009007}
9008#endif /* HAVE_STATVFS */
9009
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009010#ifdef MS_WINDOWS
9011PyDoc_STRVAR(win32__getdiskusage__doc__,
9012"_getdiskusage(path) -> (total, free)\n\n\
9013Return disk usage statistics about the given path as (total, free) tuple.");
9014
9015static PyObject *
9016win32__getdiskusage(PyObject *self, PyObject *args)
9017{
9018 BOOL retval;
9019 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009020 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009021
Victor Stinner6139c1b2011-11-09 22:14:14 +01009022 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009023 return NULL;
9024
9025 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009026 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009027 Py_END_ALLOW_THREADS
9028 if (retval == 0)
9029 return PyErr_SetFromWindowsErr(0);
9030
9031 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9032}
9033#endif
9034
9035
Fred Drakec9680921999-12-13 16:37:25 +00009036/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9037 * It maps strings representing configuration variable names to
9038 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009039 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009040 * rarely-used constants. There are three separate tables that use
9041 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009042 *
9043 * This code is always included, even if none of the interfaces that
9044 * need it are included. The #if hackery needed to avoid it would be
9045 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009046 */
9047struct constdef {
9048 char *name;
9049 long value;
9050};
9051
Fred Drake12c6e2d1999-12-14 21:25:03 +00009052static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009053conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009054 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009055{
Christian Heimes217cfd12007-12-02 14:31:20 +00009056 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009057 *valuep = PyLong_AS_LONG(arg);
9058 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009059 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009060 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009061 /* look up the value in the table using a binary search */
9062 size_t lo = 0;
9063 size_t mid;
9064 size_t hi = tablesize;
9065 int cmp;
9066 const char *confname;
9067 if (!PyUnicode_Check(arg)) {
9068 PyErr_SetString(PyExc_TypeError,
9069 "configuration names must be strings or integers");
9070 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009072 confname = _PyUnicode_AsString(arg);
9073 if (confname == NULL)
9074 return 0;
9075 while (lo < hi) {
9076 mid = (lo + hi) / 2;
9077 cmp = strcmp(confname, table[mid].name);
9078 if (cmp < 0)
9079 hi = mid;
9080 else if (cmp > 0)
9081 lo = mid + 1;
9082 else {
9083 *valuep = table[mid].value;
9084 return 1;
9085 }
9086 }
9087 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9088 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009090}
9091
9092
9093#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9094static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009095#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009097#endif
9098#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009100#endif
Fred Drakec9680921999-12-13 16:37:25 +00009101#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
9119#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009121#endif
9122#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
9125#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009127#endif
9128#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009130#endif
9131#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009133#endif
9134#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009136#endif
9137#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009139#endif
9140#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009142#endif
9143#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009146#ifdef _PC_ACL_ENABLED
9147 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9148#endif
9149#ifdef _PC_MIN_HOLE_SIZE
9150 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9151#endif
9152#ifdef _PC_ALLOC_SIZE_MIN
9153 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9154#endif
9155#ifdef _PC_REC_INCR_XFER_SIZE
9156 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9157#endif
9158#ifdef _PC_REC_MAX_XFER_SIZE
9159 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9160#endif
9161#ifdef _PC_REC_MIN_XFER_SIZE
9162 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9163#endif
9164#ifdef _PC_REC_XFER_ALIGN
9165 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9166#endif
9167#ifdef _PC_SYMLINK_MAX
9168 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9169#endif
9170#ifdef _PC_XATTR_ENABLED
9171 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9172#endif
9173#ifdef _PC_XATTR_EXISTS
9174 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9175#endif
9176#ifdef _PC_TIMESTAMP_RESOLUTION
9177 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9178#endif
Fred Drakec9680921999-12-13 16:37:25 +00009179};
9180
Fred Drakec9680921999-12-13 16:37:25 +00009181static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009182conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009183{
9184 return conv_confname(arg, valuep, posix_constants_pathconf,
9185 sizeof(posix_constants_pathconf)
9186 / sizeof(struct constdef));
9187}
9188#endif
9189
9190#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009191PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009192"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009193Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009194If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009195
9196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009197posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009198{
9199 PyObject *result = NULL;
9200 int name, fd;
9201
Fred Drake12c6e2d1999-12-14 21:25:03 +00009202 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9203 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009204 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009205
Stefan Krah0e803b32010-11-26 16:16:47 +00009206 errno = 0;
9207 limit = fpathconf(fd, name);
9208 if (limit == -1 && errno != 0)
9209 posix_error();
9210 else
9211 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009212 }
9213 return result;
9214}
9215#endif
9216
9217
9218#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009219PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009220"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009221Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009222If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009223
9224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009225posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009226{
9227 PyObject *result = NULL;
9228 int name;
9229 char *path;
9230
9231 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
9232 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009234
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 errno = 0;
9236 limit = pathconf(path, name);
9237 if (limit == -1 && errno != 0) {
9238 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009239 /* could be a path or name problem */
9240 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009241 else
Stefan Krah99439262010-11-26 12:58:05 +00009242 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 }
9244 else
9245 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009246 }
9247 return result;
9248}
9249#endif
9250
9251#ifdef HAVE_CONFSTR
9252static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009253#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009255#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009256#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009258#endif
9259#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009261#endif
Fred Draked86ed291999-12-15 15:34:33 +00009262#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009264#endif
9265#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009267#endif
9268#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009270#endif
9271#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009273#endif
Fred Drakec9680921999-12-13 16:37:25 +00009274#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
9277#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009279#endif
9280#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009282#endif
9283#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009285#endif
9286#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009288#endif
9289#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
9292#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009294#endif
9295#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009297#endif
Fred Draked86ed291999-12-15 15:34:33 +00009298#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009300#endif
Fred Drakec9680921999-12-13 16:37:25 +00009301#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009303#endif
Fred Draked86ed291999-12-15 15:34:33 +00009304#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009306#endif
9307#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009309#endif
9310#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009312#endif
9313#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009315#endif
Fred Drakec9680921999-12-13 16:37:25 +00009316#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
Fred Draked86ed291999-12-15 15:34:33 +00009364#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009366#endif
9367#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009369#endif
9370#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009372#endif
9373#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009375#endif
9376#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009378#endif
9379#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009381#endif
9382#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009384#endif
9385#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009387#endif
9388#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009390#endif
9391#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009393#endif
9394#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009396#endif
9397#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009399#endif
9400#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009402#endif
Fred Drakec9680921999-12-13 16:37:25 +00009403};
9404
9405static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009406conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009407{
9408 return conv_confname(arg, valuep, posix_constants_confstr,
9409 sizeof(posix_constants_confstr)
9410 / sizeof(struct constdef));
9411}
9412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009413PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009414"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009415Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009416
9417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009418posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009419{
9420 PyObject *result = NULL;
9421 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009422 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009423 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009424
Victor Stinnercb043522010-09-10 23:49:04 +00009425 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9426 return NULL;
9427
9428 errno = 0;
9429 len = confstr(name, buffer, sizeof(buffer));
9430 if (len == 0) {
9431 if (errno) {
9432 posix_error();
9433 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009434 }
9435 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009436 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009437 }
9438 }
Victor Stinnercb043522010-09-10 23:49:04 +00009439
9440 if ((unsigned int)len >= sizeof(buffer)) {
9441 char *buf = PyMem_Malloc(len);
9442 if (buf == NULL)
9443 return PyErr_NoMemory();
9444 confstr(name, buf, len);
9445 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9446 PyMem_Free(buf);
9447 }
9448 else
9449 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009450 return result;
9451}
9452#endif
9453
9454
9455#ifdef HAVE_SYSCONF
9456static struct constdef posix_constants_sysconf[] = {
9457#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
9475#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009477#endif
9478#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009480#endif
9481#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
9484#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
Fred Draked86ed291999-12-15 15:34:33 +00009487#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009489#endif
9490#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009492#endif
Fred Drakec9680921999-12-13 16:37:25 +00009493#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
Fred Drakec9680921999-12-13 16:37:25 +00009496#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
Fred Draked86ed291999-12-15 15:34:33 +00009511#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009513#endif
Fred Drakec9680921999-12-13 16:37:25 +00009514#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
Fred Draked86ed291999-12-15 15:34:33 +00009529#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009531#endif
Fred Drakec9680921999-12-13 16:37:25 +00009532#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
Fred Draked86ed291999-12-15 15:34:33 +00009601#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009603#endif
Fred Drakec9680921999-12-13 16:37:25 +00009604#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
Fred Draked86ed291999-12-15 15:34:33 +00009613#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009615#endif
Fred Drakec9680921999-12-13 16:37:25 +00009616#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
Fred Draked86ed291999-12-15 15:34:33 +00009619#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009621#endif
9622#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009624#endif
Fred Drakec9680921999-12-13 16:37:25 +00009625#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
Fred Draked86ed291999-12-15 15:34:33 +00009637#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
Fred Drakec9680921999-12-13 16:37:25 +00009640#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
9649#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
9652#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
Fred Draked86ed291999-12-15 15:34:33 +00009661#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009663#endif
Fred Drakec9680921999-12-13 16:37:25 +00009664#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
9667#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
Fred Draked86ed291999-12-15 15:34:33 +00009670#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009672#endif
Fred Drakec9680921999-12-13 16:37:25 +00009673#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
9676#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
9691#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009693#endif
9694#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
Fred Draked86ed291999-12-15 15:34:33 +00009700#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009702#endif
9703#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009705#endif
Fred Drakec9680921999-12-13 16:37:25 +00009706#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
9712#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
9718#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
Fred Draked86ed291999-12-15 15:34:33 +00009811#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009813#endif
Fred Drakec9680921999-12-13 16:37:25 +00009814#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
9841#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949};
9950
9951static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009952conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009953{
9954 return conv_confname(arg, valuep, posix_constants_sysconf,
9955 sizeof(posix_constants_sysconf)
9956 / sizeof(struct constdef));
9957}
9958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009959PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009960"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009961Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009962
9963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009964posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009965{
9966 PyObject *result = NULL;
9967 int name;
9968
9969 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9970 int value;
9971
9972 errno = 0;
9973 value = sysconf(name);
9974 if (value == -1 && errno != 0)
9975 posix_error();
9976 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009977 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009978 }
9979 return result;
9980}
9981#endif
9982
9983
Fred Drakebec628d1999-12-15 18:31:10 +00009984/* This code is used to ensure that the tables of configuration value names
9985 * are in sorted order as required by conv_confname(), and also to build the
9986 * the exported dictionaries that are used to publish information about the
9987 * names available on the host platform.
9988 *
9989 * Sorting the table at runtime ensures that the table is properly ordered
9990 * when used, even for platforms we're not able to test on. It also makes
9991 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009992 */
Fred Drakebec628d1999-12-15 18:31:10 +00009993
9994static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009995cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009996{
9997 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009999 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010001
10002 return strcmp(c1->name, c2->name);
10003}
10004
10005static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010006setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010008{
Fred Drakebec628d1999-12-15 18:31:10 +000010009 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010010 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010011
10012 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10013 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010014 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010016
Barry Warsaw3155db32000-04-13 15:20:40 +000010017 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 PyObject *o = PyLong_FromLong(table[i].value);
10019 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10020 Py_XDECREF(o);
10021 Py_DECREF(d);
10022 return -1;
10023 }
10024 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010025 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010026 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010027}
10028
Fred Drakebec628d1999-12-15 18:31:10 +000010029/* Return -1 on failure, 0 on success. */
10030static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010031setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010032{
10033#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010034 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010035 sizeof(posix_constants_pathconf)
10036 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010037 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010038 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010039#endif
10040#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010041 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010042 sizeof(posix_constants_confstr)
10043 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010044 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010045 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010048 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010049 sizeof(posix_constants_sysconf)
10050 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010051 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010052 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010053#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010054 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010055}
Fred Draked86ed291999-12-15 15:34:33 +000010056
10057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010058PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010059"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010060Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010061in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010062
10063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010064posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010065{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010066 abort();
10067 /*NOTREACHED*/
10068 Py_FatalError("abort() called from Python code didn't abort!");
10069 return NULL;
10070}
Fred Drakebec628d1999-12-15 18:31:10 +000010071
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010072#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010073PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010074"startfile(filepath [, operation]) - Start a file with its associated\n\
10075application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010076\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010077When \"operation\" is not specified or \"open\", this acts like\n\
10078double-clicking the file in Explorer, or giving the file name as an\n\
10079argument to the DOS \"start\" command: the file is opened with whatever\n\
10080application (if any) its extension is associated.\n\
10081When another \"operation\" is given, it specifies what should be done with\n\
10082the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010083\n\
10084startfile returns as soon as the associated application is launched.\n\
10085There is no option to wait for the application to close, and no way\n\
10086to retrieve the application's exit status.\n\
10087\n\
10088The filepath is relative to the current directory. If you want to use\n\
10089an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010090the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010091
10092static PyObject *
10093win32_startfile(PyObject *self, PyObject *args)
10094{
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 PyObject *ofilepath;
10096 char *filepath;
10097 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010098 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010100
Victor Stinnereb5657a2011-09-30 01:44:27 +020010101 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 if (!PyArg_ParseTuple(args, "U|s:startfile",
10103 &unipath, &operation)) {
10104 PyErr_Clear();
10105 goto normal;
10106 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010107
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010109 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010111 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 PyErr_Clear();
10113 operation = NULL;
10114 goto normal;
10115 }
10116 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010117
Victor Stinnereb5657a2011-09-30 01:44:27 +020010118 wpath = PyUnicode_AsUnicode(unipath);
10119 if (wpath == NULL)
10120 goto normal;
10121 if (uoperation) {
10122 woperation = PyUnicode_AsUnicode(uoperation);
10123 if (woperation == NULL)
10124 goto normal;
10125 }
10126 else
10127 woperation = NULL;
10128
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010130 rc = ShellExecuteW((HWND)0, woperation, wpath,
10131 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 Py_END_ALLOW_THREADS
10133
Victor Stinnereb5657a2011-09-30 01:44:27 +020010134 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010136 win32_error_object("startfile", unipath);
10137 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 }
10139 Py_INCREF(Py_None);
10140 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010141
10142normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10144 PyUnicode_FSConverter, &ofilepath,
10145 &operation))
10146 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010147 if (win32_warn_bytes_api()) {
10148 Py_DECREF(ofilepath);
10149 return NULL;
10150 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 filepath = PyBytes_AsString(ofilepath);
10152 Py_BEGIN_ALLOW_THREADS
10153 rc = ShellExecute((HWND)0, operation, filepath,
10154 NULL, NULL, SW_SHOWNORMAL);
10155 Py_END_ALLOW_THREADS
10156 if (rc <= (HINSTANCE)32) {
10157 PyObject *errval = win32_error("startfile", filepath);
10158 Py_DECREF(ofilepath);
10159 return errval;
10160 }
10161 Py_DECREF(ofilepath);
10162 Py_INCREF(Py_None);
10163 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010164}
10165#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010166
Martin v. Löwis438b5342002-12-27 10:16:42 +000010167#ifdef HAVE_GETLOADAVG
10168PyDoc_STRVAR(posix_getloadavg__doc__,
10169"getloadavg() -> (float, float, float)\n\n\
10170Return the number of processes in the system run queue averaged over\n\
10171the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10172was unobtainable");
10173
10174static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010175posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010176{
10177 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010178 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010179 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10180 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010181 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010182 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010183}
10184#endif
10185
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010186PyDoc_STRVAR(device_encoding__doc__,
10187"device_encoding(fd) -> str\n\n\
10188Return a string describing the encoding of the device\n\
10189if the output is a terminal; else return None.");
10190
10191static PyObject *
10192device_encoding(PyObject *self, PyObject *args)
10193{
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010195
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10197 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010198
10199 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010200}
10201
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010202#ifdef __VMS
10203/* Use openssl random routine */
10204#include <openssl/rand.h>
10205PyDoc_STRVAR(vms_urandom__doc__,
10206"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +000010207Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010208
10209static PyObject*
10210vms_urandom(PyObject *self, PyObject *args)
10211{
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 int howMany;
10213 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010214
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 /* Read arguments */
10216 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10217 return NULL;
10218 if (howMany < 0)
10219 return PyErr_Format(PyExc_ValueError,
10220 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010221
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 /* Allocate bytes */
10223 result = PyBytes_FromStringAndSize(NULL, howMany);
10224 if (result != NULL) {
10225 /* Get random data */
10226 if (RAND_pseudo_bytes((unsigned char*)
10227 PyBytes_AS_STRING(result),
10228 howMany) < 0) {
10229 Py_DECREF(result);
10230 return PyErr_Format(PyExc_ValueError,
10231 "RAND_pseudo_bytes");
10232 }
10233 }
10234 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010235}
10236#endif
10237
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010238#ifdef HAVE_SETRESUID
10239PyDoc_STRVAR(posix_setresuid__doc__,
10240"setresuid(ruid, euid, suid)\n\n\
10241Set the current process's real, effective, and saved user ids.");
10242
10243static PyObject*
10244posix_setresuid (PyObject *self, PyObject *args)
10245{
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 /* We assume uid_t is no larger than a long. */
10247 long ruid, euid, suid;
10248 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10249 return NULL;
10250 if (setresuid(ruid, euid, suid) < 0)
10251 return posix_error();
10252 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010253}
10254#endif
10255
10256#ifdef HAVE_SETRESGID
10257PyDoc_STRVAR(posix_setresgid__doc__,
10258"setresgid(rgid, egid, sgid)\n\n\
10259Set the current process's real, effective, and saved group ids.");
10260
10261static PyObject*
10262posix_setresgid (PyObject *self, PyObject *args)
10263{
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 /* We assume uid_t is no larger than a long. */
10265 long rgid, egid, sgid;
10266 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10267 return NULL;
10268 if (setresgid(rgid, egid, sgid) < 0)
10269 return posix_error();
10270 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010271}
10272#endif
10273
10274#ifdef HAVE_GETRESUID
10275PyDoc_STRVAR(posix_getresuid__doc__,
10276"getresuid() -> (ruid, euid, suid)\n\n\
10277Get tuple of the current process's real, effective, and saved user ids.");
10278
10279static PyObject*
10280posix_getresuid (PyObject *self, PyObject *noargs)
10281{
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 uid_t ruid, euid, suid;
10283 long l_ruid, l_euid, l_suid;
10284 if (getresuid(&ruid, &euid, &suid) < 0)
10285 return posix_error();
10286 /* Force the values into long's as we don't know the size of uid_t. */
10287 l_ruid = ruid;
10288 l_euid = euid;
10289 l_suid = suid;
10290 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010291}
10292#endif
10293
10294#ifdef HAVE_GETRESGID
10295PyDoc_STRVAR(posix_getresgid__doc__,
10296"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010297Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010298
10299static PyObject*
10300posix_getresgid (PyObject *self, PyObject *noargs)
10301{
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 uid_t rgid, egid, sgid;
10303 long l_rgid, l_egid, l_sgid;
10304 if (getresgid(&rgid, &egid, &sgid) < 0)
10305 return posix_error();
10306 /* Force the values into long's as we don't know the size of uid_t. */
10307 l_rgid = rgid;
10308 l_egid = egid;
10309 l_sgid = sgid;
10310 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010311}
10312#endif
10313
Benjamin Peterson9428d532011-09-14 11:45:52 -040010314#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010315
Benjamin Peterson799bd802011-08-31 22:15:17 -040010316PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010317"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10318Return the value of extended attribute attribute on path.\n\
10319\n\
10320path may be either a string or an open file descriptor.\n\
10321If follow_symlinks is False, and the last element of the path is a symbolic\n\
10322 link, getxattr will examine the symbolic link itself instead of the file\n\
10323 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010324
10325static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010326posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010327{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010328 path_t path;
10329 path_t attribute;
10330 int follow_symlinks = 1;
10331 PyObject *buffer = NULL;
10332 int i;
10333 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010334
Larry Hastings9cf065c2012-06-22 16:30:09 -070010335 memset(&path, 0, sizeof(path));
10336 memset(&attribute, 0, sizeof(attribute));
10337 path.allow_fd = 1;
10338 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10339 path_converter, &path,
10340 path_converter, &attribute,
10341 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010342 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010343
Larry Hastings9cf065c2012-06-22 16:30:09 -070010344 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10345 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010346
Larry Hastings9cf065c2012-06-22 16:30:09 -070010347 for (i = 0; ; i++) {
10348 void *ptr;
10349 ssize_t result;
10350 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10351 Py_ssize_t buffer_size = buffer_sizes[i];
10352 if (!buffer_size) {
10353 path_error("getxattr", &path);
10354 goto exit;
10355 }
10356 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10357 if (!buffer)
10358 goto exit;
10359 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010360
Larry Hastings9cf065c2012-06-22 16:30:09 -070010361 Py_BEGIN_ALLOW_THREADS;
10362 if (path.fd >= 0)
10363 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10364 else if (follow_symlinks)
10365 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10366 else
10367 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10368 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010369
Larry Hastings9cf065c2012-06-22 16:30:09 -070010370 if (result < 0) {
10371 Py_DECREF(buffer);
10372 buffer = NULL;
10373 if (errno == ERANGE)
10374 continue;
10375 path_error("getxattr", &path);
10376 goto exit;
10377 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010378
Larry Hastings9cf065c2012-06-22 16:30:09 -070010379 if (result != buffer_size) {
10380 /* Can only shrink. */
10381 _PyBytes_Resize(&buffer, result);
10382 }
10383 break;
10384 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010385
Larry Hastings9cf065c2012-06-22 16:30:09 -070010386exit:
10387 path_cleanup(&path);
10388 path_cleanup(&attribute);
10389 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010390}
10391
10392PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10394Set extended attribute attribute on path to value.\n\
10395path may be either a string or an open file descriptor.\n\
10396If follow_symlinks is False, and the last element of the path is a symbolic\n\
10397 link, setxattr will modify the symbolic link itself instead of the file\n\
10398 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010399
10400static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010401posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010402{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010403 path_t path;
10404 path_t attribute;
10405 Py_buffer value;
10406 int flags = 0;
10407 int follow_symlinks = 1;
10408 int result;
10409 PyObject *return_value = NULL;
10410 static char *keywords[] = {"path", "attribute", "value",
10411 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010412
Larry Hastings9cf065c2012-06-22 16:30:09 -070010413 memset(&path, 0, sizeof(path));
10414 path.allow_fd = 1;
10415 memset(&attribute, 0, sizeof(attribute));
10416 memset(&value, 0, sizeof(value));
10417 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10418 keywords,
10419 path_converter, &path,
10420 path_converter, &attribute,
10421 &value, &flags,
10422 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010423 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010424
10425 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10426 goto exit;
10427
Benjamin Peterson799bd802011-08-31 22:15:17 -040010428 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010429 if (path.fd > -1)
10430 result = fsetxattr(path.fd, attribute.narrow,
10431 value.buf, value.len, flags);
10432 else if (follow_symlinks)
10433 result = setxattr(path.narrow, attribute.narrow,
10434 value.buf, value.len, flags);
10435 else
10436 result = lsetxattr(path.narrow, attribute.narrow,
10437 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010438 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010439
Larry Hastings9cf065c2012-06-22 16:30:09 -070010440 if (result) {
10441 return_value = path_error("setxattr", &path);
10442 goto exit;
10443 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010444
Larry Hastings9cf065c2012-06-22 16:30:09 -070010445 return_value = Py_None;
10446 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010447
Larry Hastings9cf065c2012-06-22 16:30:09 -070010448exit:
10449 path_cleanup(&path);
10450 path_cleanup(&attribute);
10451 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010454}
10455
10456PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010457"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10458Remove extended attribute attribute on path.\n\
10459path may be either a string or an open file descriptor.\n\
10460If follow_symlinks is False, and the last element of the path is a symbolic\n\
10461 link, removexattr will modify the symbolic link itself instead of the file\n\
10462 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463
10464static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010465posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010466{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010467 path_t path;
10468 path_t attribute;
10469 int follow_symlinks = 1;
10470 int result;
10471 PyObject *return_value = NULL;
10472 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010473
Larry Hastings9cf065c2012-06-22 16:30:09 -070010474 memset(&path, 0, sizeof(path));
10475 memset(&attribute, 0, sizeof(attribute));
10476 path.allow_fd = 1;
10477 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10478 keywords,
10479 path_converter, &path,
10480 path_converter, &attribute,
10481 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010482 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010483
10484 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10485 goto exit;
10486
Benjamin Peterson799bd802011-08-31 22:15:17 -040010487 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010488 if (path.fd > -1)
10489 result = fremovexattr(path.fd, attribute.narrow);
10490 else if (follow_symlinks)
10491 result = removexattr(path.narrow, attribute.narrow);
10492 else
10493 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010495
Larry Hastings9cf065c2012-06-22 16:30:09 -070010496 if (result) {
10497 return_value = path_error("removexattr", &path);
10498 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010499 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010500
Larry Hastings9cf065c2012-06-22 16:30:09 -070010501 return_value = Py_None;
10502 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010503
Larry Hastings9cf065c2012-06-22 16:30:09 -070010504exit:
10505 path_cleanup(&path);
10506 path_cleanup(&attribute);
10507
10508 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010509}
10510
10511PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512"listxattr(path='.', *, follow_symlinks=True)\n\n\
10513Return a list of extended attributes on path.\n\
10514\n\
10515path may be either None, a string, or an open file descriptor.\n\
10516if path is None, listxattr will examine the current directory.\n\
10517If follow_symlinks is False, and the last element of the path is a symbolic\n\
10518 link, listxattr will examine the symbolic link itself instead of the file\n\
10519 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010520
10521static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010522posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010523{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010524 path_t path;
10525 int follow_symlinks = 1;
10526 Py_ssize_t i;
10527 PyObject *result = NULL;
10528 char *buffer = NULL;
10529 char *name;
10530 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010531
Larry Hastings9cf065c2012-06-22 16:30:09 -070010532 memset(&path, 0, sizeof(path));
10533 path.allow_fd = 1;
10534 path.fd = -1;
10535 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10536 path_converter, &path,
10537 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010538 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010539
Larry Hastings9cf065c2012-06-22 16:30:09 -070010540 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10541 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010542
Larry Hastings9cf065c2012-06-22 16:30:09 -070010543 name = path.narrow ? path.narrow : ".";
10544 for (i = 0; ; i++) {
10545 char *start, *trace, *end;
10546 ssize_t length;
10547 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10548 Py_ssize_t buffer_size = buffer_sizes[i];
10549 if (!buffer_size) {
10550 // ERANGE
10551 path_error("listxattr", &path);
10552 break;
10553 }
10554 buffer = PyMem_MALLOC(buffer_size);
10555 if (!buffer) {
10556 PyErr_NoMemory();
10557 break;
10558 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010559
Larry Hastings9cf065c2012-06-22 16:30:09 -070010560 Py_BEGIN_ALLOW_THREADS;
10561 if (path.fd > -1)
10562 length = flistxattr(path.fd, buffer, buffer_size);
10563 else if (follow_symlinks)
10564 length = listxattr(name, buffer, buffer_size);
10565 else
10566 length = llistxattr(name, buffer, buffer_size);
10567 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568
Larry Hastings9cf065c2012-06-22 16:30:09 -070010569 if (length < 0) {
10570 if (errno == ERANGE)
10571 continue;
10572 path_error("listxattr", &path);
10573 break;
10574 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010575
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576 result = PyList_New(0);
10577 if (!result) {
10578 goto exit;
10579 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580
Larry Hastings9cf065c2012-06-22 16:30:09 -070010581 end = buffer + length;
10582 for (trace = start = buffer; trace != end; trace++) {
10583 if (!*trace) {
10584 int error;
10585 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10586 trace - start);
10587 if (!attribute) {
10588 Py_DECREF(result);
10589 result = NULL;
10590 goto exit;
10591 }
10592 error = PyList_Append(result, attribute);
10593 Py_DECREF(attribute);
10594 if (error) {
10595 Py_DECREF(result);
10596 result = NULL;
10597 goto exit;
10598 }
10599 start = trace + 1;
10600 }
10601 }
10602 break;
10603 }
10604exit:
10605 path_cleanup(&path);
10606 if (buffer)
10607 PyMem_FREE(buffer);
10608 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609}
10610
Benjamin Peterson9428d532011-09-14 11:45:52 -040010611#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010612
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010613
Georg Brandl2fb477c2012-02-21 00:33:36 +010010614PyDoc_STRVAR(posix_urandom__doc__,
10615"urandom(n) -> str\n\n\
10616Return n random bytes suitable for cryptographic use.");
10617
10618static PyObject *
10619posix_urandom(PyObject *self, PyObject *args)
10620{
10621 Py_ssize_t size;
10622 PyObject *result;
10623 int ret;
10624
10625 /* Read arguments */
10626 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10627 return NULL;
10628 if (size < 0)
10629 return PyErr_Format(PyExc_ValueError,
10630 "negative argument not allowed");
10631 result = PyBytes_FromStringAndSize(NULL, size);
10632 if (result == NULL)
10633 return NULL;
10634
10635 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10636 PyBytes_GET_SIZE(result));
10637 if (ret == -1) {
10638 Py_DECREF(result);
10639 return NULL;
10640 }
10641 return result;
10642}
10643
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010644/* Terminal size querying */
10645
10646static PyTypeObject TerminalSizeType;
10647
10648PyDoc_STRVAR(TerminalSize_docstring,
10649 "A tuple of (columns, lines) for holding terminal window size");
10650
10651static PyStructSequence_Field TerminalSize_fields[] = {
10652 {"columns", "width of the terminal window in characters"},
10653 {"lines", "height of the terminal window in characters"},
10654 {NULL, NULL}
10655};
10656
10657static PyStructSequence_Desc TerminalSize_desc = {
10658 "os.terminal_size",
10659 TerminalSize_docstring,
10660 TerminalSize_fields,
10661 2,
10662};
10663
10664#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10665PyDoc_STRVAR(termsize__doc__,
10666 "Return the size of the terminal window as (columns, lines).\n" \
10667 "\n" \
10668 "The optional argument fd (default standard output) specifies\n" \
10669 "which file descriptor should be queried.\n" \
10670 "\n" \
10671 "If the file descriptor is not connected to a terminal, an OSError\n" \
10672 "is thrown.\n" \
10673 "\n" \
10674 "This function will only be defined if an implementation is\n" \
10675 "available for this system.\n" \
10676 "\n" \
10677 "shutil.get_terminal_size is the high-level function which should \n" \
10678 "normally be used, os.get_terminal_size is the low-level implementation.");
10679
10680static PyObject*
10681get_terminal_size(PyObject *self, PyObject *args)
10682{
10683 int columns, lines;
10684 PyObject *termsize;
10685
10686 int fd = fileno(stdout);
10687 /* Under some conditions stdout may not be connected and
10688 * fileno(stdout) may point to an invalid file descriptor. For example
10689 * GUI apps don't have valid standard streams by default.
10690 *
10691 * If this happens, and the optional fd argument is not present,
10692 * the ioctl below will fail returning EBADF. This is what we want.
10693 */
10694
10695 if (!PyArg_ParseTuple(args, "|i", &fd))
10696 return NULL;
10697
10698#ifdef TERMSIZE_USE_IOCTL
10699 {
10700 struct winsize w;
10701 if (ioctl(fd, TIOCGWINSZ, &w))
10702 return PyErr_SetFromErrno(PyExc_OSError);
10703 columns = w.ws_col;
10704 lines = w.ws_row;
10705 }
10706#endif /* TERMSIZE_USE_IOCTL */
10707
10708#ifdef TERMSIZE_USE_CONIO
10709 {
10710 DWORD nhandle;
10711 HANDLE handle;
10712 CONSOLE_SCREEN_BUFFER_INFO csbi;
10713 switch (fd) {
10714 case 0: nhandle = STD_INPUT_HANDLE;
10715 break;
10716 case 1: nhandle = STD_OUTPUT_HANDLE;
10717 break;
10718 case 2: nhandle = STD_ERROR_HANDLE;
10719 break;
10720 default:
10721 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10722 }
10723 handle = GetStdHandle(nhandle);
10724 if (handle == NULL)
10725 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10726 if (handle == INVALID_HANDLE_VALUE)
10727 return PyErr_SetFromWindowsErr(0);
10728
10729 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10730 return PyErr_SetFromWindowsErr(0);
10731
10732 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10733 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10734 }
10735#endif /* TERMSIZE_USE_CONIO */
10736
10737 termsize = PyStructSequence_New(&TerminalSizeType);
10738 if (termsize == NULL)
10739 return NULL;
10740 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10741 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10742 if (PyErr_Occurred()) {
10743 Py_DECREF(termsize);
10744 return NULL;
10745 }
10746 return termsize;
10747}
10748#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10749
10750
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010751static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 {"access", (PyCFunction)posix_access,
10753 METH_VARARGS | METH_KEYWORDS,
10754 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010755#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010757#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 {"chdir", (PyCFunction)posix_chdir,
10759 METH_VARARGS | METH_KEYWORDS,
10760 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010761#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762 {"chflags", (PyCFunction)posix_chflags,
10763 METH_VARARGS | METH_KEYWORDS,
10764 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010765#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766 {"chmod", (PyCFunction)posix_chmod,
10767 METH_VARARGS | METH_KEYWORDS,
10768 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010769#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010771#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010772#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 {"chown", (PyCFunction)posix_chown,
10774 METH_VARARGS | METH_KEYWORDS,
10775 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010776#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010777#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010779#endif /* HAVE_LCHMOD */
10780#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010782#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010783#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010785#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010786#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010788#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010789#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010791#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010792#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010794#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010795#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10797 METH_NOARGS, posix_getcwd__doc__},
10798 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10799 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010800#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010801#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10802 {"link", (PyCFunction)posix_link,
10803 METH_VARARGS | METH_KEYWORDS,
10804 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010805#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010806 {"listdir", (PyCFunction)posix_listdir,
10807 METH_VARARGS | METH_KEYWORDS,
10808 posix_listdir__doc__},
10809 {"lstat", (PyCFunction)posix_lstat,
10810 METH_VARARGS | METH_KEYWORDS,
10811 posix_lstat__doc__},
10812 {"mkdir", (PyCFunction)posix_mkdir,
10813 METH_VARARGS | METH_KEYWORDS,
10814 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010815#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010817#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010818#ifdef HAVE_GETPRIORITY
10819 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10820#endif /* HAVE_GETPRIORITY */
10821#ifdef HAVE_SETPRIORITY
10822 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10823#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010824#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 {"readlink", (PyCFunction)posix_readlink,
10826 METH_VARARGS | METH_KEYWORDS,
10827 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010828#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010829#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010830 {"readlink", (PyCFunction)win_readlink,
10831 METH_VARARGS | METH_KEYWORDS,
10832 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010833#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010834 {"rename", (PyCFunction)posix_rename,
10835 METH_VARARGS | METH_KEYWORDS,
10836 posix_rename__doc__},
10837 {"replace", (PyCFunction)posix_replace,
10838 METH_VARARGS | METH_KEYWORDS,
10839 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010840 {"rmdir", (PyCFunction)posix_rmdir,
10841 METH_VARARGS | METH_KEYWORDS,
10842 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 {"stat", (PyCFunction)posix_stat,
10844 METH_VARARGS | METH_KEYWORDS,
10845 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847#if defined(HAVE_SYMLINK)
10848 {"symlink", (PyCFunction)posix_symlink,
10849 METH_VARARGS | METH_KEYWORDS,
10850 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010851#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010852#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010854#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010856#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010858#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010859 {"unlink", (PyCFunction)posix_unlink,
10860 METH_VARARGS | METH_KEYWORDS,
10861 posix_unlink__doc__},
10862 {"remove", (PyCFunction)posix_unlink,
10863 METH_VARARGS | METH_KEYWORDS,
10864 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010865 {"utime", (PyCFunction)posix_utime,
10866 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010867#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010869#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010871#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010873 {"execve", (PyCFunction)posix_execve,
10874 METH_VARARGS | METH_KEYWORDS,
10875 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010876#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010877#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10879 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010880#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10882 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010883#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010884#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010885#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010887#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010888#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010890#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010891#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010892#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010893 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10894 {"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 +020010895#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010896#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010897 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010898#endif
10899#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010900 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010901#endif
10902#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010903 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010904#endif
10905#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010906 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010907#endif
10908#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010909 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010910#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010911 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010912#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010913 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10914 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10915#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010916#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010917#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010919#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010920#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010922#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010923#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010925#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010926#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010928#endif /* HAVE_GETEUID */
10929#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010931#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010932#ifdef HAVE_GETGROUPLIST
10933 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10934#endif
Fred Drakec9680921999-12-13 16:37:25 +000010935#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010939#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010941#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010942#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010944#endif /* HAVE_GETPPID */
10945#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010947#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010948#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010950#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010951#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010953#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010954#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010956#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010957#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010959#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010960#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10962 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010963#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010964#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010966#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010967#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010969#endif /* HAVE_SETEUID */
10970#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010972#endif /* HAVE_SETEGID */
10973#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010975#endif /* HAVE_SETREUID */
10976#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010978#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010979#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010981#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010982#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010984#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010985#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010987#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010988#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010990#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010991#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010993#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010994#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010996#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010997#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010998 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010999#endif /* HAVE_WAIT3 */
11000#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011001 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011002#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011003#if defined(HAVE_WAITID) && !defined(__APPLE__)
11004 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11005#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011006#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011008#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011009#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011011#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011012#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011014#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011015#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011017#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011018#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011020#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011021#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011023#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 {"open", (PyCFunction)posix_open,\
11025 METH_VARARGS | METH_KEYWORDS,
11026 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11028 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11029 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11030 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11031 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011032#ifdef HAVE_LOCKF
11033 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11034#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11036 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011037#ifdef HAVE_READV
11038 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11039#endif
11040#ifdef HAVE_PREAD
11041 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011044#ifdef HAVE_WRITEV
11045 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11046#endif
11047#ifdef HAVE_PWRITE
11048 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11049#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011050#ifdef HAVE_SENDFILE
11051 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11052 posix_sendfile__doc__},
11053#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011054 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011056#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011058#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011059#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011060 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011061#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011062#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011063 {"mkfifo", (PyCFunction)posix_mkfifo,
11064 METH_VARARGS | METH_KEYWORDS,
11065 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011066#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011067#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011068 {"mknod", (PyCFunction)posix_mknod,
11069 METH_VARARGS | METH_KEYWORDS,
11070 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011071#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011072#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11074 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11075 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011076#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011077#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011079#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011080#ifdef HAVE_TRUNCATE
11081 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
11082#endif
11083#ifdef HAVE_POSIX_FALLOCATE
11084 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11085#endif
11086#ifdef HAVE_POSIX_FADVISE
11087 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11088#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011089#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011091#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011092#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011094#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011096#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011098#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011099#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011101#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011102#ifdef HAVE_SYNC
11103 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11104#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011105#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011107#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011108#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011109#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011111#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011112#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011114#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011115#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011117#endif /* WIFSTOPPED */
11118#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011120#endif /* WIFSIGNALED */
11121#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011123#endif /* WIFEXITED */
11124#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011126#endif /* WEXITSTATUS */
11127#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011129#endif /* WTERMSIG */
11130#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011132#endif /* WSTOPSIG */
11133#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011134#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011136#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011137#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 {"statvfs", (PyCFunction)posix_statvfs,
11139 METH_VARARGS | METH_KEYWORDS,
11140 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011141#endif
Fred Drakec9680921999-12-13 16:37:25 +000011142#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011157 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011158 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011159 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011160 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011161#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011162#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011164#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011165 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011166#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011168#endif
11169#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011171#endif
11172#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011174#endif
11175#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011177#endif
11178
Benjamin Peterson9428d532011-09-14 11:45:52 -040011179#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 {"setxattr", (PyCFunction)posix_setxattr,
11181 METH_VARARGS | METH_KEYWORDS,
11182 posix_setxattr__doc__},
11183 {"getxattr", (PyCFunction)posix_getxattr,
11184 METH_VARARGS | METH_KEYWORDS,
11185 posix_getxattr__doc__},
11186 {"removexattr", (PyCFunction)posix_removexattr,
11187 METH_VARARGS | METH_KEYWORDS,
11188 posix_removexattr__doc__},
11189 {"listxattr", (PyCFunction)posix_listxattr,
11190 METH_VARARGS | METH_KEYWORDS,
11191 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011192#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011193#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11194 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11195#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011197};
11198
11199
Barry Warsaw4a342091996-12-19 23:50:02 +000011200static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011201ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011202{
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011204}
11205
Guido van Rossumd48f2521997-12-05 22:19:34 +000011206#if defined(PYOS_OS2)
11207/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011208static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011209{
11210 APIRET rc;
11211 ULONG values[QSV_MAX+1];
11212 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011213 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011214
11215 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011216 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011217 Py_END_ALLOW_THREADS
11218
11219 if (rc != NO_ERROR) {
11220 os2_error(rc);
11221 return -1;
11222 }
11223
Fred Drake4d1e64b2002-04-15 19:40:07 +000011224 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11225 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11226 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11227 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11228 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11229 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11230 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011231
11232 switch (values[QSV_VERSION_MINOR]) {
11233 case 0: ver = "2.00"; break;
11234 case 10: ver = "2.10"; break;
11235 case 11: ver = "2.11"; break;
11236 case 30: ver = "3.00"; break;
11237 case 40: ver = "4.00"; break;
11238 case 50: ver = "5.00"; break;
11239 default:
Tim Peters885d4572001-11-28 20:27:42 +000011240 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011242 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011243 ver = &tmp[0];
11244 }
11245
11246 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011247 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011248 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011249
11250 /* Add Indicator of Which Drive was Used to Boot the System */
11251 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11252 tmp[1] = ':';
11253 tmp[2] = '\0';
11254
Fred Drake4d1e64b2002-04-15 19:40:07 +000011255 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011256}
11257#endif
11258
Brian Curtin52173d42010-12-02 18:29:18 +000011259#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011260static int
Brian Curtin52173d42010-12-02 18:29:18 +000011261enable_symlink()
11262{
11263 HANDLE tok;
11264 TOKEN_PRIVILEGES tok_priv;
11265 LUID luid;
11266 int meth_idx = 0;
11267
11268 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011269 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011270
11271 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011272 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011273
11274 tok_priv.PrivilegeCount = 1;
11275 tok_priv.Privileges[0].Luid = luid;
11276 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11277
11278 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11279 sizeof(TOKEN_PRIVILEGES),
11280 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011281 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011282
Brian Curtin3b4499c2010-12-28 14:31:47 +000011283 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11284 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011285}
11286#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11287
Barry Warsaw4a342091996-12-19 23:50:02 +000011288static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011289all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011290{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011291#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011293#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011294#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011296#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011297#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011299#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011300#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011302#endif
Fred Drakec9680921999-12-13 16:37:25 +000011303#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011306#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011308#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011309#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011311#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011312#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011314#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011315#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011317#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011318#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011320#endif
11321#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011323#endif
11324#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011326#endif
11327#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011329#endif
11330#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011332#endif
11333#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011335#endif
11336#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011338#endif
11339#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011341#endif
11342#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011344#endif
11345#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011347#endif
11348#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011350#endif
11351#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011353#endif
11354#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011356#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011357#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011359#endif
11360#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011362#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011363#ifdef O_XATTR
11364 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11365#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011366#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011368#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011369#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011371#endif
11372#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011374#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011375#ifdef O_EXEC
11376 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11377#endif
11378#ifdef O_SEARCH
11379 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11380#endif
11381#ifdef O_TTY_INIT
11382 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11383#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011384#ifdef PRIO_PROCESS
11385 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11386#endif
11387#ifdef PRIO_PGRP
11388 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11389#endif
11390#ifdef PRIO_USER
11391 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11392#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011393#ifdef O_CLOEXEC
11394 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11395#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011396#ifdef O_ACCMODE
11397 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11398#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011399
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011400
Jesus Cea94363612012-06-22 18:32:07 +020011401#ifdef SEEK_HOLE
11402 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11403#endif
11404#ifdef SEEK_DATA
11405 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11406#endif
11407
Tim Peters5aa91602002-01-30 05:46:57 +000011408/* MS Windows */
11409#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 /* Don't inherit in child processes. */
11411 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011412#endif
11413#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 /* Optimize for short life (keep in memory). */
11415 /* MS forgot to define this one with a non-underscore form too. */
11416 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011417#endif
11418#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 /* Automatically delete when last handle is closed. */
11420 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011421#endif
11422#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 /* Optimize for random access. */
11424 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011425#endif
11426#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 /* Optimize for sequential access. */
11428 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011429#endif
11430
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011431/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011432#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 /* Send a SIGIO signal whenever input or output
11434 becomes available on file descriptor */
11435 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011436#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011437#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 /* Direct disk access. */
11439 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011440#endif
11441#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 /* Must be a directory. */
11443 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011444#endif
11445#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 /* Do not follow links. */
11447 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011448#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011449#ifdef O_NOLINKS
11450 /* Fails if link count of the named file is greater than 1 */
11451 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11452#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011453#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 /* Do not update the access time. */
11455 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011456#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011457
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011459#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011461#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011462#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011464#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011465#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011467#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011468#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011470#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011471#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011473#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011474#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011476#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011477#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011479#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011480#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011482#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011483#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011485#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011486#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011488#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011489#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011491#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011492#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011494#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011495#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011497#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011498#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011500#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011501#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011503#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011504#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011506#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011507#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011509#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011510
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011511 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011512#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011513 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011514#endif /* ST_RDONLY */
11515#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011516 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011517#endif /* ST_NOSUID */
11518
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011519 /* FreeBSD sendfile() constants */
11520#ifdef SF_NODISKIO
11521 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11522#endif
11523#ifdef SF_MNOWAIT
11524 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11525#endif
11526#ifdef SF_SYNC
11527 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11528#endif
11529
Ross Lagerwall7807c352011-03-17 20:20:30 +020011530 /* constants for posix_fadvise */
11531#ifdef POSIX_FADV_NORMAL
11532 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11533#endif
11534#ifdef POSIX_FADV_SEQUENTIAL
11535 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11536#endif
11537#ifdef POSIX_FADV_RANDOM
11538 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11539#endif
11540#ifdef POSIX_FADV_NOREUSE
11541 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11542#endif
11543#ifdef POSIX_FADV_WILLNEED
11544 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11545#endif
11546#ifdef POSIX_FADV_DONTNEED
11547 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11548#endif
11549
11550 /* constants for waitid */
11551#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11552 if (ins(d, "P_PID", (long)P_PID)) return -1;
11553 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11554 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11555#endif
11556#ifdef WEXITED
11557 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11558#endif
11559#ifdef WNOWAIT
11560 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11561#endif
11562#ifdef WSTOPPED
11563 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11564#endif
11565#ifdef CLD_EXITED
11566 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11567#endif
11568#ifdef CLD_DUMPED
11569 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11570#endif
11571#ifdef CLD_TRAPPED
11572 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11573#endif
11574#ifdef CLD_CONTINUED
11575 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11576#endif
11577
11578 /* constants for lockf */
11579#ifdef F_LOCK
11580 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11581#endif
11582#ifdef F_TLOCK
11583 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11584#endif
11585#ifdef F_ULOCK
11586 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11587#endif
11588#ifdef F_TEST
11589 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11590#endif
11591
Guido van Rossum246bc171999-02-01 23:54:31 +000011592#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011593#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11595 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11596 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11597 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11598 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11599 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11600 if (ins(d, "P_PM", (long)P_PM)) return -1;
11601 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11602 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11603 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11604 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11605 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11606 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11607 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11608 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11609 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11610 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11611 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11612 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11613 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011614#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11616 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11617 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11618 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11619 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011620#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011621#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011622
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011623#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011624 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011625 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11626 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11627#ifdef SCHED_SPORADIC
11628 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11629#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011630#ifdef SCHED_BATCH
11631 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11632#endif
11633#ifdef SCHED_IDLE
11634 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11635#endif
11636#ifdef SCHED_RESET_ON_FORK
11637 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11638#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011639#ifdef SCHED_SYS
11640 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11641#endif
11642#ifdef SCHED_IA
11643 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11644#endif
11645#ifdef SCHED_FSS
11646 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11647#endif
11648#ifdef SCHED_FX
11649 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11650#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011651#endif
11652
Benjamin Peterson9428d532011-09-14 11:45:52 -040011653#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011654 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11655 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11656 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11657#endif
11658
Victor Stinner8b905bd2011-10-25 13:34:04 +020011659#ifdef RTLD_LAZY
11660 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11661#endif
11662#ifdef RTLD_NOW
11663 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11664#endif
11665#ifdef RTLD_GLOBAL
11666 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11667#endif
11668#ifdef RTLD_LOCAL
11669 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11670#endif
11671#ifdef RTLD_NODELETE
11672 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11673#endif
11674#ifdef RTLD_NOLOAD
11675 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11676#endif
11677#ifdef RTLD_DEEPBIND
11678 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11679#endif
11680
Guido van Rossumd48f2521997-12-05 22:19:34 +000011681#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011683#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011685}
11686
11687
Tim Peters5aa91602002-01-30 05:46:57 +000011688#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011689#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011690#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011691
11692#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011693#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011694#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011695
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011696#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011697#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011698#define MODNAME "posix"
11699#endif
11700
Martin v. Löwis1a214512008-06-11 05:26:20 +000011701static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011702 PyModuleDef_HEAD_INIT,
11703 MODNAME,
11704 posix__doc__,
11705 -1,
11706 posix_methods,
11707 NULL,
11708 NULL,
11709 NULL,
11710 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011711};
11712
11713
Larry Hastings9cf065c2012-06-22 16:30:09 -070011714static char *have_functions[] = {
11715
11716#ifdef HAVE_FACCESSAT
11717 "HAVE_FACCESSAT",
11718#endif
11719
11720#ifdef HAVE_FCHDIR
11721 "HAVE_FCHDIR",
11722#endif
11723
11724#ifdef HAVE_FCHMOD
11725 "HAVE_FCHMOD",
11726#endif
11727
11728#ifdef HAVE_FCHMODAT
11729 "HAVE_FCHMODAT",
11730#endif
11731
11732#ifdef HAVE_FCHOWN
11733 "HAVE_FCHOWN",
11734#endif
11735
11736#ifdef HAVE_FEXECVE
11737 "HAVE_FEXECVE",
11738#endif
11739
11740#ifdef HAVE_FDOPENDIR
11741 "HAVE_FDOPENDIR",
11742#endif
11743
11744#ifdef HAVE_FSTATAT
11745 "HAVE_FSTATAT",
11746#endif
11747
11748#ifdef HAVE_FSTATVFS
11749 "HAVE_FSTATVFS",
11750#endif
11751
11752#ifdef HAVE_FUTIMENS
11753 "HAVE_FUTIMENS",
11754#endif
11755
11756#ifdef HAVE_FUTIMES
11757 "HAVE_FUTIMES",
11758#endif
11759
11760#ifdef HAVE_FUTIMESAT
11761 "HAVE_FUTIMESAT",
11762#endif
11763
11764#ifdef HAVE_LINKAT
11765 "HAVE_LINKAT",
11766#endif
11767
11768#ifdef HAVE_LCHFLAGS
11769 "HAVE_LCHFLAGS",
11770#endif
11771
11772#ifdef HAVE_LCHMOD
11773 "HAVE_LCHMOD",
11774#endif
11775
11776#ifdef HAVE_LCHOWN
11777 "HAVE_LCHOWN",
11778#endif
11779
11780#ifdef HAVE_LSTAT
11781 "HAVE_LSTAT",
11782#endif
11783
11784#ifdef HAVE_LUTIMES
11785 "HAVE_LUTIMES",
11786#endif
11787
11788#ifdef HAVE_MKDIRAT
11789 "HAVE_MKDIRAT",
11790#endif
11791
11792#ifdef HAVE_MKFIFOAT
11793 "HAVE_MKFIFOAT",
11794#endif
11795
11796#ifdef HAVE_MKNODAT
11797 "HAVE_MKNODAT",
11798#endif
11799
11800#ifdef HAVE_OPENAT
11801 "HAVE_OPENAT",
11802#endif
11803
11804#ifdef HAVE_READLINKAT
11805 "HAVE_READLINKAT",
11806#endif
11807
11808#ifdef HAVE_RENAMEAT
11809 "HAVE_RENAMEAT",
11810#endif
11811
11812#ifdef HAVE_SYMLINKAT
11813 "HAVE_SYMLINKAT",
11814#endif
11815
11816#ifdef HAVE_UNLINKAT
11817 "HAVE_UNLINKAT",
11818#endif
11819
11820#ifdef HAVE_UTIMENSAT
11821 "HAVE_UTIMENSAT",
11822#endif
11823
11824#ifdef MS_WINDOWS
11825 "MS_WINDOWS",
11826#endif
11827
11828 NULL
11829};
11830
11831
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011832PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011833INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011834{
Victor Stinner8c62be82010-05-06 00:08:46 +000011835 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011836 PyObject *list;
11837 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011838
Brian Curtin52173d42010-12-02 18:29:18 +000011839#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011840 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011841#endif
11842
Victor Stinner8c62be82010-05-06 00:08:46 +000011843 m = PyModule_Create(&posixmodule);
11844 if (m == NULL)
11845 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011846
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 /* Initialize environ dictionary */
11848 v = convertenviron();
11849 Py_XINCREF(v);
11850 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11851 return NULL;
11852 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011853
Victor Stinner8c62be82010-05-06 00:08:46 +000011854 if (all_ins(m))
11855 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011856
Victor Stinner8c62be82010-05-06 00:08:46 +000011857 if (setup_confname_tables(m))
11858 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011859
Victor Stinner8c62be82010-05-06 00:08:46 +000011860 Py_INCREF(PyExc_OSError);
11861 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011862
Benjamin Peterson2740af82011-08-02 17:41:34 -050011863#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011864 if (PyType_Ready(&cpu_set_type) < 0)
11865 return NULL;
11866 Py_INCREF(&cpu_set_type);
11867 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011868#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011869
Guido van Rossumb3d39562000-01-31 18:41:26 +000011870#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 if (posix_putenv_garbage == NULL)
11872 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011873#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011874
Victor Stinner8c62be82010-05-06 00:08:46 +000011875 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011876#if defined(HAVE_WAITID) && !defined(__APPLE__)
11877 waitid_result_desc.name = MODNAME ".waitid_result";
11878 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11879#endif
11880
Victor Stinner8c62be82010-05-06 00:08:46 +000011881 stat_result_desc.name = MODNAME ".stat_result";
11882 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11883 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11884 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11885 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11886 structseq_new = StatResultType.tp_new;
11887 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011888
Victor Stinner8c62be82010-05-06 00:08:46 +000011889 statvfs_result_desc.name = MODNAME ".statvfs_result";
11890 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011891#ifdef NEED_TICKS_PER_SECOND
11892# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011893 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011894# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011895 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011896# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011897 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011898# endif
11899#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011900
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011901#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011902 sched_param_desc.name = MODNAME ".sched_param";
11903 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11904 SchedParamType.tp_new = sched_param_new;
11905#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011906
11907 /* initialize TerminalSize_info */
11908 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11909 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011910 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011911#if defined(HAVE_WAITID) && !defined(__APPLE__)
11912 Py_INCREF((PyObject*) &WaitidResultType);
11913 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11914#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011915 Py_INCREF((PyObject*) &StatResultType);
11916 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11917 Py_INCREF((PyObject*) &StatVFSResultType);
11918 PyModule_AddObject(m, "statvfs_result",
11919 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011920
11921#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011922 Py_INCREF(&SchedParamType);
11923 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011924#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011925
11926#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011927 /*
11928 * Step 2 of weak-linking support on Mac OS X.
11929 *
11930 * The code below removes functions that are not available on the
11931 * currently active platform.
11932 *
11933 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011934 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011935 * OSX 10.4.
11936 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011937#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 if (fstatvfs == NULL) {
11939 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11940 return NULL;
11941 }
11942 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011943#endif /* HAVE_FSTATVFS */
11944
11945#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011946 if (statvfs == NULL) {
11947 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11948 return NULL;
11949 }
11950 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011951#endif /* HAVE_STATVFS */
11952
11953# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 if (lchown == NULL) {
11955 if (PyObject_DelAttrString(m, "lchown") == -1) {
11956 return NULL;
11957 }
11958 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011959#endif /* HAVE_LCHOWN */
11960
11961
11962#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011963
11964 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11965
Larry Hastings6fe20b32012-04-19 15:07:49 -070011966 billion = PyLong_FromLong(1000000000);
11967 if (!billion)
11968 return NULL;
11969
Larry Hastings9cf065c2012-06-22 16:30:09 -070011970 /* suppress "function not used" warnings */
11971 {
11972 int ignored;
11973 fd_specified("", -1);
11974 follow_symlinks_specified("", 1);
11975 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11976 dir_fd_converter(Py_None, &ignored);
11977 dir_fd_unavailable(Py_None, &ignored);
11978 }
11979
11980 /*
11981 * provide list of locally available functions
11982 * so os.py can populate support_* lists
11983 */
11984 list = PyList_New(0);
11985 if (!list)
11986 return NULL;
11987 for (trace = have_functions; *trace; trace++) {
11988 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11989 if (!unicode)
11990 return NULL;
11991 if (PyList_Append(list, unicode))
11992 return NULL;
11993 Py_DECREF(unicode);
11994 }
11995 PyModule_AddObject(m, "_have_functions", list);
11996
11997 initialized = 1;
11998
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012000
Guido van Rossumb6775db1994-08-01 11:34:53 +000012001}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012002
12003#ifdef __cplusplus
12004}
12005#endif