blob: eb595134daf804be8ad6be92a7ccde0e2ab7fd0c [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
417#define DEFAULT_DIR_FD AT_FDCWD
418#else
419#define DEFAULT_DIR_FD (-100)
420#endif
421
422static int
423_fd_converter(PyObject *o, int *p, int default_value) {
424 long long_value;
425 if (o == Py_None) {
426 *p = default_value;
427 return 1;
428 }
429 if (PyFloat_Check(o)) {
430 PyErr_SetString(PyExc_TypeError,
431 "integer argument expected, got float" );
432 return 0;
433 }
434 long_value = PyLong_AsLong(o);
435 if (long_value == -1 && PyErr_Occurred())
436 return 0;
437 if (long_value > INT_MAX) {
438 PyErr_SetString(PyExc_OverflowError,
439 "signed integer is greater than maximum");
440 return 0;
441 }
442 if (long_value < INT_MIN) {
443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is less than minimum");
445 return 0;
446 }
447 *p = (int)long_value;
448 return 1;
449}
450
451static int
452dir_fd_converter(PyObject *o, void *p) {
453 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
454}
455
456
457
458/*
459 * A PyArg_ParseTuple "converter" function
460 * that handles filesystem paths in the manner
461 * preferred by the os module.
462 *
463 * path_converter accepts (Unicode) strings and their
464 * subclasses, and bytes and their subclasses. What
465 * it does with the argument depends on the platform:
466 *
467 * * On Windows, if we get a (Unicode) string we
468 * extract the wchar_t * and return it; if we get
469 * bytes we extract the char * and return that.
470 *
471 * * On all other platforms, strings are encoded
472 * to bytes using PyUnicode_FSConverter, then we
473 * extract the char * from the bytes object and
474 * return that.
475 *
476 * path_converter also optionally accepts signed
477 * integers (representing open file descriptors) instead
478 * of path strings.
479 *
480 * Input fields:
481 * path.nullable
482 * If nonzero, the path is permitted to be None.
483 * path.allow_fd
484 * If nonzero, the path is permitted to be a file handle
485 * (a signed int) instead of a string.
486 * path.function_name
487 * If non-NULL, path_converter will use that as the name
488 * of the function in error messages.
489 * (If path.argument_name is NULL it omits the function name.)
490 * path.argument_name
491 * If non-NULL, path_converter will use that as the name
492 * of the parameter in error messages.
493 * (If path.argument_name is NULL it uses "path".)
494 *
495 * Output fields:
496 * path.wide
497 * Points to the path if it was expressed as Unicode
498 * and was not encoded. (Only used on Windows.)
499 * path.narrow
500 * Points to the path if it was expressed as bytes,
501 * or it was Unicode and was encoded to bytes.
502 * path.fd
503 * Contains a file descriptor if path.accept_fd was true
504 * and the caller provided a signed integer instead of any
505 * sort of string.
506 *
507 * WARNING: if your "path" parameter is optional, and is
508 * unspecified, path_converter will never get called.
509 * So if you set allow_fd, you *MUST* initialize path.fd = -1
510 * yourself!
511 * path.length
512 * The length of the path in characters, if specified as
513 * a string.
514 * path.object
515 * The original object passed in.
516 * path.cleanup
517 * For internal use only. May point to a temporary object.
518 * (Pay no attention to the man behind the curtain.)
519 *
520 * At most one of path.wide or path.narrow will be non-NULL.
521 * If path was None and path.nullable was set,
522 * or if path was an integer and path.allow_fd was set,
523 * both path.wide and path.narrow will be NULL
524 * and path.length will be 0.
525 *
526 * path_converter takes care to not write to the path_t
527 * unless it's successful. However it must reset the
528 * "cleanup" field each time it's called.
529 *
530 * Use as follows:
531 * path_t path;
532 * memset(&path, 0, sizeof(path));
533 * PyArg_ParseTuple(args, "O&", path_converter, &path);
534 * // ... use values from path ...
535 * path_cleanup(&path);
536 *
537 * (Note that if PyArg_Parse fails you don't need to call
538 * path_cleanup(). However it is safe to do so.)
539 */
540typedef struct {
541 char *function_name;
542 char *argument_name;
543 int nullable;
544 int allow_fd;
545 wchar_t *wide;
546 char *narrow;
547 int fd;
548 Py_ssize_t length;
549 PyObject *object;
550 PyObject *cleanup;
551} path_t;
552
553static void
554path_cleanup(path_t *path) {
555 if (path->cleanup) {
556 Py_DECREF(path->cleanup);
557 path->cleanup = NULL;
558 }
559}
560
561static int
562path_converter(PyObject *o, void *p) {
563 path_t *path = (path_t *)p;
564 PyObject *unicode, *bytes;
565 Py_ssize_t length;
566 char *narrow;
567
568#define FORMAT_EXCEPTION(exc, fmt) \
569 PyErr_Format(exc, "%s%s" fmt, \
570 path->function_name ? path->function_name : "", \
571 path->function_name ? ": " : "", \
572 path->argument_name ? path->argument_name : "path")
573
574 /* Py_CLEANUP_SUPPORTED support */
575 if (o == NULL) {
576 path_cleanup(path);
577 return 1;
578 }
579
580 /* ensure it's always safe to call path_cleanup() */
581 path->cleanup = NULL;
582
583 if (o == Py_None) {
584 if (!path->nullable) {
585 FORMAT_EXCEPTION(PyExc_TypeError,
586 "can't specify None for %s argument");
587 return 0;
588 }
589 path->wide = NULL;
590 path->narrow = NULL;
591 path->length = 0;
592 path->object = o;
593 path->fd = -1;
594 return 1;
595 }
596
597 unicode = PyUnicode_FromObject(o);
598 if (unicode) {
599#ifdef MS_WINDOWS
600 wchar_t *wide;
601 length = PyUnicode_GET_SIZE(unicode);
602 if (length > 32767) {
603 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
604 Py_DECREF(unicode);
605 return 0;
606 }
607
608 wide = PyUnicode_AsUnicode(unicode);
609 if (!wide) {
610 Py_DECREF(unicode);
611 return 0;
612 }
613
614 path->wide = wide;
615 path->narrow = NULL;
616 path->length = length;
617 path->object = o;
618 path->fd = -1;
619 path->cleanup = unicode;
620 return Py_CLEANUP_SUPPORTED;
621#else
622 int converted = PyUnicode_FSConverter(unicode, &bytes);
623 Py_DECREF(unicode);
624 if (!converted)
625 bytes = NULL;
626#endif
627 }
628 else {
629 PyErr_Clear();
630 bytes = PyBytes_FromObject(o);
631 if (!bytes) {
632 PyErr_Clear();
633 if (path->allow_fd) {
634 int fd;
635 /*
636 * note: _fd_converter always permits None.
637 * but we've already done our None check.
638 * so o cannot be None at this point.
639 */
640 int result = _fd_converter(o, &fd, -1);
641 if (result) {
642 path->wide = NULL;
643 path->narrow = NULL;
644 path->length = 0;
645 path->object = o;
646 path->fd = fd;
647 return result;
648 }
649 }
650 }
651 }
652
653 if (!bytes) {
654 if (!PyErr_Occurred())
655 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
656 return 0;
657 }
658
659#ifdef MS_WINDOWS
660 if (win32_warn_bytes_api()) {
661 Py_DECREF(bytes);
662 return 0;
663 }
664#endif
665
666 length = PyBytes_GET_SIZE(bytes);
667#ifdef MS_WINDOWS
668 if (length > MAX_PATH) {
669 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 narrow = PyBytes_AS_STRING(bytes);
676 if (length != strlen(narrow)) {
677 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
678 Py_DECREF(bytes);
679 return 0;
680 }
681
682 path->wide = NULL;
683 path->narrow = narrow;
684 path->length = length;
685 path->object = o;
686 path->fd = -1;
687 path->cleanup = bytes;
688 return Py_CLEANUP_SUPPORTED;
689}
690
691static void
692argument_unavailable_error(char *function_name, char *argument_name) {
693 PyErr_Format(PyExc_NotImplementedError,
694 "%s%s%s unavailable on this platform",
695 (function_name != NULL) ? function_name : "",
696 (function_name != NULL) ? ": ": "",
697 argument_name);
698}
699
700static int
701dir_fd_unavailable(PyObject *o, void *p) {
702 int *dir_fd = (int *)p;
703 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
704 if (!return_value)
705 return 0;
706 if (*dir_fd == DEFAULT_DIR_FD)
707 return 1;
708 argument_unavailable_error(NULL, "dir_fd");
709 return 0;
710}
711
712static int
713fd_specified(char *function_name, int fd) {
714 if (fd == -1)
715 return 0;
716
717 argument_unavailable_error(function_name, "fd");
718 return 1;
719}
720
721static int
722follow_symlinks_specified(char *function_name, int follow_symlinks) {
723 if (follow_symlinks)
724 return 0;
725
726 argument_unavailable_error(function_name, "follow_symlinks");
727 return 1;
728}
729
730static int
731path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
732 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
733 PyErr_Format(PyExc_ValueError,
734 "%s: can't specify dir_fd without matching path",
735 function_name);
736 return 1;
737 }
738 return 0;
739}
740
741static int
742dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify both dir_fd and fd",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753fd_and_follow_symlinks_invalid(char *function_name, int fd,
754 int follow_symlinks) {
755 if ((fd > 0) && (!follow_symlinks)) {
756 PyErr_Format(PyExc_ValueError,
757 "%s: cannot use fd and follow_symlinks together",
758 function_name);
759 return 1;
760 }
761 return 0;
762}
763
764static int
765dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
766 int follow_symlinks) {
767 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
768 PyErr_Format(PyExc_ValueError,
769 "%s: cannot use dir_fd and follow_symlinks together",
770 function_name);
771 return 1;
772 }
773 return 0;
774}
775
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200776/* A helper used by a number of POSIX-only functions */
777#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000778static int
779_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000780{
781#if !defined(HAVE_LARGEFILE_SUPPORT)
782 *((off_t*)addr) = PyLong_AsLong(arg);
783#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000784 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000785#endif
786 if (PyErr_Occurred())
787 return 0;
788 return 1;
789}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200790#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792#if defined _MSC_VER && _MSC_VER >= 1400
793/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
794 * valid and throw an assertion if it isn't.
795 * Normally, an invalid fd is likely to be a C program error and therefore
796 * an assertion can be useful, but it does contradict the POSIX standard
797 * which for write(2) states:
798 * "Otherwise, -1 shall be returned and errno set to indicate the error."
799 * "[EBADF] The fildes argument is not a valid file descriptor open for
800 * writing."
801 * Furthermore, python allows the user to enter any old integer
802 * as a fd and should merely raise a python exception on error.
803 * The Microsoft CRT doesn't provide an official way to check for the
804 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * internal structures involved.
807 * The structures below must be updated for each version of visual studio
808 * according to the file internal.h in the CRT source, until MS comes
809 * up with a less hacky way to do this.
810 * (all of this is to avoid globally modifying the CRT behaviour using
811 * _set_invalid_parameter_handler() and _CrtSetReportMode())
812 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000813/* The actual size of the structure is determined at runtime.
814 * Only the first items must be present.
815 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000816typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000817 intptr_t osfhnd;
818 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000819} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000820
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000821extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000822#define IOINFO_L2E 5
823#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
824#define IOINFO_ARRAYS 64
825#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
826#define FOPEN 0x01
827#define _NO_CONSOLE_FILENO (intptr_t)-2
828
829/* This function emulates what the windows CRT does to validate file handles */
830int
831_PyVerify_fd(int fd)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 const int i1 = fd >> IOINFO_L2E;
834 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000835
Antoine Pitrou22e41552010-08-15 18:07:50 +0000836 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000837
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 /* Determine the actual size of the ioinfo structure,
839 * as used by the CRT loaded in memory
840 */
841 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
842 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
843 }
844 if (sizeof_ioinfo == 0) {
845 /* This should not happen... */
846 goto fail;
847 }
848
849 /* See that it isn't a special CLEAR fileno */
850 if (fd != _NO_CONSOLE_FILENO) {
851 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
852 * we check pointer validity and other info
853 */
854 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
855 /* finally, check that the file is open */
856 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
857 if (info->osfile & FOPEN) {
858 return 1;
859 }
860 }
861 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000862 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 errno = EBADF;
864 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000865}
866
867/* the special case of checking dup2. The target fd must be in a sensible range */
868static int
869_PyVerify_fd_dup2(int fd1, int fd2)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 if (!_PyVerify_fd(fd1))
872 return 0;
873 if (fd2 == _NO_CONSOLE_FILENO)
874 return 0;
875 if ((unsigned)fd2 < _NHANDLE_)
876 return 1;
877 else
878 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000879}
880#else
881/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
882#define _PyVerify_fd_dup2(A, B) (1)
883#endif
884
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000885#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000886/* The following structure was copied from
887 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
888 include doesn't seem to be present in the Windows SDK (at least as included
889 with Visual Studio Express). */
890typedef struct _REPARSE_DATA_BUFFER {
891 ULONG ReparseTag;
892 USHORT ReparseDataLength;
893 USHORT Reserved;
894 union {
895 struct {
896 USHORT SubstituteNameOffset;
897 USHORT SubstituteNameLength;
898 USHORT PrintNameOffset;
899 USHORT PrintNameLength;
900 ULONG Flags;
901 WCHAR PathBuffer[1];
902 } SymbolicLinkReparseBuffer;
903
904 struct {
905 USHORT SubstituteNameOffset;
906 USHORT SubstituteNameLength;
907 USHORT PrintNameOffset;
908 USHORT PrintNameLength;
909 WCHAR PathBuffer[1];
910 } MountPointReparseBuffer;
911
912 struct {
913 UCHAR DataBuffer[1];
914 } GenericReparseBuffer;
915 };
916} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
917
918#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
919 GenericReparseBuffer)
920#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
921
922static int
Brian Curtind25aef52011-06-13 15:16:04 -0500923win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000924{
925 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
926 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
927 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000928
929 if (0 == DeviceIoControl(
930 reparse_point_handle,
931 FSCTL_GET_REPARSE_POINT,
932 NULL, 0, /* in buffer */
933 target_buffer, sizeof(target_buffer),
934 &n_bytes_returned,
935 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500936 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000937
938 if (reparse_tag)
939 *reparse_tag = rdb->ReparseTag;
940
Brian Curtind25aef52011-06-13 15:16:04 -0500941 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000942}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100943
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000944#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000945
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000947#ifdef WITH_NEXT_FRAMEWORK
948/* On Darwin/MacOSX a shared library or framework has no access to
949** environ directly, we must obtain it with _NSGetEnviron().
950*/
951#include <crt_externs.h>
952static char **environ;
953#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000955#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000958convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000963#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000964 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000965#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000966#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 APIRET rc;
968 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
969#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000970
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 d = PyDict_New();
972 if (d == NULL)
973 return NULL;
974#ifdef WITH_NEXT_FRAMEWORK
975 if (environ == NULL)
976 environ = *_NSGetEnviron();
977#endif
978#ifdef MS_WINDOWS
979 /* _wenviron must be initialized in this way if the program is started
980 through main() instead of wmain(). */
981 _wgetenv(L"");
982 if (_wenviron == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = _wenviron; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 wchar_t *p = wcschr(*e, L'=');
989 if (p == NULL)
990 continue;
991 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000995 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
1008 }
1009#else
1010 if (environ == NULL)
1011 return d;
1012 /* This part ignores errors */
1013 for (e = environ; *e != NULL; e++) {
1014 PyObject *k;
1015 PyObject *v;
1016 char *p = strchr(*e, '=');
1017 if (p == NULL)
1018 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001019 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 if (k == NULL) {
1021 PyErr_Clear();
1022 continue;
1023 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001024 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 if (v == NULL) {
1026 PyErr_Clear();
1027 Py_DECREF(k);
1028 continue;
1029 }
1030 if (PyDict_GetItem(d, k) == NULL) {
1031 if (PyDict_SetItem(d, k, v) != 0)
1032 PyErr_Clear();
1033 }
1034 Py_DECREF(k);
1035 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001036 }
1037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001038#if defined(PYOS_OS2)
1039 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1040 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1041 PyObject *v = PyBytes_FromString(buffer);
1042 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1043 Py_DECREF(v);
1044 }
1045 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1046 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1047 PyObject *v = PyBytes_FromString(buffer);
1048 PyDict_SetItemString(d, "ENDLIBPATH", v);
1049 Py_DECREF(v);
1050 }
1051#endif
1052 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055/* Set a POSIX-specific error from errno, and return NULL */
1056
Barry Warsawd58d7641998-07-23 16:14:40 +00001057static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001058posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061}
Barry Warsawd58d7641998-07-23 16:14:40 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001066}
1067
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001068
Mark Hammondef8b6542001-05-13 08:04:26 +00001069static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001070posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001071{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001072 PyObject *name_str, *rc;
1073 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1074 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001076 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1077 name_str);
1078 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001080}
1081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001082#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001083static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001084win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 /* XXX We should pass the function name along in the future.
1087 (winreg.c also wants to pass the function name.)
1088 This would however require an additional param to the
1089 Windows error object, which is non-trivial.
1090 */
1091 errno = GetLastError();
1092 if (filename)
1093 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1094 else
1095 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001097
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001098static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001099win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 /* XXX - see win32_error for comments on 'function' */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107}
1108
Victor Stinnereb5657a2011-09-30 01:44:27 +02001109static PyObject *
1110win32_error_object(char* function, PyObject* filename)
1111{
1112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1116 PyExc_WindowsError,
1117 errno,
1118 filename);
1119 else
1120 return PyErr_SetFromWindowsErr(errno);
1121}
1122
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001123#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125/*
1126 * Some functions return Win32 errors, others only ever use posix_error
1127 * (this is for backwards compatibility with exceptions)
1128 */
1129static PyObject *
1130path_posix_error(char *function_name, path_t *path)
1131{
1132 if (path->narrow)
1133 return posix_error_with_filename(path->narrow);
1134 return posix_error();
1135}
1136
1137static PyObject *
1138path_error(char *function_name, path_t *path)
1139{
1140#ifdef MS_WINDOWS
1141 if (path->narrow)
1142 return win32_error(function_name, path->narrow);
1143 if (path->wide)
1144 return win32_error_unicode(function_name, path->wide);
1145 return win32_error(function_name, NULL);
1146#else
1147 return path_posix_error(function_name, path);
1148#endif
1149}
1150
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151#if defined(PYOS_OS2)
1152/**********************************************************************
1153 * Helper Function to Trim and Format OS/2 Messages
1154 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001155static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001156os2_formatmsg(char *msgbuf, int msglen, char *reason)
1157{
1158 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1159
1160 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1161 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1162
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001163 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001164 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1165 }
1166
1167 /* Add Optional Reason Text */
1168 if (reason) {
1169 strcat(msgbuf, " : ");
1170 strcat(msgbuf, reason);
1171 }
1172}
1173
1174/**********************************************************************
1175 * Decode an OS/2 Operating System Error Code
1176 *
1177 * A convenience function to lookup an OS/2 error code and return a
1178 * text message we can use to raise a Python exception.
1179 *
1180 * Notes:
1181 * The messages for errors returned from the OS/2 kernel reside in
1182 * the file OSO001.MSG in the \OS2 directory hierarchy.
1183 *
1184 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001185static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001186os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1187{
1188 APIRET rc;
1189 ULONG msglen;
1190
1191 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1192 Py_BEGIN_ALLOW_THREADS
1193 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1194 errorcode, "oso001.msg", &msglen);
1195 Py_END_ALLOW_THREADS
1196
1197 if (rc == NO_ERROR)
1198 os2_formatmsg(msgbuf, msglen, reason);
1199 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001200 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001202
1203 return msgbuf;
1204}
1205
1206/* Set an OS/2-specific error and return NULL. OS/2 kernel
1207 errors are not in a global variable e.g. 'errno' nor are
1208 they congruent with posix error numbers. */
1209
Victor Stinner8c62be82010-05-06 00:08:46 +00001210static PyObject *
1211os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001212{
1213 char text[1024];
1214 PyObject *v;
1215
1216 os2_strerror(text, sizeof(text), code, "");
1217
1218 v = Py_BuildValue("(is)", code, text);
1219 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001220 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221 Py_DECREF(v);
1222 }
1223 return NULL; /* Signal to Python that an Exception is Pending */
1224}
1225
1226#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227
1228/* POSIX generic methods */
1229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001231posix_fildes(PyObject *fdobj, int (*func)(int))
1232{
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 int fd;
1234 int res;
1235 fd = PyObject_AsFileDescriptor(fdobj);
1236 if (fd < 0)
1237 return NULL;
1238 if (!_PyVerify_fd(fd))
1239 return posix_error();
1240 Py_BEGIN_ALLOW_THREADS
1241 res = (*func)(fd);
1242 Py_END_ALLOW_THREADS
1243 if (res < 0)
1244 return posix_error();
1245 Py_INCREF(Py_None);
1246 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247}
Guido van Rossum21142a01999-01-08 21:05:37 +00001248
1249static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 PyObject *opath1 = NULL;
1253 char *path1;
1254 int res;
1255 if (!PyArg_ParseTuple(args, format,
1256 PyUnicode_FSConverter, &opath1))
1257 return NULL;
1258 path1 = PyBytes_AsString(opath1);
1259 Py_BEGIN_ALLOW_THREADS
1260 res = (*func)(path1);
1261 Py_END_ALLOW_THREADS
1262 if (res < 0)
1263 return posix_error_with_allocated_filename(opath1);
1264 Py_DECREF(opath1);
1265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001270#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001272win32_1str(PyObject* args, char* func,
1273 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1274 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001277 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001279
Victor Stinnereb5657a2011-09-30 01:44:27 +02001280 if (PyArg_ParseTuple(args, wformat, &uni))
1281 {
1282 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1283 if (wstr == NULL)
1284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 Py_END_ALLOW_THREADS
1288 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 Py_INCREF(Py_None);
1291 return Py_None;
1292 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 PyErr_Clear();
1294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (!PyArg_ParseTuple(args, format, &ansi))
1296 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001297 if (win32_warn_bytes_api())
1298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_BEGIN_ALLOW_THREADS
1300 result = funcA(ansi);
1301 Py_END_ALLOW_THREADS
1302 if (!result)
1303 return win32_error(func, ansi);
1304 Py_INCREF(Py_None);
1305 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306
1307}
1308
1309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char new_path[MAX_PATH+1];
1318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
1323 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
1327 than MAX_PATH. */
1328 assert(result <= MAX_PATH+1);
1329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
1348 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1349 if (!result)
1350 return FALSE;
1351 if (result > MAX_PATH+1) {
1352 new_path = malloc(result * sizeof(wchar_t));
1353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
1359 free(new_path);
1360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
1370 free(new_path);
1371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001383
1384struct win32_stat{
1385 int st_dev;
1386 __int64 st_ino;
1387 unsigned short st_mode;
1388 int st_nlink;
1389 int st_uid;
1390 int st_gid;
1391 int st_rdev;
1392 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001393 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001395 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001396 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001397 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001398 int st_ctime_nsec;
1399};
1400
1401static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1402
1403static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1407 /* Cannot simply cast and dereference in_ptr,
1408 since it might not be aligned properly */
1409 __int64 in;
1410 memcpy(&in, in_ptr, sizeof(in));
1411 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001412 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001413}
1414
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness */
1419 __int64 out;
1420 out = time_in + secs_between_epochs;
1421 out = out * 10000000 + nsec_in / 100;
1422 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423}
1424
Martin v. Löwis14694662006-02-03 12:54:16 +00001425/* Below, we *know* that ugo+r is 0444 */
1426#if _S_IREAD != 0400
1427#error Unsupported C library
1428#endif
1429static int
1430attributes_to_mode(DWORD attr)
1431{
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 int m = 0;
1433 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1434 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1435 else
1436 m |= _S_IFREG;
1437 if (attr & FILE_ATTRIBUTE_READONLY)
1438 m |= 0444;
1439 else
1440 m |= 0666;
1441 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442}
1443
1444static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 memset(result, 0, sizeof(*result));
1448 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1449 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1450 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1451 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1452 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001453 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001454 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1456 /* first clear the S_IFMT bits */
1457 result->st_mode ^= (result->st_mode & 0170000);
1458 /* now set the bits that make this a symlink */
1459 result->st_mode |= 0120000;
1460 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463}
1464
Guido van Rossumd8faa362007-04-27 19:54:29 +00001465static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATAA FileData;
1470 hFindFile = FindFirstFileA(pszFile, &FileData);
1471 if (hFindFile == INVALID_HANDLE_VALUE)
1472 return FALSE;
1473 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001474 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001475 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001476 info->dwFileAttributes = FileData.dwFileAttributes;
1477 info->ftCreationTime = FileData.ftCreationTime;
1478 info->ftLastAccessTime = FileData.ftLastAccessTime;
1479 info->ftLastWriteTime = FileData.ftLastWriteTime;
1480 info->nFileSizeHigh = FileData.nFileSizeHigh;
1481 info->nFileSizeLow = FileData.nFileSizeLow;
1482/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001483 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1484 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486}
1487
1488static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 HANDLE hFindFile;
1492 WIN32_FIND_DATAW FileData;
1493 hFindFile = FindFirstFileW(pszFile, &FileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE)
1495 return FALSE;
1496 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001498 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 info->dwFileAttributes = FileData.dwFileAttributes;
1500 info->ftCreationTime = FileData.ftCreationTime;
1501 info->ftLastAccessTime = FileData.ftLastAccessTime;
1502 info->ftLastWriteTime = FileData.ftLastWriteTime;
1503 info->nFileSizeHigh = FileData.nFileSizeHigh;
1504 info->nFileSizeLow = FileData.nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509}
1510
Brian Curtind25aef52011-06-13 15:16:04 -05001511/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1512static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001513static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1514 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515static int
Brian Curtind25aef52011-06-13 15:16:04 -05001516check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517{
Brian Curtind25aef52011-06-13 15:16:04 -05001518 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001519 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1520 DWORD);
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* only recheck */
1523 if (!has_GetFinalPathNameByHandle)
1524 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001525 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001526 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1527 "GetFinalPathNameByHandleA");
1528 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1529 "GetFinalPathNameByHandleW");
1530 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1531 Py_GetFinalPathNameByHandleW;
1532 }
1533 return has_GetFinalPathNameByHandle;
1534}
1535
1536static BOOL
1537get_target_path(HANDLE hdl, wchar_t **target_path)
1538{
1539 int buf_size, result_length;
1540 wchar_t *buf;
1541
1542 /* We have a good handle to the target, use it to determine
1543 the target path name (then we'll call lstat on it). */
1544 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1545 VOLUME_NAME_DOS);
1546 if(!buf_size)
1547 return FALSE;
1548
1549 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001550 if (!buf) {
1551 SetLastError(ERROR_OUTOFMEMORY);
1552 return FALSE;
1553 }
1554
Brian Curtind25aef52011-06-13 15:16:04 -05001555 result_length = Py_GetFinalPathNameByHandleW(hdl,
1556 buf, buf_size, VOLUME_NAME_DOS);
1557
1558 if(!result_length) {
1559 free(buf);
1560 return FALSE;
1561 }
1562
1563 if(!CloseHandle(hdl)) {
1564 free(buf);
1565 return FALSE;
1566 }
1567
1568 buf[result_length] = 0;
1569
1570 *target_path = buf;
1571 return TRUE;
1572}
1573
1574static int
1575win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1576 BOOL traverse);
1577static int
1578win32_xstat_impl(const char *path, struct win32_stat *result,
1579 BOOL traverse)
1580{
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const char *dot;
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1590 traverse reparse point. */
1591 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 }
1593
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 hFile = CreateFileA(
1595 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 0, /* share mode */
1598 NULL, /* security attributes */
1599 OPEN_EXISTING,
1600 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001601 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1602 Because of this, calls like GetFinalPathNameByHandle will return
1603 the symlink path agin and not the actual final path. */
1604 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1605 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 NULL);
1607
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 /* Either the target doesn't exist, or we don't have access to
1610 get a handle to it. If the former, we need to return an error.
1611 If the latter, we can use attributes_from_dir. */
1612 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileA(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 free(target_path);
1656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = strrchr(path, '.');
1665 if (dot) {
1666 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1667 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Brian Curtind25aef52011-06-13 15:16:04 -05001674win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1675 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
1677 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001678 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 const wchar_t *dot;
1683
Brian Curtind25aef52011-06-13 15:16:04 -05001684 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1686 traverse reparse point. */
1687 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 }
1689
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 hFile = CreateFileW(
1691 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 0, /* share mode */
1694 NULL, /* security attributes */
1695 OPEN_EXISTING,
1696 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1698 Because of this, calls like GetFinalPathNameByHandle will return
1699 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001700 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 NULL);
1703
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 /* Either the target doesn't exist, or we don't have access to
1706 get a handle to it. If the former, we need to return an error.
1707 If the latter, we can use attributes_from_dir. */
1708 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
1739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
1750 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 free(target_path);
1752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779static int
1780win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1781{
1782 /* Protocol violation: we explicitly clear errno, instead of
1783 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001784 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 errno = 0;
1786 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787}
Brian Curtind25aef52011-06-13 15:16:04 -05001788/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001789
1790 In Posix, stat automatically traverses symlinks and returns the stat
1791 structure for the target. In Windows, the equivalent GetFileAttributes by
1792 default does not traverse symlinks and instead returns attributes for
1793 the symlink.
1794
1795 Therefore, win32_lstat will get the attributes traditionally, and
1796 win32_stat will first explicitly resolve the symlink target and then will
1797 call win32_lstat on that result.
1798
Ezio Melotti4969f702011-03-15 05:59:46 +02001799 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001801static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001802win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001803{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001804 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001805}
1806
Victor Stinner8c62be82010-05-06 00:08:46 +00001807static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001808win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001809{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001811}
1812
1813static int
1814win32_stat(const char* path, struct win32_stat *result)
1815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001817}
1818
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_stat_w(const wchar_t* path, struct win32_stat *result)
1821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001823}
1824
1825static int
1826win32_fstat(int file_number, struct win32_stat *result)
1827{
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 BY_HANDLE_FILE_INFORMATION info;
1829 HANDLE h;
1830 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001831
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001833
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
1836 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001837
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 if (h == INVALID_HANDLE_VALUE) {
1839 /* This is really a C library error (invalid file handle).
1840 We set the Win32 error to the closes one matching. */
1841 SetLastError(ERROR_INVALID_HANDLE);
1842 return -1;
1843 }
1844 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 type = GetFileType(h);
1847 if (type == FILE_TYPE_UNKNOWN) {
1848 DWORD error = GetLastError();
1849 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 }
1852 /* else: valid but unknown file */
1853 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (type != FILE_TYPE_DISK) {
1856 if (type == FILE_TYPE_CHAR)
1857 result->st_mode = _S_IFCHR;
1858 else if (type == FILE_TYPE_PIPE)
1859 result->st_mode = _S_IFIFO;
1860 return 0;
1861 }
1862
1863 if (!GetFileInformationByHandle(h, &info)) {
1864 return -1;
1865 }
1866
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1870 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
1873#endif /* MS_WINDOWS */
1874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001876"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001878 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1880\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001881Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1882or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001885
1886static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 {"st_mode", "protection bits"},
1888 {"st_ino", "inode"},
1889 {"st_dev", "device"},
1890 {"st_nlink", "number of hard links"},
1891 {"st_uid", "user ID of owner"},
1892 {"st_gid", "group ID of owner"},
1893 {"st_size", "total size, in bytes"},
1894 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1895 {NULL, "integer time of last access"},
1896 {NULL, "integer time of last modification"},
1897 {NULL, "integer time of last change"},
1898 {"st_atime", "time of last access"},
1899 {"st_mtime", "time of last modification"},
1900 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 {"st_atime_ns", "time of last access in nanoseconds"},
1902 {"st_mtime_ns", "time of last modification in nanoseconds"},
1903 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001904#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001907#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001910#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001913#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001915#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001916#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001918#endif
1919#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923};
1924
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001925#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001926#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001929#endif
1930
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1933#else
1934#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1935#endif
1936
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1939#else
1940#define ST_RDEV_IDX ST_BLOCKS_IDX
1941#endif
1942
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001943#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1944#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1945#else
1946#define ST_FLAGS_IDX ST_RDEV_IDX
1947#endif
1948
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001949#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001950#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001951#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001952#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001953#endif
1954
1955#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1956#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1957#else
1958#define ST_BIRTHTIME_IDX ST_GEN_IDX
1959#endif
1960
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001961static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 "stat_result", /* name */
1963 stat_result__doc__, /* doc */
1964 stat_result_fields,
1965 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001966};
1967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1970This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001972or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001973\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975
1976static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"f_bsize", },
1978 {"f_frsize", },
1979 {"f_blocks", },
1980 {"f_bfree", },
1981 {"f_bavail", },
1982 {"f_files", },
1983 {"f_ffree", },
1984 {"f_favail", },
1985 {"f_flag", },
1986 {"f_namemax",},
1987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
1990static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 "statvfs_result", /* name */
1992 statvfs_result__doc__, /* doc */
1993 statvfs_result_fields,
1994 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995};
1996
Ross Lagerwall7807c352011-03-17 20:20:30 +02001997#if defined(HAVE_WAITID) && !defined(__APPLE__)
1998PyDoc_STRVAR(waitid_result__doc__,
1999"waitid_result: Result from waitid.\n\n\
2000This object may be accessed either as a tuple of\n\
2001 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2002or via the attributes si_pid, si_uid, and so on.\n\
2003\n\
2004See os.waitid for more information.");
2005
2006static PyStructSequence_Field waitid_result_fields[] = {
2007 {"si_pid", },
2008 {"si_uid", },
2009 {"si_signo", },
2010 {"si_status", },
2011 {"si_code", },
2012 {0}
2013};
2014
2015static PyStructSequence_Desc waitid_result_desc = {
2016 "waitid_result", /* name */
2017 waitid_result__doc__, /* doc */
2018 waitid_result_fields,
2019 5
2020};
2021static PyTypeObject WaitidResultType;
2022#endif
2023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002024static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025static PyTypeObject StatResultType;
2026static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002027#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002028static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002029#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002030static newfunc structseq_new;
2031
2032static PyObject *
2033statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyStructSequence *result;
2036 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002037
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 result = (PyStructSequence*)structseq_new(type, args, kwds);
2039 if (!result)
2040 return NULL;
2041 /* If we have been initialized from a tuple,
2042 st_?time might be set to None. Initialize it
2043 from the int slots. */
2044 for (i = 7; i <= 9; i++) {
2045 if (result->ob_item[i+3] == Py_None) {
2046 Py_DECREF(Py_None);
2047 Py_INCREF(result->ob_item[i]);
2048 result->ob_item[i+3] = result->ob_item[i];
2049 }
2050 }
2051 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052}
2053
2054
2055
2056/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002057static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002058
2059PyDoc_STRVAR(stat_float_times__doc__,
2060"stat_float_times([newval]) -> oldval\n\n\
2061Determine whether os.[lf]stat represents time stamps as float objects.\n\
2062If newval is True, future calls to stat() return floats, if it is False,\n\
2063future calls return ints. \n\
2064If newval is omitted, return the current setting.\n");
2065
2066static PyObject*
2067stat_float_times(PyObject* self, PyObject *args)
2068{
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 int newval = -1;
2070 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2071 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002072 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2073 "stat_float_times() is deprecated",
2074 1))
2075 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 if (newval == -1)
2077 /* Return old value */
2078 return PyBool_FromLong(_stat_float_times);
2079 _stat_float_times = newval;
2080 Py_INCREF(Py_None);
2081 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002082}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083
Larry Hastings6fe20b32012-04-19 15:07:49 -07002084static PyObject *billion = NULL;
2085
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002086static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002087fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002088{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002089 PyObject *s = _PyLong_FromTime_t(sec);
2090 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2091 PyObject *s_in_ns = NULL;
2092 PyObject *ns_total = NULL;
2093 PyObject *float_s = NULL;
2094
2095 if (!(s && ns_fractional))
2096 goto exit;
2097
2098 s_in_ns = PyNumber_Multiply(s, billion);
2099 if (!s_in_ns)
2100 goto exit;
2101
2102 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2103 if (!ns_total)
2104 goto exit;
2105
Victor Stinner4195b5c2012-02-08 23:03:19 +01002106 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002107 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2108 if (!float_s)
2109 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002111 else {
2112 float_s = s;
2113 Py_INCREF(float_s);
2114 }
2115
2116 PyStructSequence_SET_ITEM(v, index, s);
2117 PyStructSequence_SET_ITEM(v, index+3, float_s);
2118 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2119 s = NULL;
2120 float_s = NULL;
2121 ns_total = NULL;
2122exit:
2123 Py_XDECREF(s);
2124 Py_XDECREF(ns_fractional);
2125 Py_XDECREF(s_in_ns);
2126 Py_XDECREF(ns_total);
2127 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002128}
2129
Tim Peters5aa91602002-01-30 05:46:57 +00002130/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002131 (used by posix_stat() and posix_fstat()) */
2132static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002133_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 unsigned long ansec, mnsec, cnsec;
2136 PyObject *v = PyStructSequence_New(&StatResultType);
2137 if (v == NULL)
2138 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002139
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002141#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002142 PyStructSequence_SET_ITEM(v, 1,
2143 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002144#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002146#endif
2147#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 PyStructSequence_SET_ITEM(v, 2,
2149 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002156#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, 6,
2158 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002161#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002162
Martin v. Löwis14694662006-02-03 12:54:16 +00002163#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 ansec = st->st_atim.tv_nsec;
2165 mnsec = st->st_mtim.tv_nsec;
2166 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002167#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 ansec = st->st_atimespec.tv_nsec;
2169 mnsec = st->st_mtimespec.tv_nsec;
2170 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002171#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 ansec = st->st_atime_nsec;
2173 mnsec = st->st_mtime_nsec;
2174 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002177#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002178 fill_time(v, 7, st->st_atime, ansec);
2179 fill_time(v, 8, st->st_mtime, mnsec);
2180 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002181
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002182#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2184 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002185#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002186#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2188 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002190#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2192 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002193#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002194#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2196 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002197#endif
2198#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002200 PyObject *val;
2201 unsigned long bsec,bnsec;
2202 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002203#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002204 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002205#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002207#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002208 if (_stat_float_times) {
2209 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2210 } else {
2211 val = PyLong_FromLong((long)bsec);
2212 }
2213 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2214 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002216#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002217#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2219 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002220#endif
Fred Drake699f3522000-06-29 21:12:41 +00002221
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 if (PyErr_Occurred()) {
2223 Py_DECREF(v);
2224 return NULL;
2225 }
Fred Drake699f3522000-06-29 21:12:41 +00002226
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002228}
2229
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002230/* POSIX methods */
2231
Guido van Rossum94f6f721999-01-06 18:42:14 +00002232
2233static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002234posix_do_stat(char *function_name, path_t *path,
2235 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002236{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002237 STRUCT_STAT st;
2238 int result;
2239
2240#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2241 if (follow_symlinks_specified(function_name, follow_symlinks))
2242 return NULL;
2243#endif
2244
2245 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2246 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2247 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2248 return NULL;
2249
2250 Py_BEGIN_ALLOW_THREADS
2251 if (path->fd != -1)
2252 result = FSTAT(path->fd, &st);
2253 else
2254#ifdef MS_WINDOWS
2255 if (path->wide) {
2256 if (follow_symlinks)
2257 result = win32_stat_w(path->wide, &st);
2258 else
2259 result = win32_lstat_w(path->wide, &st);
2260 }
2261 else
2262#endif
2263#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2264 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2265 result = LSTAT(path->narrow, &st);
2266 else
2267#endif
2268#ifdef HAVE_FSTATAT
2269 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2270 result = fstatat(dir_fd, path->narrow, &st,
2271 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2272 else
2273#endif
2274 result = STAT(path->narrow, &st);
2275 Py_END_ALLOW_THREADS
2276
2277 if (result != 0)
2278 return path_error("stat", path);
2279
2280 return _pystat_fromstructstat(&st);
2281}
2282
2283PyDoc_STRVAR(posix_stat__doc__,
2284"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2285Perform a stat system call on the given path.\n\
2286\n\
2287path may be specified as either a string or as an open file descriptor.\n\
2288\n\
2289If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2290 and path should be relative; path will then be relative to that directory.\n\
2291 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2292 it will raise a NotImplementedError.\n\
2293If follow_symlinks is False, and the last element of the path is a symbolic\n\
2294 link, stat will examine the symbolic link itself instead of the file the\n\
2295 link points to.\n\
2296It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2297 an open file descriptor.");
2298
2299static PyObject *
2300posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2301{
2302 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2303 path_t path;
2304 int dir_fd = DEFAULT_DIR_FD;
2305 int follow_symlinks = 1;
2306 PyObject *return_value;
2307
2308 memset(&path, 0, sizeof(path));
2309 path.allow_fd = 1;
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2311 path_converter, &path,
2312#ifdef HAVE_FSTATAT
2313 dir_fd_converter, &dir_fd,
2314#else
2315 dir_fd_unavailable, &dir_fd,
2316#endif
2317 &follow_symlinks))
2318 return NULL;
2319 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2320 path_cleanup(&path);
2321 return return_value;
2322}
2323
2324PyDoc_STRVAR(posix_lstat__doc__,
2325"lstat(path, *, dir_fd=None) -> stat result\n\n\
2326Like stat(), but do not follow symbolic links.\n\
2327Equivalent to stat(path, follow_symlinks=False).");
2328
2329static PyObject *
2330posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2331{
2332 static char *keywords[] = {"path", "dir_fd", NULL};
2333 path_t path;
2334 int dir_fd = DEFAULT_DIR_FD;
2335 int follow_symlinks = 0;
2336 PyObject *return_value;
2337
2338 memset(&path, 0, sizeof(path));
2339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2340 path_converter, &path,
2341#ifdef HAVE_FSTATAT
2342 dir_fd_converter, &dir_fd
2343#else
2344 dir_fd_unavailable, &dir_fd
2345#endif
2346 ))
2347 return NULL;
2348 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2349 path_cleanup(&path);
2350 return return_value;
2351}
2352
2353PyDoc_STRVAR(posix_access__doc__,
2354"access(path, mode, *, dir_fd=None, effective_ids=False,\
2355 follow_symlinks=True)\n\n\
2356Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2357False otherwise.\n\
2358\n\
2359If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2360 and path should be relative; path will then be relative to that directory.\n\
2361If effective_ids is True, access will use the effective uid/gid instead of\n\
2362 the real uid/gid.\n\
2363If follow_symlinks is False, and the last element of the path is a symbolic\n\
2364 link, access will examine the symbolic link itself instead of the file the\n\
2365 link points to.\n\
2366dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2367 on your platform. If they are unavailable, using them will raise a\n\
2368 NotImplementedError.\n\
2369\n\
2370Note that most operations will use the effective uid/gid, therefore this\n\
2371 routine can be used in a suid/sgid environment to test if the invoking user\n\
2372 has the specified access to the path.\n\
2373The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2374 of R_OK, W_OK, and X_OK.");
2375
2376static PyObject *
2377posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2378{
2379 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2380 "follow_symlinks", NULL};
2381 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002382 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002383 int dir_fd = DEFAULT_DIR_FD;
2384 int effective_ids = 0;
2385 int follow_symlinks = 1;
2386 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002387
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002388#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002392#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002393
2394 memset(&path, 0, sizeof(path));
2395 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2396 path_converter, &path, &mode,
2397#ifdef HAVE_FACCESSAT
2398 dir_fd_converter, &dir_fd,
2399#else
2400 dir_fd_unavailable, &dir_fd,
2401#endif
2402 &effective_ids, &follow_symlinks))
2403 return NULL;
2404
2405#ifndef HAVE_FACCESSAT
2406 if (follow_symlinks_specified("access", follow_symlinks))
2407 goto exit;
2408
2409 if (effective_ids) {
2410 argument_unavailable_error("access", "effective_ids");
2411 goto exit;
2412 }
2413#endif
2414
2415#ifdef MS_WINDOWS
2416 Py_BEGIN_ALLOW_THREADS
2417 if (path.wide != NULL)
2418 attr = GetFileAttributesW(path.wide);
2419 else
2420 attr = GetFileAttributesA(path.narrow);
2421 Py_END_ALLOW_THREADS
2422
2423 /*
2424 * Access is possible if
2425 * * we didn't get a -1, and
2426 * * write access wasn't requested,
2427 * * or the file isn't read-only,
2428 * * or it's a directory.
2429 * (Directories cannot be read-only on Windows.)
2430 */
2431 return_value = PyBool_FromLong(
2432 (attr != 0xFFFFFFFF) &&
2433 ((mode & 2) ||
2434 !(attr & FILE_ATTRIBUTE_READONLY) ||
2435 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2436#else
2437
2438 Py_BEGIN_ALLOW_THREADS
2439#ifdef HAVE_FACCESSAT
2440 if ((dir_fd != DEFAULT_DIR_FD) ||
2441 effective_ids ||
2442 !follow_symlinks) {
2443 int flags = 0;
2444 if (!follow_symlinks)
2445 flags |= AT_SYMLINK_NOFOLLOW;
2446 if (effective_ids)
2447 flags |= AT_EACCESS;
2448 result = faccessat(dir_fd, path.narrow, mode, flags);
2449 }
2450 else
2451#endif
2452 result = access(path.narrow, mode);
2453 Py_END_ALLOW_THREADS
2454 return_value = PyBool_FromLong(!result);
2455#endif
2456
2457#ifndef HAVE_FACCESSAT
2458exit:
2459#endif
2460 path_cleanup(&path);
2461 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002462}
2463
Guido van Rossumd371ff11999-01-25 16:12:23 +00002464#ifndef F_OK
2465#define F_OK 0
2466#endif
2467#ifndef R_OK
2468#define R_OK 4
2469#endif
2470#ifndef W_OK
2471#define W_OK 2
2472#endif
2473#ifndef X_OK
2474#define X_OK 1
2475#endif
2476
2477#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484{
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 int id;
2486 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2489 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002491#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002492 /* file descriptor 0 only, the default input device (stdin) */
2493 if (id == 0) {
2494 ret = ttyname();
2495 }
2496 else {
2497 ret = NULL;
2498 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (ret == NULL)
2503 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002504 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002508#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002510"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512
2513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002514posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515{
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 char *ret;
2517 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518
Greg Wardb48bc172000-03-01 21:51:56 +00002519#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (ret == NULL)
2525 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002526 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527}
2528#endif
2529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532Change the current working directory to the specified path.\n\
2533\n\
2534path may always be specified as a string.\n\
2535On some platforms, path may also be specified as an open file descriptor.\n\
2536 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 path_t path;
2542 int result;
2543 PyObject *return_value = NULL;
2544 static char *keywords[] = {"path", NULL};
2545
2546 memset(&path, 0, sizeof(path));
2547#ifdef HAVE_FCHDIR
2548 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2551 path_converter, &path
2552 ))
2553 return NULL;
2554
2555 Py_BEGIN_ALLOW_THREADS
2556#ifdef MS_WINDOWS
2557 if (path.wide)
2558 result = win32_wchdir(path.wide);
2559 else
2560 result = win32_chdir(path.narrow);
2561 result = !result; /* on unix, success = 0, on windows, success = !0 */
2562#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2563 result = _chdir2(path.narrow);
2564#else
2565#ifdef HAVE_FCHDIR
2566 if (path.fd != -1)
2567 result = fchdir(path.fd);
2568 else
2569#endif
2570 result = chdir(path.narrow);
2571#endif
2572 Py_END_ALLOW_THREADS
2573
2574 if (result) {
2575 return_value = path_error("chdir", &path);
2576 goto exit;
2577 }
2578
2579 return_value = Py_None;
2580 Py_INCREF(Py_None);
2581
2582exit:
2583 path_cleanup(&path);
2584 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002585}
2586
Fred Drake4d1e64b2002-04-15 19:40:07 +00002587#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589"fchdir(fd)\n\n\
2590Change to the directory of the given file descriptor. fd must be\n\
2591opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002592
2593static PyObject *
2594posix_fchdir(PyObject *self, PyObject *fdobj)
2595{
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002597}
2598#endif /* HAVE_FCHDIR */
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002601PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2603Change the access permissions of a file.\n\
2604\n\
2605path may always be specified as a string.\n\
2606On some platforms, path may also be specified as an open file descriptor.\n\
2607 If this functionality is unavailable, using it raises an exception.\n\
2608If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2609 and path should be relative; path will then be relative to that directory.\n\
2610If follow_symlinks is False, and the last element of the path is a symbolic\n\
2611 link, chmod will modify the symbolic link itself instead of the file the\n\
2612 link points to.\n\
2613It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2614 an open file descriptor.\n\
2615dir_fd and follow_symlinks may not be implemented on your platform.\n\
2616 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002617
Barry Warsaw53699e91996-12-10 23:23:01 +00002618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 path_t path;
2622 int mode;
2623 int dir_fd = DEFAULT_DIR_FD;
2624 int follow_symlinks = 1;
2625 int result;
2626 PyObject *return_value = NULL;
2627 static char *keywords[] = {"path", "mode", "dir_fd",
2628 "follow_symlinks", NULL};
2629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002630#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002633
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634#ifdef HAVE_FCHMODAT
2635 int fchmodat_nofollow_unsupported = 0;
2636#endif
2637
2638 memset(&path, 0, sizeof(path));
2639#ifdef HAVE_FCHMOD
2640 path.allow_fd = 1;
2641#endif
2642 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2643 path_converter, &path,
2644 &mode,
2645#ifdef HAVE_FCHMODAT
2646 dir_fd_converter, &dir_fd,
2647#else
2648 dir_fd_unavailable, &dir_fd,
2649#endif
2650 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002651 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652
2653#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2654 if (follow_symlinks_specified("chmod", follow_symlinks))
2655 goto exit;
2656#endif
2657
2658#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002659 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 if (path.wide)
2661 attr = GetFileAttributesW(path.wide);
2662 else
2663 attr = GetFileAttributesA(path.narrow);
2664 if (attr == 0xFFFFFFFF)
2665 result = 0;
2666 else {
2667 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 attr &= ~FILE_ATTRIBUTE_READONLY;
2669 else
2670 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 if (path.wide)
2672 result = SetFileAttributesW(path.wide, attr);
2673 else
2674 result = SetFileAttributesA(path.narrow, attr);
2675 }
2676 Py_END_ALLOW_THREADS
2677
2678 if (!result) {
2679 return_value = win32_error_object("chmod", path.object);
2680 goto exit;
2681 }
2682#else /* MS_WINDOWS */
2683 Py_BEGIN_ALLOW_THREADS
2684#ifdef HAVE_FCHMOD
2685 if (path.fd != -1)
2686 result = fchmod(path.fd, mode);
2687 else
2688#endif
2689#ifdef HAVE_LCHMOD
2690 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2691 result = lchmod(path.narrow, mode);
2692 else
2693#endif
2694#ifdef HAVE_FCHMODAT
2695 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2696 /*
2697 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2698 * The documentation specifically shows how to use it,
2699 * and then says it isn't implemented yet. (glibc 2.15)
2700 *
2701 * Once it is supported, os.chmod will automatically
2702 * support dir_fd and follow_symlinks=False. (Hopefully.)
2703 * Until then, we need to be careful what exception we raise.
2704 */
2705 result = fchmodat(dir_fd, path.narrow, mode,
2706 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2707 /*
2708 * But wait! We can't throw the exception without allowing threads,
2709 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2710 */
2711 fchmodat_nofollow_unsupported =
2712 result && (errno == ENOTSUP) && !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002713 }
2714 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002715#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 result = chmod(path.narrow, mode);
2717 Py_END_ALLOW_THREADS
2718
2719 if (result) {
2720#ifdef HAVE_FCHMODAT
2721 if (fchmodat_nofollow_unsupported) {
2722 if (dir_fd != DEFAULT_DIR_FD)
2723 dir_fd_and_follow_symlinks_invalid("chmod",
2724 dir_fd, follow_symlinks);
2725 else
2726 follow_symlinks_specified("chmod", follow_symlinks);
2727 }
2728 else
2729#endif
2730 return_value = path_error("chmod", &path);
2731 goto exit;
2732 }
2733#endif
2734
2735 Py_INCREF(Py_None);
2736 return_value = Py_None;
2737exit:
2738 path_cleanup(&path);
2739 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002740}
2741
Larry Hastings9cf065c2012-06-22 16:30:09 -07002742
Christian Heimes4e30a842007-11-30 22:12:06 +00002743#ifdef HAVE_FCHMOD
2744PyDoc_STRVAR(posix_fchmod__doc__,
2745"fchmod(fd, mode)\n\n\
2746Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002748
2749static PyObject *
2750posix_fchmod(PyObject *self, PyObject *args)
2751{
Victor Stinner8c62be82010-05-06 00:08:46 +00002752 int fd, mode, res;
2753 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2754 return NULL;
2755 Py_BEGIN_ALLOW_THREADS
2756 res = fchmod(fd, mode);
2757 Py_END_ALLOW_THREADS
2758 if (res < 0)
2759 return posix_error();
2760 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002761}
2762#endif /* HAVE_FCHMOD */
2763
2764#ifdef HAVE_LCHMOD
2765PyDoc_STRVAR(posix_lchmod__doc__,
2766"lchmod(path, mode)\n\n\
2767Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768affects the link itself rather than the target.\n\
2769Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002770
2771static PyObject *
2772posix_lchmod(PyObject *self, PyObject *args)
2773{
Victor Stinner8c62be82010-05-06 00:08:46 +00002774 PyObject *opath;
2775 char *path;
2776 int i;
2777 int res;
2778 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2779 &opath, &i))
2780 return NULL;
2781 path = PyBytes_AsString(opath);
2782 Py_BEGIN_ALLOW_THREADS
2783 res = lchmod(path, i);
2784 Py_END_ALLOW_THREADS
2785 if (res < 0)
2786 return posix_error_with_allocated_filename(opath);
2787 Py_DECREF(opath);
2788 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002789}
2790#endif /* HAVE_LCHMOD */
2791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002792
Thomas Wouterscf297e42007-02-23 15:07:44 +00002793#ifdef HAVE_CHFLAGS
2794PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795"chflags(path, flags, *, follow_symlinks=True)\n\n\
2796Set file flags.\n\
2797\n\
2798If follow_symlinks is False, and the last element of the path is a symbolic\n\
2799 link, chflags will change flags on the symbolic link itself instead of the\n\
2800 file the link points to.\n\
2801follow_symlinks may not be implemented on your platform. If it is\n\
2802unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002803
2804static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002806{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809 int follow_symlinks = 1;
2810 int result;
2811 PyObject *return_value;
2812 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2813
2814 memset(&path, 0, sizeof(path));
2815 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2816 path_converter, &path,
2817 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819
2820#ifndef HAVE_LCHFLAGS
2821 if (follow_symlinks_specified("chflags", follow_symlinks))
2822 goto exit;
2823#endif
2824
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826#ifdef HAVE_LCHFLAGS
2827 if (!follow_symlinks)
2828 result = lchflags(path.narrow, flags);
2829 else
2830#endif
2831 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002832 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833
2834 if (result) {
2835 return_value = path_posix_error("chflags", &path);
2836 goto exit;
2837 }
2838
2839 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841
2842exit:
2843 path_cleanup(&path);
2844 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002845}
2846#endif /* HAVE_CHFLAGS */
2847
2848#ifdef HAVE_LCHFLAGS
2849PyDoc_STRVAR(posix_lchflags__doc__,
2850"lchflags(path, flags)\n\n\
2851Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852This function will not follow symbolic links.\n\
2853Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002854
2855static PyObject *
2856posix_lchflags(PyObject *self, PyObject *args)
2857{
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 PyObject *opath;
2859 char *path;
2860 unsigned long flags;
2861 int res;
2862 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2863 PyUnicode_FSConverter, &opath, &flags))
2864 return NULL;
2865 path = PyBytes_AsString(opath);
2866 Py_BEGIN_ALLOW_THREADS
2867 res = lchflags(path, flags);
2868 Py_END_ALLOW_THREADS
2869 if (res < 0)
2870 return posix_error_with_allocated_filename(opath);
2871 Py_DECREF(opath);
2872 Py_INCREF(Py_None);
2873 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002874}
2875#endif /* HAVE_LCHFLAGS */
2876
Martin v. Löwis244edc82001-10-04 22:44:26 +00002877#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002881
2882static PyObject *
2883posix_chroot(PyObject *self, PyObject *args)
2884{
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002886}
2887#endif
2888
Guido van Rossum21142a01999-01-08 21:05:37 +00002889#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002890PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002891"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002892force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002893
2894static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002895posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002896{
Stefan Krah0e803b32010-11-26 16:16:47 +00002897 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002898}
2899#endif /* HAVE_FSYNC */
2900
Ross Lagerwall7807c352011-03-17 20:20:30 +02002901#ifdef HAVE_SYNC
2902PyDoc_STRVAR(posix_sync__doc__,
2903"sync()\n\n\
2904Force write of everything to disk.");
2905
2906static PyObject *
2907posix_sync(PyObject *self, PyObject *noargs)
2908{
2909 Py_BEGIN_ALLOW_THREADS
2910 sync();
2911 Py_END_ALLOW_THREADS
2912 Py_RETURN_NONE;
2913}
2914#endif
2915
Guido van Rossum21142a01999-01-08 21:05:37 +00002916#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002917
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002918#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002919extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2920#endif
2921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002922PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002923"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002924force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002926
2927static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002928posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002929{
Stefan Krah0e803b32010-11-26 16:16:47 +00002930 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002931}
2932#endif /* HAVE_FDATASYNC */
2933
2934
Fredrik Lundh10723342000-07-10 16:38:09 +00002935#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2938Change the owner and group id of path to the numeric uid and gid.\n\
2939\n\
2940path may always be specified as a string.\n\
2941On some platforms, path may also be specified as an open file descriptor.\n\
2942 If this functionality is unavailable, using it raises an exception.\n\
2943If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2944 and path should be relative; path will then be relative to that directory.\n\
2945If follow_symlinks is False, and the last element of the path is a symbolic\n\
2946 link, chown will modify the symbolic link itself instead of the file the\n\
2947 link points to.\n\
2948It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2949 an open file descriptor.\n\
2950dir_fd and follow_symlinks may not be implemented on your platform.\n\
2951 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Barry Warsaw53699e91996-12-10 23:23:01 +00002953static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002954posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002955{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956 path_t path;
2957 long uid_l, gid_l;
2958 uid_t uid;
2959 gid_t gid;
2960 int dir_fd = DEFAULT_DIR_FD;
2961 int follow_symlinks = 1;
2962 int result;
2963 PyObject *return_value = NULL;
2964 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2965 "follow_symlinks", NULL};
2966
2967 memset(&path, 0, sizeof(path));
2968#ifdef HAVE_FCHOWN
2969 path.allow_fd = 1;
2970#endif
2971 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2972 path_converter, &path,
2973 &uid_l, &gid_l,
2974#ifdef HAVE_FCHOWNAT
2975 dir_fd_converter, &dir_fd,
2976#else
2977 dir_fd_unavailable, &dir_fd,
2978#endif
2979 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002981
2982#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2983 if (follow_symlinks_specified("chown", follow_symlinks))
2984 goto exit;
2985#endif
2986 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2987 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2988 goto exit;
2989
2990#ifdef __APPLE__
2991 /*
2992 * This is for Mac OS X 10.3, which doesn't have lchown.
2993 * (But we still have an lchown symbol because of weak-linking.)
2994 * It doesn't have fchownat either. So there's no possibility
2995 * of a graceful failover.
2996 */
2997 if ((!follow_symlinks) && (lchown == NULL)) {
2998 follow_symlinks_specified("chown", follow_symlinks);
2999 goto exit;
3000 }
3001#endif
3002
Victor Stinner8c62be82010-05-06 00:08:46 +00003003 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003004 uid = (uid_t)uid_l;
3005 gid = (uid_t)gid_l;
3006#ifdef HAVE_FCHOWN
3007 if (path.fd != -1)
3008 result = fchown(path.fd, uid, gid);
3009 else
3010#endif
3011#ifdef HAVE_LCHOWN
3012 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3013 result = lchown(path.narrow, uid, gid);
3014 else
3015#endif
3016#ifdef HAVE_FCHOWNAT
3017 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3018 result = fchownat(dir_fd, path.narrow, uid, gid,
3019 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3020 else
3021#endif
3022 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024
3025 if (result) {
3026 return_value = path_posix_error("chown", &path);
3027 goto exit;
3028 }
3029
3030 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003031 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003032
3033exit:
3034 path_cleanup(&path);
3035 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003036}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003037#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003038
Christian Heimes4e30a842007-11-30 22:12:06 +00003039#ifdef HAVE_FCHOWN
3040PyDoc_STRVAR(posix_fchown__doc__,
3041"fchown(fd, uid, gid)\n\n\
3042Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003044
3045static PyObject *
3046posix_fchown(PyObject *self, PyObject *args)
3047{
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 int fd;
3049 long uid, gid;
3050 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003051 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003052 return NULL;
3053 Py_BEGIN_ALLOW_THREADS
3054 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3055 Py_END_ALLOW_THREADS
3056 if (res < 0)
3057 return posix_error();
3058 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003059}
3060#endif /* HAVE_FCHOWN */
3061
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003062#ifdef HAVE_LCHOWN
3063PyDoc_STRVAR(posix_lchown__doc__,
3064"lchown(path, uid, gid)\n\n\
3065Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003066This function will not follow symbolic links.\n\
3067Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003068
3069static PyObject *
3070posix_lchown(PyObject *self, PyObject *args)
3071{
Victor Stinner8c62be82010-05-06 00:08:46 +00003072 PyObject *opath;
3073 char *path;
3074 long uid, gid;
3075 int res;
3076 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3077 PyUnicode_FSConverter, &opath,
3078 &uid, &gid))
3079 return NULL;
3080 path = PyBytes_AsString(opath);
3081 Py_BEGIN_ALLOW_THREADS
3082 res = lchown(path, (uid_t) uid, (gid_t) gid);
3083 Py_END_ALLOW_THREADS
3084 if (res < 0)
3085 return posix_error_with_allocated_filename(opath);
3086 Py_DECREF(opath);
3087 Py_INCREF(Py_None);
3088 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003089}
3090#endif /* HAVE_LCHOWN */
3091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003092
Guido van Rossum36bc6801995-06-14 22:54:23 +00003093#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003094static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003095posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003096{
Victor Stinner8c62be82010-05-06 00:08:46 +00003097 char buf[1026];
3098 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003099
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003100#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003101 if (!use_bytes) {
3102 wchar_t wbuf[1026];
3103 wchar_t *wbuf2 = wbuf;
3104 PyObject *resobj;
3105 DWORD len;
3106 Py_BEGIN_ALLOW_THREADS
3107 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3108 /* If the buffer is large enough, len does not include the
3109 terminating \0. If the buffer is too small, len includes
3110 the space needed for the terminator. */
3111 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3112 wbuf2 = malloc(len * sizeof(wchar_t));
3113 if (wbuf2)
3114 len = GetCurrentDirectoryW(len, wbuf2);
3115 }
3116 Py_END_ALLOW_THREADS
3117 if (!wbuf2) {
3118 PyErr_NoMemory();
3119 return NULL;
3120 }
3121 if (!len) {
3122 if (wbuf2 != wbuf) free(wbuf2);
3123 return win32_error("getcwdu", NULL);
3124 }
3125 resobj = PyUnicode_FromWideChar(wbuf2, len);
3126 if (wbuf2 != wbuf) free(wbuf2);
3127 return resobj;
3128 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003129
3130 if (win32_warn_bytes_api())
3131 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003132#endif
3133
Victor Stinner8c62be82010-05-06 00:08:46 +00003134 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003136 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003137#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003138 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003139#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003140 Py_END_ALLOW_THREADS
3141 if (res == NULL)
3142 return posix_error();
3143 if (use_bytes)
3144 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003145 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003146}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003147
3148PyDoc_STRVAR(posix_getcwd__doc__,
3149"getcwd() -> path\n\n\
3150Return a unicode string representing the current working directory.");
3151
3152static PyObject *
3153posix_getcwd_unicode(PyObject *self)
3154{
3155 return posix_getcwd(0);
3156}
3157
3158PyDoc_STRVAR(posix_getcwdb__doc__,
3159"getcwdb() -> path\n\n\
3160Return a bytes string representing the current working directory.");
3161
3162static PyObject *
3163posix_getcwd_bytes(PyObject *self)
3164{
3165 return posix_getcwd(1);
3166}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003167#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003168
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3170#define HAVE_LINK 1
3171#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003172
Guido van Rossumb6775db1994-08-01 11:34:53 +00003173#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003174PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3176Create a hard link to a file.\n\
3177\n\
3178If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3179 descriptor open to a directory, and the respective path string (src or dst)\n\
3180 should be relative; the path will then be relative to that directory.\n\
3181If follow_symlinks is False, and the last element of src is a symbolic\n\
3182 link, link will create a link to the symbolic link itself instead of the\n\
3183 file the link points to.\n\
3184src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3185 platform. If they are unavailable, using them will raise a\n\
3186 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003187
Barry Warsaw53699e91996-12-10 23:23:01 +00003188static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003190{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191 path_t src, dst;
3192 int src_dir_fd = DEFAULT_DIR_FD;
3193 int dst_dir_fd = DEFAULT_DIR_FD;
3194 int follow_symlinks = 1;
3195 PyObject *return_value = NULL;
3196 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3197 "follow_symlinks", NULL};
3198#ifdef MS_WINDOWS
3199 BOOL result;
3200#else
3201 int result;
3202#endif
3203
3204 memset(&src, 0, sizeof(src));
3205 memset(&dst, 0, sizeof(dst));
3206 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3207 path_converter, &src,
3208 path_converter, &dst,
3209 dir_fd_converter, &src_dir_fd,
3210 dir_fd_converter, &dst_dir_fd,
3211 &follow_symlinks))
3212 return NULL;
3213
3214#ifndef HAVE_LINKAT
3215 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3216 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3217 goto exit;
3218 }
3219#endif
3220
3221 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3222 PyErr_SetString(PyExc_NotImplementedError,
3223 "link: src and dst must be the same type");
3224 goto exit;
3225 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003226
Brian Curtin1b9df392010-11-24 20:24:31 +00003227#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003228 Py_BEGIN_ALLOW_THREADS
3229 if (src.wide)
3230 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3231 else
3232 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3233 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003234
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 if (!result) {
3236 return_value = win32_error_object("link", dst.object);
3237 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003238 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239#else
3240 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003241#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3243 (dst_dir_fd != DEFAULT_DIR_FD) ||
3244 (!follow_symlinks))
3245 result = linkat(src_dir_fd, src.narrow,
3246 dst_dir_fd, dst.narrow,
3247 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3248 else
3249#endif
3250 result = link(src.narrow, dst.narrow);
3251 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003252
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253 if (result) {
3254 return_value = path_error("link", &dst);
3255 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003256 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257#endif
3258
3259 return_value = Py_None;
3260 Py_INCREF(Py_None);
3261
3262exit:
3263 path_cleanup(&src);
3264 path_cleanup(&dst);
3265 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003266}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267#endif
3268
Brian Curtin1b9df392010-11-24 20:24:31 +00003269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003271PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272"listdir(path='.') -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273Return a list containing the names of the entries in the directory.\n\
3274\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003275The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003276entries '.' and '..' even if they are present in the directory.\n\
3277\n\
3278path can always be specified as a string.\n\
3279On some platforms, path may also be specified as an open file descriptor.\n\
3280 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003281
Barry Warsaw53699e91996-12-10 23:23:01 +00003282static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003284{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 path_t path;
3286 PyObject *list = NULL;
3287 static char *keywords[] = {"path", NULL};
3288 int fd = -1;
3289
3290#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3291 PyObject *v;
3292 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3293 BOOL result;
3294 WIN32_FIND_DATA FileData;
3295 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3296 char *bufptr = namebuf;
3297 /* only claim to have space for MAX_PATH */
3298 Py_ssize_t len = sizeof(namebuf)-5;
3299 PyObject *po = NULL;
3300 wchar_t *wnamebuf = NULL;
3301#elif defined(PYOS_OS2)
3302#ifndef MAX_PATH
3303#define MAX_PATH CCHMAXPATH
3304#endif
3305 char *pt;
3306 PyObject *v;
3307 char namebuf[MAX_PATH+5];
3308 HDIR hdir = 1;
3309 ULONG srchcnt = 1;
3310 FILEFINDBUF3 ep;
3311 APIRET rc;
3312#else
3313 PyObject *v;
3314 DIR *dirp = NULL;
3315 struct dirent *ep;
3316 int arg_is_unicode = 1;
3317#endif
3318
3319 memset(&path, 0, sizeof(path));
3320 path.nullable = 1;
3321#ifdef HAVE_FDOPENDIR
3322 path.allow_fd = 1;
3323 path.fd = -1;
3324#endif
3325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3326 path_converter, &path
3327 ))
3328 return NULL;
3329
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 /* XXX Should redo this putting the (now four) versions of opendir
3331 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003332#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003336
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003338 po_wchars = L".";
3339 len = 1;
3340 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341 po_wchars = path.wide;
3342 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003343 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3346 if (!wnamebuf) {
3347 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003350 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003352 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 if (wch != L'/' && wch != L'\\' && wch != L':')
3354 wnamebuf[len++] = L'\\';
3355 wcscpy(wnamebuf + len, L"*.*");
3356 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 if ((list = PyList_New(0)) == NULL) {
3358 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003360 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003362 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 if (hFindFile == INVALID_HANDLE_VALUE) {
3364 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003365 if (error == ERROR_FILE_NOT_FOUND)
3366 goto exit;
3367 Py_DECREF(list);
3368 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003370 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 }
3372 do {
3373 /* Skip over . and .. */
3374 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3375 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376 v = PyUnicode_FromWideChar(wFileData.cFileName,
3377 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 Py_DECREF(list);
3380 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 break;
3382 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 Py_DECREF(list);
3386 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003387 break;
3388 }
3389 Py_DECREF(v);
3390 }
3391 Py_BEGIN_ALLOW_THREADS
3392 result = FindNextFileW(hFindFile, &wFileData);
3393 Py_END_ALLOW_THREADS
3394 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3395 it got to the end of the directory. */
3396 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003397 Py_DECREF(list);
3398 list = win32_error_unicode("FindNextFileW", wnamebuf);
3399 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 }
3401 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003402
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405 strcpy(namebuf, path.narrow);
3406 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 if (len > 0) {
3408 char ch = namebuf[len-1];
3409 if (ch != SEP && ch != ALTSEP && ch != ':')
3410 namebuf[len++] = '/';
3411 strcpy(namebuf + len, "*.*");
3412 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003413
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416
Antoine Pitroub73caab2010-08-09 23:39:31 +00003417 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003419 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 if (hFindFile == INVALID_HANDLE_VALUE) {
3421 int error = GetLastError();
3422 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 goto exit;
3424 Py_DECREF(list);
3425 list = win32_error("FindFirstFile", namebuf);
3426 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 }
3428 do {
3429 /* Skip over . and .. */
3430 if (strcmp(FileData.cFileName, ".") != 0 &&
3431 strcmp(FileData.cFileName, "..") != 0) {
3432 v = PyBytes_FromString(FileData.cFileName);
3433 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_DECREF(list);
3435 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 break;
3437 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 Py_DECREF(list);
3441 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 break;
3443 }
3444 Py_DECREF(v);
3445 }
3446 Py_BEGIN_ALLOW_THREADS
3447 result = FindNextFile(hFindFile, &FileData);
3448 Py_END_ALLOW_THREADS
3449 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3450 it got to the end of the directory. */
3451 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 Py_DECREF(list);
3453 list = win32_error("FindNextFile", namebuf);
3454 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 }
3456 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003457
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458exit:
3459 if (hFindFile != INVALID_HANDLE_VALUE) {
3460 if (FindClose(hFindFile) == FALSE) {
3461 if (list != NULL) {
3462 Py_DECREF(list);
3463 list = win32_error_object("FindClose", path.object);
3464 }
3465 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 if (wnamebuf)
3468 free(wnamebuf);
3469 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003470
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003472
Tim Peters0bb44a42000-09-15 07:44:49 +00003473#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003475 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003477 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003479 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003480 if (*pt == ALTSEP)
3481 *pt = SEP;
3482 if (namebuf[len-1] != SEP)
3483 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003484 strcpy(namebuf + len, "*.*");
3485
Larry Hastings9cf065c2012-06-22 16:30:09 -07003486 if ((list = PyList_New(0)) == NULL) {
3487 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003488 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003489
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003490 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3491 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003493 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3494 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3495 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003496
3497 if (rc != NO_ERROR) {
3498 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 Py_DECREF(list);
3500 list = posix_error_with_filename(path.narrow);
3501 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003502 }
3503
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003504 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505 do {
3506 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003507 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003508 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
3510 strcpy(namebuf, ep.achName);
3511
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003512 /* Leave Case of Name Alone -- In Native Form */
3513 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003514
Christian Heimes72b710a2008-05-26 13:28:38 +00003515 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003516 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003517 Py_DECREF(list);
3518 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519 break;
3520 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 Py_DECREF(list);
3524 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525 break;
3526 }
3527 Py_DECREF(v);
3528 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3529 }
3530
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531exit:
3532 path_cleanup(&path);
3533
3534 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003535#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003536
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003538 /* v is never read, so it does not need to be initialized yet. */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 if (path.narrow && !PyArg_ParseTuple(args, "U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 arg_is_unicode = 0;
3541 PyErr_Clear();
3542 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543#ifdef HAVE_FDOPENDIR
3544 if (path.fd != -1) {
3545 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003546 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003548 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549
3550 if (fd == -1) {
3551 list = posix_error();
3552 goto exit;
3553 }
3554
3555 Py_BEGIN_ALLOW_THREADS
3556 dirp = fdopendir(fd);
3557 Py_END_ALLOW_THREADS
3558 }
3559 else
3560#endif
3561 {
3562 char *name = path.narrow ? path.narrow : ".";
3563 Py_BEGIN_ALLOW_THREADS
3564 dirp = opendir(name);
3565 Py_END_ALLOW_THREADS
3566 }
3567
3568 if (dirp == NULL) {
3569 list = path_error("listdir", &path);
3570 goto exit;
3571 }
3572 if ((list = PyList_New(0)) == NULL) {
3573 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 }
3575 for (;;) {
3576 errno = 0;
3577 Py_BEGIN_ALLOW_THREADS
3578 ep = readdir(dirp);
3579 Py_END_ALLOW_THREADS
3580 if (ep == NULL) {
3581 if (errno == 0) {
3582 break;
3583 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 Py_DECREF(list);
3585 list = path_error("listdir", &path);
3586 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 }
3588 }
3589 if (ep->d_name[0] == '.' &&
3590 (NAMLEN(ep) == 1 ||
3591 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3592 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00003593 if (arg_is_unicode)
3594 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3595 else
3596 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 break;
3600 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 break;
3605 }
3606 Py_DECREF(v);
3607 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609exit:
3610 if (dirp != NULL) {
3611 Py_BEGIN_ALLOW_THREADS
3612 if (fd > -1)
3613 rewinddir(dirp);
3614 closedir(dirp);
3615 Py_END_ALLOW_THREADS
3616 }
3617
3618 path_cleanup(&path);
3619
3620 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003621
Tim Peters0bb44a42000-09-15 07:44:49 +00003622#endif /* which OS */
3623} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003624
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003625#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003626/* A helper function for abspath on win32 */
3627static PyObject *
3628posix__getfullpathname(PyObject *self, PyObject *args)
3629{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003630 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 char outbuf[MAX_PATH*2];
3632 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003633 PyObject *po;
3634
3635 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3636 {
3637 wchar_t *wpath;
3638 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3639 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 DWORD result;
3641 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003642
3643 wpath = PyUnicode_AsUnicode(po);
3644 if (wpath == NULL)
3645 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003647 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003649 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003650 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 if (!woutbufp)
3652 return PyErr_NoMemory();
3653 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3654 }
3655 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003656 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003658 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003659 if (woutbufp != woutbuf)
3660 free(woutbufp);
3661 return v;
3662 }
3663 /* Drop the argument parsing error as narrow strings
3664 are also valid. */
3665 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003666
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003667 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3668 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003670 if (win32_warn_bytes_api())
3671 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003672 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 outbuf, &temp)) {
3674 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 return NULL;
3676 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3678 return PyUnicode_Decode(outbuf, strlen(outbuf),
3679 Py_FileSystemDefaultEncoding, NULL);
3680 }
3681 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003682} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003683
Brian Curtind25aef52011-06-13 15:16:04 -05003684
Brian Curtinf5e76d02010-11-24 13:14:05 +00003685
Brian Curtind40e6f72010-07-08 21:39:08 +00003686/* A helper function for samepath on windows */
3687static PyObject *
3688posix__getfinalpathname(PyObject *self, PyObject *args)
3689{
3690 HANDLE hFile;
3691 int buf_size;
3692 wchar_t *target_path;
3693 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003694 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003695 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003696
Victor Stinnereb5657a2011-09-30 01:44:27 +02003697 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003698 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003699 path = PyUnicode_AsUnicode(po);
3700 if (path == NULL)
3701 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003702
3703 if(!check_GetFinalPathNameByHandle()) {
3704 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3705 NotImplementedError. */
3706 return PyErr_Format(PyExc_NotImplementedError,
3707 "GetFinalPathNameByHandle not available on this platform");
3708 }
3709
3710 hFile = CreateFileW(
3711 path,
3712 0, /* desired access */
3713 0, /* share mode */
3714 NULL, /* security attributes */
3715 OPEN_EXISTING,
3716 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3717 FILE_FLAG_BACKUP_SEMANTICS,
3718 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003719
Victor Stinnereb5657a2011-09-30 01:44:27 +02003720 if(hFile == INVALID_HANDLE_VALUE)
3721 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003722
3723 /* We have a good handle to the target, use it to determine the
3724 target path name. */
3725 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3726
3727 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003728 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003729
3730 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3731 if(!target_path)
3732 return PyErr_NoMemory();
3733
3734 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3735 buf_size, VOLUME_NAME_DOS);
3736 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003737 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003738
3739 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
3742 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003743 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 free(target_path);
3745 return result;
3746
3747} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003748
3749static PyObject *
3750posix__getfileinformation(PyObject *self, PyObject *args)
3751{
3752 HANDLE hFile;
3753 BY_HANDLE_FILE_INFORMATION info;
3754 int fd;
3755
3756 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3757 return NULL;
3758
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003759 if (!_PyVerify_fd(fd))
3760 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003761
3762 hFile = (HANDLE)_get_osfhandle(fd);
3763 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003764 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003765
3766 if (!GetFileInformationByHandle(hFile, &info))
3767 return win32_error("_getfileinformation", NULL);
3768
3769 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3770 info.nFileIndexHigh,
3771 info.nFileIndexLow);
3772}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003773
Brian Curtin95d028f2011-06-09 09:10:38 -05003774PyDoc_STRVAR(posix__isdir__doc__,
3775"Return true if the pathname refers to an existing directory.");
3776
Brian Curtin9c669cc2011-06-08 18:17:18 -05003777static PyObject *
3778posix__isdir(PyObject *self, PyObject *args)
3779{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003780 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003781 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003782 DWORD attributes;
3783
3784 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003785 wchar_t *wpath = PyUnicode_AsUnicode(po);
3786 if (wpath == NULL)
3787 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003788
3789 attributes = GetFileAttributesW(wpath);
3790 if (attributes == INVALID_FILE_ATTRIBUTES)
3791 Py_RETURN_FALSE;
3792 goto check;
3793 }
3794 /* Drop the argument parsing error as narrow strings
3795 are also valid. */
3796 PyErr_Clear();
3797
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003798 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003799 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003800 if (win32_warn_bytes_api())
3801 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003802 attributes = GetFileAttributesA(path);
3803 if (attributes == INVALID_FILE_ATTRIBUTES)
3804 Py_RETURN_FALSE;
3805
3806check:
3807 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3808 Py_RETURN_TRUE;
3809 else
3810 Py_RETURN_FALSE;
3811}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003812#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003813
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003814PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003815"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3816Create a directory.\n\
3817\n\
3818If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3819 and path should be relative; path will then be relative to that directory.\n\
3820dir_fd may not be implemented on your platform.\n\
3821 If it is unavailable, using it will raise a NotImplementedError.\n\
3822\n\
3823The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003824
Barry Warsaw53699e91996-12-10 23:23:01 +00003825static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003826posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003827{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003828 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830 int dir_fd = DEFAULT_DIR_FD;
3831 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3832 PyObject *return_value = NULL;
3833 int result;
3834
3835 memset(&path, 0, sizeof(path));
3836 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3837 path_converter, &path, &mode,
3838#ifdef HAVE_MKDIRAT
3839 dir_fd_converter, &dir_fd
3840#else
3841 dir_fd_unavailable, &dir_fd
3842#endif
3843 ))
3844 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003845
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003846#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003848 if (path.wide)
3849 result = CreateDirectoryW(path.wide, NULL);
3850 else
3851 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003853
Larry Hastings9cf065c2012-06-22 16:30:09 -07003854 if (!result) {
3855 return_value = win32_error_object("mkdir", path.object);
3856 goto exit;
3857 }
3858#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003860#if HAVE_MKDIRAT
3861 if (dir_fd != DEFAULT_DIR_FD)
3862 result = mkdirat(dir_fd, path.narrow, mode);
3863 else
3864#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003865#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003866 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003867#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003868 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003869#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 if (result < 0) {
3872 return_value = path_error("mkdir", &path);
3873 goto exit;
3874 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003875#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003876 return_value = Py_None;
3877 Py_INCREF(Py_None);
3878exit:
3879 path_cleanup(&path);
3880 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003881}
3882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003884/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3885#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003886#include <sys/resource.h>
3887#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003888
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003889
3890#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003892"nice(inc) -> new_priority\n\n\
3893Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003894
Barry Warsaw53699e91996-12-10 23:23:01 +00003895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003896posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003897{
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003899
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3901 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003902
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 /* There are two flavours of 'nice': one that returns the new
3904 priority (as required by almost all standards out there) and the
3905 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3906 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003907
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 If we are of the nice family that returns the new priority, we
3909 need to clear errno before the call, and check if errno is filled
3910 before calling posix_error() on a returnvalue of -1, because the
3911 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003912
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 errno = 0;
3914 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003915#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 if (value == 0)
3917 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 if (value == -1 && errno != 0)
3920 /* either nice() or getpriority() returned an error */
3921 return posix_error();
3922 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003923}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003924#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003925
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003926
3927#ifdef HAVE_GETPRIORITY
3928PyDoc_STRVAR(posix_getpriority__doc__,
3929"getpriority(which, who) -> current_priority\n\n\
3930Get program scheduling priority.");
3931
3932static PyObject *
3933posix_getpriority(PyObject *self, PyObject *args)
3934{
3935 int which, who, retval;
3936
3937 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3938 return NULL;
3939 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003940 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003941 if (errno != 0)
3942 return posix_error();
3943 return PyLong_FromLong((long)retval);
3944}
3945#endif /* HAVE_GETPRIORITY */
3946
3947
3948#ifdef HAVE_SETPRIORITY
3949PyDoc_STRVAR(posix_setpriority__doc__,
3950"setpriority(which, who, prio) -> None\n\n\
3951Set program scheduling priority.");
3952
3953static PyObject *
3954posix_setpriority(PyObject *self, PyObject *args)
3955{
3956 int which, who, prio, retval;
3957
3958 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3959 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003960 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003961 if (retval == -1)
3962 return posix_error();
3963 Py_RETURN_NONE;
3964}
3965#endif /* HAVE_SETPRIORITY */
3966
3967
Barry Warsaw53699e91996-12-10 23:23:01 +00003968static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003970{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003971 char *function_name = is_replace ? "replace" : "rename";
3972 path_t src;
3973 path_t dst;
3974 int src_dir_fd = DEFAULT_DIR_FD;
3975 int dst_dir_fd = DEFAULT_DIR_FD;
3976 int dir_fd_specified;
3977 PyObject *return_value = NULL;
3978 char format[24];
3979 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3980
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003981#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003982 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003983 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003986#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987
3988 memset(&src, 0, sizeof(src));
3989 memset(&dst, 0, sizeof(dst));
3990 strcpy(format, "O&O&|$O&O&:");
3991 strcat(format, function_name);
3992 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3993 path_converter, &src,
3994 path_converter, &dst,
3995 dir_fd_converter, &src_dir_fd,
3996 dir_fd_converter, &dst_dir_fd))
3997 return NULL;
3998
3999 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4000 (dst_dir_fd != DEFAULT_DIR_FD);
4001#ifndef HAVE_RENAMEAT
4002 if (dir_fd_specified) {
4003 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4004 goto exit;
4005 }
4006#endif
4007
4008 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4009 PyErr_Format(PyExc_ValueError,
4010 "%s: src and dst must be the same type", function_name);
4011 goto exit;
4012 }
4013
4014#ifdef MS_WINDOWS
4015 Py_BEGIN_ALLOW_THREADS
4016 if (src.wide)
4017 result = MoveFileExW(src.wide, dst.wide, flags);
4018 else
4019 result = MoveFileExA(src.narrow, dst.narrow, flags);
4020 Py_END_ALLOW_THREADS
4021
4022 if (!result) {
4023 return_value = win32_error_object(function_name, dst.object);
4024 goto exit;
4025 }
4026
4027#else
4028 Py_BEGIN_ALLOW_THREADS
4029#ifdef HAVE_RENAMEAT
4030 if (dir_fd_specified)
4031 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4032 else
4033#endif
4034 result = rename(src.narrow, dst.narrow);
4035 Py_END_ALLOW_THREADS
4036
4037 if (result) {
4038 return_value = path_error(function_name, &dst);
4039 goto exit;
4040 }
4041#endif
4042
4043 Py_INCREF(Py_None);
4044 return_value = Py_None;
4045exit:
4046 path_cleanup(&src);
4047 path_cleanup(&dst);
4048 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004049}
4050
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004051PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4053Rename a file or directory.\n\
4054\n\
4055If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4056 descriptor open to a directory, and the respective path string (src or dst)\n\
4057 should be relative; the path will then be relative to that directory.\n\
4058src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4059 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004060
4061static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004062posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004063{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004065}
4066
4067PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004068"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4069Rename a file or directory, overwriting the destination.\n\
4070\n\
4071If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4072 descriptor open to a directory, and the respective path string (src or dst)\n\
4073 should be relative; the path will then be relative to that directory.\n\
4074src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4075 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004076
4077static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004079{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004081}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004083PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004084"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004086
Barry Warsaw53699e91996-12-10 23:23:01 +00004087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004088posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004089{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004090#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004092#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004094#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004095}
4096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004098#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004100"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004104posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004105{
Victor Stinner8c62be82010-05-06 00:08:46 +00004106 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004108 wchar_t *command;
4109 if (!PyArg_ParseTuple(args, "u:system", &command))
4110 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004111
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 Py_BEGIN_ALLOW_THREADS
4113 sts = _wsystem(command);
4114 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004115#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004116 PyObject *command_obj;
4117 char *command;
4118 if (!PyArg_ParseTuple(args, "O&:system",
4119 PyUnicode_FSConverter, &command_obj))
4120 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004121
Victor Stinner8c62be82010-05-06 00:08:46 +00004122 command = PyBytes_AsString(command_obj);
4123 Py_BEGIN_ALLOW_THREADS
4124 sts = system(command);
4125 Py_END_ALLOW_THREADS
4126 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004127#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004129}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004130#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004134"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004136
Barry Warsaw53699e91996-12-10 23:23:01 +00004137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004138posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004139{
Victor Stinner8c62be82010-05-06 00:08:46 +00004140 int i;
4141 if (!PyArg_ParseTuple(args, "i:umask", &i))
4142 return NULL;
4143 i = (int)umask(i);
4144 if (i < 0)
4145 return posix_error();
4146 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004147}
4148
Brian Curtind40e6f72010-07-08 21:39:08 +00004149#ifdef MS_WINDOWS
4150
4151/* override the default DeleteFileW behavior so that directory
4152symlinks can be removed with this function, the same as with
4153Unix symlinks */
4154BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4155{
4156 WIN32_FILE_ATTRIBUTE_DATA info;
4157 WIN32_FIND_DATAW find_data;
4158 HANDLE find_data_handle;
4159 int is_directory = 0;
4160 int is_link = 0;
4161
4162 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4163 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004164
Brian Curtind40e6f72010-07-08 21:39:08 +00004165 /* Get WIN32_FIND_DATA structure for the path to determine if
4166 it is a symlink */
4167 if(is_directory &&
4168 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4169 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4170
4171 if(find_data_handle != INVALID_HANDLE_VALUE) {
4172 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4173 FindClose(find_data_handle);
4174 }
4175 }
4176 }
4177
4178 if (is_directory && is_link)
4179 return RemoveDirectoryW(lpFileName);
4180
4181 return DeleteFileW(lpFileName);
4182}
4183#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004185PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004186"unlink(path, *, dir_fd=None, rmdir=False)\n\n\
4187Remove a file (same as remove()).\n\
4188\n\
4189If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4190 and path should be relative; path will then be relative to that directory.\n\
4191dir_fd may not be implemented on your platform.\n\
4192 If it is unavailable, using it will raise a NotImplementedError.\n\
4193If rmdir is True, unlink will behave like os.rmdir().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195PyDoc_STRVAR(posix_remove__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004196"remove(path, *, dir_fd=None, rmdir=False)\n\n\
4197Remove a file (same as unlink()).\n\
4198\n\
4199If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4200 and path should be relative; path will then be relative to that directory.\n\
4201dir_fd may not be implemented on your platform.\n\
4202 If it is unavailable, using it will raise a NotImplementedError.\n\
4203If rmdir is True, remove will behave like os.rmdir().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Barry Warsaw53699e91996-12-10 23:23:01 +00004205static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004206posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004208 path_t path;
4209 int dir_fd = DEFAULT_DIR_FD;
4210 int remove_dir = 0;
4211 static char *keywords[] = {"path", "dir_fd", "rmdir", NULL};
4212 int result;
4213 PyObject *return_value = NULL;
4214
4215 memset(&path, 0, sizeof(path));
4216 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:unlink", keywords,
4217 path_converter, &path,
4218#ifdef HAVE_UNLINKAT
4219 dir_fd_converter, &dir_fd,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004220#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004221 dir_fd_unavailable, &dir_fd,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004222#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004223 &remove_dir))
4224 return NULL;
4225
4226 Py_BEGIN_ALLOW_THREADS
4227#ifdef MS_WINDOWS
4228 if (remove_dir) {
4229 if (path.wide)
4230 result = RemoveDirectoryW(path.wide);
4231 else
4232 result = RemoveDirectoryA(path.narrow);
4233 }
4234 else {
4235 if (path.wide)
4236 result = Py_DeleteFileW(path.wide);
4237 else
4238 result = DeleteFileA(path.narrow);
4239 }
4240 result = !result; /* Windows, success=1, UNIX, success=0 */
4241#else
4242 if (remove_dir && (dir_fd == DEFAULT_DIR_FD))
4243 result = rmdir(path.narrow);
4244 else
4245#ifdef HAVE_UNLINKAT
4246 if (dir_fd != DEFAULT_DIR_FD)
4247 result = unlinkat(dir_fd, path.narrow, remove_dir ? AT_REMOVEDIR : 0);
4248 else
4249#endif /* HAVE_UNLINKAT */
4250 result = unlink(path.narrow);
4251#endif
4252 Py_END_ALLOW_THREADS
4253
4254 if (result) {
4255 return_value = path_error("unlink", &path);
4256 goto exit;
4257 }
4258
4259 return_value = Py_None;
4260 Py_INCREF(Py_None);
4261
4262exit:
4263 path_cleanup(&path);
4264 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265}
4266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Guido van Rossumb6775db1994-08-01 11:34:53 +00004268#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004270"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004271Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004272
Barry Warsaw53699e91996-12-10 23:23:01 +00004273static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004274posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004275{
Victor Stinner8c62be82010-05-06 00:08:46 +00004276 struct utsname u;
4277 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00004278
Victor Stinner8c62be82010-05-06 00:08:46 +00004279 Py_BEGIN_ALLOW_THREADS
4280 res = uname(&u);
4281 Py_END_ALLOW_THREADS
4282 if (res < 0)
4283 return posix_error();
4284 return Py_BuildValue("(sssss)",
4285 u.sysname,
4286 u.nodename,
4287 u.release,
4288 u.version,
4289 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004290}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004291#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004292
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004293
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294PyDoc_STRVAR(posix_utime__doc__,
4295"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4296Set the access and modified time of path.\n\
4297\n\
4298path may always be specified as a string.\n\
4299On some platforms, path may also be specified as an open file descriptor.\n\
4300 If this functionality is unavailable, using it raises an exception.\n\
4301\n\
4302If times is not None, it must be a tuple (atime, mtime);\n\
4303 atime and mtime should be expressed as float seconds since the epoch.\n\
4304If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4305 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4306 since the epoch.\n\
4307If both times and ns are None, utime uses the current time.\n\
4308Specifying tuples for both times and ns is an error.\n\
4309\n\
4310If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4311 and path should be relative; path will then be relative to that directory.\n\
4312If follow_symlinks is False, and the last element of the path is a symbolic\n\
4313 link, utime will modify the symbolic link itself instead of the file the\n\
4314 link points to.\n\
4315It is an error to use dir_fd or follow_symlinks when specifying path\n\
4316 as an open file descriptor.\n\
4317dir_fd and follow_symlinks may not be available on your platform.\n\
4318 If they are unavailable, using them will raise a NotImplementedError.");
4319
4320typedef struct {
4321 int now;
4322 time_t atime_s;
4323 long atime_ns;
4324 time_t mtime_s;
4325 long mtime_ns;
4326} utime_t;
4327
4328/*
4329 * these macros assume that "utime" is a pointer to a utime_t
4330 * they also intentionally leak the declaration of a pointer named "time"
4331 */
4332#define UTIME_TO_TIMESPEC \
4333 struct timespec ts[2]; \
4334 struct timespec *time; \
4335 if (utime->now) \
4336 time = NULL; \
4337 else { \
4338 ts[0].tv_sec = utime->atime_s; \
4339 ts[0].tv_nsec = utime->atime_ns; \
4340 ts[1].tv_sec = utime->mtime_s; \
4341 ts[1].tv_nsec = utime->mtime_ns; \
4342 time = ts; \
4343 } \
4344
4345#define UTIME_TO_TIMEVAL \
4346 struct timeval tv[2]; \
4347 struct timeval *time; \
4348 if (utime->now) \
4349 time = NULL; \
4350 else { \
4351 tv[0].tv_sec = utime->atime_s; \
4352 tv[0].tv_usec = utime->atime_ns / 1000; \
4353 tv[1].tv_sec = utime->mtime_s; \
4354 tv[1].tv_usec = utime->mtime_ns / 1000; \
4355 time = tv; \
4356 } \
4357
4358#define UTIME_TO_UTIMBUF \
4359 struct utimbuf u[2]; \
4360 struct utimbuf *time; \
4361 if (utime->now) \
4362 time = NULL; \
4363 else { \
4364 u.actime = utime->atime_s; \
4365 u.modtime = utime->mtime_s; \
4366 time = u; \
4367 }
4368
4369#define UTIME_TO_TIME_T \
4370 time_t timet[2]; \
4371 struct timet time; \
4372 if (utime->now) \
4373 time = NULL; \
4374 else { \
4375 timet[0] = utime->atime_s; \
4376 timet[1] = utime->mtime_s; \
4377 time = &timet; \
4378 } \
4379
4380
4381#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4382
4383#if UTIME_HAVE_DIR_FD
4384
4385static int
4386utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4387{
4388#ifdef HAVE_UTIMENSAT
4389 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4390 UTIME_TO_TIMESPEC;
4391 return utimensat(dir_fd, path, time, flags);
4392#elif defined(HAVE_FUTIMESAT)
4393 UTIME_TO_TIMEVAL;
4394 /*
4395 * follow_symlinks will never be false here;
4396 * we only allow !follow_symlinks and dir_fd together
4397 * if we have utimensat()
4398 */
4399 assert(follow_symlinks);
4400 return futimesat(dir_fd, path, time);
4401#endif
4402}
4403
4404#endif
4405
4406#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4407
4408#if UTIME_HAVE_FD
4409
4410static int
4411utime_fd(utime_t *utime, int fd)
4412{
4413#ifdef HAVE_FUTIMENS
4414 UTIME_TO_TIMESPEC;
4415 return futimens(fd, time);
4416#else
4417 UTIME_TO_TIMEVAL;
4418 return futimes(fd, time);
4419#endif
4420}
4421
4422#endif
4423
4424
4425#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4426 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4427
4428#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4429
4430static int
4431utime_nofollow_symlinks(utime_t *utime, char *path)
4432{
4433#ifdef HAVE_UTIMENSAT
4434 UTIME_TO_TIMESPEC;
4435 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4436#else
4437 UTIME_TO_TIMEVAL;
4438 return lutimes(path, time);
4439#endif
4440}
4441
4442#endif
4443
4444#ifndef MS_WINDOWS
4445
4446static int
4447utime_default(utime_t *utime, char *path)
4448{
4449#ifdef HAVE_UTIMENSAT
4450 UTIME_TO_TIMESPEC;
4451 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4452#elif defined(HAVE_UTIMES)
4453 UTIME_TO_TIMEVAL;
4454 return utimes(path, time);
4455#elif defined(HAVE_UTIME_H)
4456 UTIME_TO_UTIMBUF;
4457 return utime(path, time);
4458#else
4459 UTIME_TO_TIME_T;
4460 return utime(path, time);
4461#endif
4462}
4463
4464#endif
4465
Larry Hastings76ad59b2012-05-03 00:30:07 -07004466static int
4467split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4468{
4469 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004470 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004471 divmod = PyNumber_Divmod(py_long, billion);
4472 if (!divmod)
4473 goto exit;
4474 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4475 if ((*s == -1) && PyErr_Occurred())
4476 goto exit;
4477 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004478 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004479 goto exit;
4480
4481 result = 1;
4482exit:
4483 Py_XDECREF(divmod);
4484 return result;
4485}
4486
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487static PyObject *
4488posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004489{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004491 PyObject *times = NULL;
4492 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004493 int dir_fd = DEFAULT_DIR_FD;
4494 int follow_symlinks = 1;
4495 char *keywords[] = {"path", "times", "ns", "dir_fd",
4496 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004497
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004499
Larry Hastings9cf065c2012-06-22 16:30:09 -07004500#ifdef MS_WINDOWS
4501 HANDLE hFile;
4502 FILETIME atime, mtime;
4503#else
4504 int result;
4505#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004506
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004508
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509 memset(&path, 0, sizeof(path));
4510#if UTIME_HAVE_FD
4511 path.allow_fd = 1;
4512#endif
4513 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4514 "O&|O$OO&p:utime", keywords,
4515 path_converter, &path,
4516 &times, &ns,
4517#if UTIME_HAVE_DIR_FD
4518 dir_fd_converter, &dir_fd,
4519#else
4520 dir_fd_unavailable, &dir_fd,
4521#endif
4522 &follow_symlinks
4523 ))
4524 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004525
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 if (times && (times != Py_None) && ns) {
4527 PyErr_SetString(PyExc_ValueError,
4528 "utime: you may specify either 'times'"
4529 " or 'ns' but not both");
4530 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004531 }
4532
4533 if (times && (times != Py_None)) {
4534 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535 PyErr_SetString(PyExc_TypeError,
4536 "utime: 'times' must be either"
4537 " a tuple of two ints or None");
4538 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004539 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004541 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004543 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 &utime.mtime_s, &utime.mtime_ns) == -1) {
4545 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004546 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004547 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004549 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004550 PyErr_SetString(PyExc_TypeError,
4551 "utime: 'ns' must be a tuple of two ints");
4552 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004553 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004555 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004557 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558 &utime.mtime_s, &utime.mtime_ns)) {
4559 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004560 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561 }
4562 else {
4563 /* times and ns are both None/unspecified. use "now". */
4564 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 }
4566
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4568 if (follow_symlinks_specified("utime", follow_symlinks))
4569 goto exit;
4570#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004571
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4573 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4574 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4575 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004576
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577#if !defined(HAVE_UTIMENSAT)
4578 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
4579 PyErr_SetString(PyExc_RuntimeError,
4580 "utime: cannot use dir_fd and follow_symlinks "
4581 "together on this platform");
4582 goto exit;
4583 }
4584#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004586#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 Py_BEGIN_ALLOW_THREADS
4588 if (path.wide)
4589 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004590 NULL, OPEN_EXISTING,
4591 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 else
4593 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004594 NULL, OPEN_EXISTING,
4595 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596 Py_END_ALLOW_THREADS
4597 if (hFile == INVALID_HANDLE_VALUE) {
4598 win32_error_object("utime", path.object);
4599 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004600 }
4601
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004603 SYSTEMTIME now;
4604 GetSystemTime(&now);
4605 if (!SystemTimeToFileTime(&now, &mtime) ||
4606 !SystemTimeToFileTime(&now, &atime)) {
4607 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004609 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004610 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004611 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4613 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004614 }
4615 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4616 /* Avoid putting the file name into the error here,
4617 as that may confuse the user into believing that
4618 something is wrong with the file, when it also
4619 could be the time stamp that gives a problem. */
4620 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004622 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004623#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004625
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4627 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4628 result = utime_nofollow_symlinks(&utime, path.narrow);
4629 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004630#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631
4632#if UTIME_HAVE_DIR_FD
4633 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4634 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4635 else
4636#endif
4637
4638#if UTIME_HAVE_FD
4639 if (path.fd != -1)
4640 result = utime_fd(&utime, path.fd);
4641 else
4642#endif
4643
4644 result = utime_default(&utime, path.narrow);
4645
4646 Py_END_ALLOW_THREADS
4647
4648 if (result < 0) {
4649 /* see previous comment about not putting filename in error here */
4650 return_value = posix_error();
4651 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004654#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655
4656 Py_INCREF(Py_None);
4657 return_value = Py_None;
4658
4659exit:
4660 path_cleanup(&path);
4661#ifdef MS_WINDOWS
4662 if (hFile != INVALID_HANDLE_VALUE)
4663 CloseHandle(hFile);
4664#endif
4665 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004666}
4667
Guido van Rossum3b066191991-06-04 19:40:25 +00004668/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004669
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004670PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004671"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004672Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004673
Barry Warsaw53699e91996-12-10 23:23:01 +00004674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004675posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004676{
Victor Stinner8c62be82010-05-06 00:08:46 +00004677 int sts;
4678 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4679 return NULL;
4680 _exit(sts);
4681 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004682}
4683
Martin v. Löwis114619e2002-10-07 06:44:21 +00004684#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4685static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004686free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004687{
Victor Stinner8c62be82010-05-06 00:08:46 +00004688 Py_ssize_t i;
4689 for (i = 0; i < count; i++)
4690 PyMem_Free(array[i]);
4691 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004692}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004693
Antoine Pitrou69f71142009-05-24 21:25:49 +00004694static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004695int fsconvert_strdup(PyObject *o, char**out)
4696{
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 PyObject *bytes;
4698 Py_ssize_t size;
4699 if (!PyUnicode_FSConverter(o, &bytes))
4700 return 0;
4701 size = PyBytes_GET_SIZE(bytes);
4702 *out = PyMem_Malloc(size+1);
4703 if (!*out)
4704 return 0;
4705 memcpy(*out, PyBytes_AsString(bytes), size+1);
4706 Py_DECREF(bytes);
4707 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004708}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004709#endif
4710
Ross Lagerwall7807c352011-03-17 20:20:30 +02004711#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004712static char**
4713parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4714{
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 char **envlist;
4716 Py_ssize_t i, pos, envc;
4717 PyObject *keys=NULL, *vals=NULL;
4718 PyObject *key, *val, *key2, *val2;
4719 char *p, *k, *v;
4720 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004721
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 i = PyMapping_Size(env);
4723 if (i < 0)
4724 return NULL;
4725 envlist = PyMem_NEW(char *, i + 1);
4726 if (envlist == NULL) {
4727 PyErr_NoMemory();
4728 return NULL;
4729 }
4730 envc = 0;
4731 keys = PyMapping_Keys(env);
4732 vals = PyMapping_Values(env);
4733 if (!keys || !vals)
4734 goto error;
4735 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4736 PyErr_Format(PyExc_TypeError,
4737 "env.keys() or env.values() is not a list");
4738 goto error;
4739 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004740
Victor Stinner8c62be82010-05-06 00:08:46 +00004741 for (pos = 0; pos < i; pos++) {
4742 key = PyList_GetItem(keys, pos);
4743 val = PyList_GetItem(vals, pos);
4744 if (!key || !val)
4745 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004746
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 if (PyUnicode_FSConverter(key, &key2) == 0)
4748 goto error;
4749 if (PyUnicode_FSConverter(val, &val2) == 0) {
4750 Py_DECREF(key2);
4751 goto error;
4752 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004753
4754#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004755 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4756 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004757#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 k = PyBytes_AsString(key2);
4759 v = PyBytes_AsString(val2);
4760 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004761
Victor Stinner8c62be82010-05-06 00:08:46 +00004762 p = PyMem_NEW(char, len);
4763 if (p == NULL) {
4764 PyErr_NoMemory();
4765 Py_DECREF(key2);
4766 Py_DECREF(val2);
4767 goto error;
4768 }
4769 PyOS_snprintf(p, len, "%s=%s", k, v);
4770 envlist[envc++] = p;
4771 Py_DECREF(key2);
4772 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004773#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004775#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
4777 Py_DECREF(vals);
4778 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004779
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 envlist[envc] = 0;
4781 *envc_ptr = envc;
4782 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004783
4784error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 Py_XDECREF(keys);
4786 Py_XDECREF(vals);
4787 while (--envc >= 0)
4788 PyMem_DEL(envlist[envc]);
4789 PyMem_DEL(envlist);
4790 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004791}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004792
Ross Lagerwall7807c352011-03-17 20:20:30 +02004793static char**
4794parse_arglist(PyObject* argv, Py_ssize_t *argc)
4795{
4796 int i;
4797 char **argvlist = PyMem_NEW(char *, *argc+1);
4798 if (argvlist == NULL) {
4799 PyErr_NoMemory();
4800 return NULL;
4801 }
4802 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004803 PyObject* item = PySequence_ITEM(argv, i);
4804 if (item == NULL)
4805 goto fail;
4806 if (!fsconvert_strdup(item, &argvlist[i])) {
4807 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004808 goto fail;
4809 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004810 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004811 }
4812 argvlist[*argc] = NULL;
4813 return argvlist;
4814fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004815 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004816 free_string_array(argvlist, *argc);
4817 return NULL;
4818}
4819#endif
4820
4821#ifdef HAVE_EXECV
4822PyDoc_STRVAR(posix_execv__doc__,
4823"execv(path, args)\n\n\
4824Execute an executable path with arguments, replacing current process.\n\
4825\n\
4826 path: path of executable file\n\
4827 args: tuple or list of strings");
4828
4829static PyObject *
4830posix_execv(PyObject *self, PyObject *args)
4831{
4832 PyObject *opath;
4833 char *path;
4834 PyObject *argv;
4835 char **argvlist;
4836 Py_ssize_t argc;
4837
4838 /* execv has two arguments: (path, argv), where
4839 argv is a list or tuple of strings. */
4840
4841 if (!PyArg_ParseTuple(args, "O&O:execv",
4842 PyUnicode_FSConverter,
4843 &opath, &argv))
4844 return NULL;
4845 path = PyBytes_AsString(opath);
4846 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4847 PyErr_SetString(PyExc_TypeError,
4848 "execv() arg 2 must be a tuple or list");
4849 Py_DECREF(opath);
4850 return NULL;
4851 }
4852 argc = PySequence_Size(argv);
4853 if (argc < 1) {
4854 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4855 Py_DECREF(opath);
4856 return NULL;
4857 }
4858
4859 argvlist = parse_arglist(argv, &argc);
4860 if (argvlist == NULL) {
4861 Py_DECREF(opath);
4862 return NULL;
4863 }
4864
4865 execv(path, argvlist);
4866
4867 /* If we get here it's definitely an error */
4868
4869 free_string_array(argvlist, argc);
4870 Py_DECREF(opath);
4871 return posix_error();
4872}
4873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004875"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004876Execute a path with arguments and environment, replacing current process.\n\
4877\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 path: path of executable file\n\
4879 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004880 env: dictionary of strings mapping to strings\n\
4881\n\
4882On some platforms, you may specify an open file descriptor for path;\n\
4883 execve will execute the program the file descriptor is open to.\n\
4884 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004885
Barry Warsaw53699e91996-12-10 23:23:01 +00004886static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004887posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004888{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004891 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004893 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004895
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 /* execve has three arguments: (path, argv, env), where
4897 argv is a list or tuple of strings and env is a dictionary
4898 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004899
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 memset(&path, 0, sizeof(path));
4901#ifdef HAVE_FEXECVE
4902 path.allow_fd = 1;
4903#endif
4904 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4905 path_converter, &path,
4906 &argv, &env
4907 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 "execve: argv must be a tuple or list");
4913 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004915 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 if (!PyMapping_Check(env)) {
4917 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004918 "execve: environment must be a mapping object");
4919 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004921
Ross Lagerwall7807c352011-03-17 20:20:30 +02004922 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004926
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 envlist = parse_envlist(env, &envc);
4928 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004929 goto fail;
4930
Larry Hastings9cf065c2012-06-22 16:30:09 -07004931#ifdef HAVE_FEXECVE
4932 if (path.fd > -1)
4933 fexecve(path.fd, argvlist, envlist);
4934 else
4935#endif
4936 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937
4938 /* If we get here it's definitely an error */
4939
Larry Hastings9cf065c2012-06-22 16:30:09 -07004940 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004941
4942 while (--envc >= 0)
4943 PyMem_DEL(envlist[envc]);
4944 PyMem_DEL(envlist);
4945 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 if (argvlist)
4947 free_string_array(argvlist, argc);
4948 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 return NULL;
4950}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004951#endif /* HAVE_EXECV */
4952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004953
Guido van Rossuma1065681999-01-25 23:20:23 +00004954#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004955PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004956"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004957Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004958\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 mode: mode of process creation\n\
4960 path: path of executable file\n\
4961 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004962
4963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004964posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004965{
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 PyObject *opath;
4967 char *path;
4968 PyObject *argv;
4969 char **argvlist;
4970 int mode, i;
4971 Py_ssize_t argc;
4972 Py_intptr_t spawnval;
4973 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004974
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 /* spawnv has three arguments: (mode, path, argv), where
4976 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4979 PyUnicode_FSConverter,
4980 &opath, &argv))
4981 return NULL;
4982 path = PyBytes_AsString(opath);
4983 if (PyList_Check(argv)) {
4984 argc = PyList_Size(argv);
4985 getitem = PyList_GetItem;
4986 }
4987 else if (PyTuple_Check(argv)) {
4988 argc = PyTuple_Size(argv);
4989 getitem = PyTuple_GetItem;
4990 }
4991 else {
4992 PyErr_SetString(PyExc_TypeError,
4993 "spawnv() arg 2 must be a tuple or list");
4994 Py_DECREF(opath);
4995 return NULL;
4996 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004997
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 argvlist = PyMem_NEW(char *, argc+1);
4999 if (argvlist == NULL) {
5000 Py_DECREF(opath);
5001 return PyErr_NoMemory();
5002 }
5003 for (i = 0; i < argc; i++) {
5004 if (!fsconvert_strdup((*getitem)(argv, i),
5005 &argvlist[i])) {
5006 free_string_array(argvlist, i);
5007 PyErr_SetString(
5008 PyExc_TypeError,
5009 "spawnv() arg 2 must contain only strings");
5010 Py_DECREF(opath);
5011 return NULL;
5012 }
5013 }
5014 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005015
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005016#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 Py_BEGIN_ALLOW_THREADS
5018 spawnval = spawnv(mode, path, argvlist);
5019 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005020#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 if (mode == _OLD_P_OVERLAY)
5022 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005023
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 Py_BEGIN_ALLOW_THREADS
5025 spawnval = _spawnv(mode, path, argvlist);
5026 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005027#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005028
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 free_string_array(argvlist, argc);
5030 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 if (spawnval == -1)
5033 return posix_error();
5034 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005035#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005037#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005039#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005040}
5041
5042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005044"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005045Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005046\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 mode: mode of process creation\n\
5048 path: path of executable file\n\
5049 args: tuple or list of arguments\n\
5050 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005051
5052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005053posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005054{
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 PyObject *opath;
5056 char *path;
5057 PyObject *argv, *env;
5058 char **argvlist;
5059 char **envlist;
5060 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005061 int mode;
5062 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 Py_intptr_t spawnval;
5064 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5065 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005066
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 /* spawnve has four arguments: (mode, path, argv, env), where
5068 argv is a list or tuple of strings and env is a dictionary
5069 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005070
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5072 PyUnicode_FSConverter,
5073 &opath, &argv, &env))
5074 return NULL;
5075 path = PyBytes_AsString(opath);
5076 if (PyList_Check(argv)) {
5077 argc = PyList_Size(argv);
5078 getitem = PyList_GetItem;
5079 }
5080 else if (PyTuple_Check(argv)) {
5081 argc = PyTuple_Size(argv);
5082 getitem = PyTuple_GetItem;
5083 }
5084 else {
5085 PyErr_SetString(PyExc_TypeError,
5086 "spawnve() arg 2 must be a tuple or list");
5087 goto fail_0;
5088 }
5089 if (!PyMapping_Check(env)) {
5090 PyErr_SetString(PyExc_TypeError,
5091 "spawnve() arg 3 must be a mapping object");
5092 goto fail_0;
5093 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 argvlist = PyMem_NEW(char *, argc+1);
5096 if (argvlist == NULL) {
5097 PyErr_NoMemory();
5098 goto fail_0;
5099 }
5100 for (i = 0; i < argc; i++) {
5101 if (!fsconvert_strdup((*getitem)(argv, i),
5102 &argvlist[i]))
5103 {
5104 lastarg = i;
5105 goto fail_1;
5106 }
5107 }
5108 lastarg = argc;
5109 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 envlist = parse_envlist(env, &envc);
5112 if (envlist == NULL)
5113 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005114
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005115#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 Py_BEGIN_ALLOW_THREADS
5117 spawnval = spawnve(mode, path, argvlist, envlist);
5118 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 if (mode == _OLD_P_OVERLAY)
5121 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 Py_BEGIN_ALLOW_THREADS
5124 spawnval = _spawnve(mode, path, argvlist, envlist);
5125 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005126#endif
Tim Peters25059d32001-12-07 20:35:43 +00005127
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 if (spawnval == -1)
5129 (void) posix_error();
5130 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005131#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005133#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005135#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 while (--envc >= 0)
5138 PyMem_DEL(envlist[envc]);
5139 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005140 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005142 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 Py_DECREF(opath);
5144 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005145}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005146
5147/* OS/2 supports spawnvp & spawnvpe natively */
5148#if defined(PYOS_OS2)
5149PyDoc_STRVAR(posix_spawnvp__doc__,
5150"spawnvp(mode, file, args)\n\n\
5151Execute the program 'file' in a new process, using the environment\n\
5152search path to find the file.\n\
5153\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 mode: mode of process creation\n\
5155 file: executable file name\n\
5156 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005157
5158static PyObject *
5159posix_spawnvp(PyObject *self, PyObject *args)
5160{
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 PyObject *opath;
5162 char *path;
5163 PyObject *argv;
5164 char **argvlist;
5165 int mode, i, argc;
5166 Py_intptr_t spawnval;
5167 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005168
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 /* spawnvp has three arguments: (mode, path, argv), where
5170 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5173 PyUnicode_FSConverter,
5174 &opath, &argv))
5175 return NULL;
5176 path = PyBytes_AsString(opath);
5177 if (PyList_Check(argv)) {
5178 argc = PyList_Size(argv);
5179 getitem = PyList_GetItem;
5180 }
5181 else if (PyTuple_Check(argv)) {
5182 argc = PyTuple_Size(argv);
5183 getitem = PyTuple_GetItem;
5184 }
5185 else {
5186 PyErr_SetString(PyExc_TypeError,
5187 "spawnvp() arg 2 must be a tuple or list");
5188 Py_DECREF(opath);
5189 return NULL;
5190 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 argvlist = PyMem_NEW(char *, argc+1);
5193 if (argvlist == NULL) {
5194 Py_DECREF(opath);
5195 return PyErr_NoMemory();
5196 }
5197 for (i = 0; i < argc; i++) {
5198 if (!fsconvert_strdup((*getitem)(argv, i),
5199 &argvlist[i])) {
5200 free_string_array(argvlist, i);
5201 PyErr_SetString(
5202 PyExc_TypeError,
5203 "spawnvp() arg 2 must contain only strings");
5204 Py_DECREF(opath);
5205 return NULL;
5206 }
5207 }
5208 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005209
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005211#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005215#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005217
Victor Stinner8c62be82010-05-06 00:08:46 +00005218 free_string_array(argvlist, argc);
5219 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005220
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 if (spawnval == -1)
5222 return posix_error();
5223 else
5224 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005225}
5226
5227
5228PyDoc_STRVAR(posix_spawnvpe__doc__,
5229"spawnvpe(mode, file, args, env)\n\n\
5230Execute the program 'file' in a new process, using the environment\n\
5231search path to find the file.\n\
5232\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 mode: mode of process creation\n\
5234 file: executable file name\n\
5235 args: tuple or list of arguments\n\
5236 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005237
5238static PyObject *
5239posix_spawnvpe(PyObject *self, PyObject *args)
5240{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005241 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 char *path;
5243 PyObject *argv, *env;
5244 char **argvlist;
5245 char **envlist;
5246 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005247 int mode;
5248 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 Py_intptr_t spawnval;
5250 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5251 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005252
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 /* spawnvpe has four arguments: (mode, path, argv, env), where
5254 argv is a list or tuple of strings and env is a dictionary
5255 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005256
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5258 PyUnicode_FSConverter,
5259 &opath, &argv, &env))
5260 return NULL;
5261 path = PyBytes_AsString(opath);
5262 if (PyList_Check(argv)) {
5263 argc = PyList_Size(argv);
5264 getitem = PyList_GetItem;
5265 }
5266 else if (PyTuple_Check(argv)) {
5267 argc = PyTuple_Size(argv);
5268 getitem = PyTuple_GetItem;
5269 }
5270 else {
5271 PyErr_SetString(PyExc_TypeError,
5272 "spawnvpe() arg 2 must be a tuple or list");
5273 goto fail_0;
5274 }
5275 if (!PyMapping_Check(env)) {
5276 PyErr_SetString(PyExc_TypeError,
5277 "spawnvpe() arg 3 must be a mapping object");
5278 goto fail_0;
5279 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005280
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 argvlist = PyMem_NEW(char *, argc+1);
5282 if (argvlist == NULL) {
5283 PyErr_NoMemory();
5284 goto fail_0;
5285 }
5286 for (i = 0; i < argc; i++) {
5287 if (!fsconvert_strdup((*getitem)(argv, i),
5288 &argvlist[i]))
5289 {
5290 lastarg = i;
5291 goto fail_1;
5292 }
5293 }
5294 lastarg = argc;
5295 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 envlist = parse_envlist(env, &envc);
5298 if (envlist == NULL)
5299 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005302#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005304#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005306#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 if (spawnval == -1)
5310 (void) posix_error();
5311 else
5312 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005313
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 while (--envc >= 0)
5315 PyMem_DEL(envlist[envc]);
5316 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005317 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005319 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 Py_DECREF(opath);
5321 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005322}
5323#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005324#endif /* HAVE_SPAWNV */
5325
5326
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005327#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005328PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005329"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005330Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5331\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005332Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005333
5334static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005335posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005336{
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 pid_t pid;
5338 int result = 0;
5339 _PyImport_AcquireLock();
5340 pid = fork1();
5341 if (pid == 0) {
5342 /* child: this clobbers and resets the import lock. */
5343 PyOS_AfterFork();
5344 } else {
5345 /* parent: release the import lock. */
5346 result = _PyImport_ReleaseLock();
5347 }
5348 if (pid == -1)
5349 return posix_error();
5350 if (result < 0) {
5351 /* Don't clobber the OSError if the fork failed. */
5352 PyErr_SetString(PyExc_RuntimeError,
5353 "not holding the import lock");
5354 return NULL;
5355 }
5356 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005357}
5358#endif
5359
5360
Guido van Rossumad0ee831995-03-01 10:34:45 +00005361#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005364Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005365Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005366
Barry Warsaw53699e91996-12-10 23:23:01 +00005367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005368posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005369{
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 pid_t pid;
5371 int result = 0;
5372 _PyImport_AcquireLock();
5373 pid = fork();
5374 if (pid == 0) {
5375 /* child: this clobbers and resets the import lock. */
5376 PyOS_AfterFork();
5377 } else {
5378 /* parent: release the import lock. */
5379 result = _PyImport_ReleaseLock();
5380 }
5381 if (pid == -1)
5382 return posix_error();
5383 if (result < 0) {
5384 /* Don't clobber the OSError if the fork failed. */
5385 PyErr_SetString(PyExc_RuntimeError,
5386 "not holding the import lock");
5387 return NULL;
5388 }
5389 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005390}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005391#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005392
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005393#ifdef HAVE_SCHED_H
5394
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005395#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5396
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005397PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5398"sched_get_priority_max(policy)\n\n\
5399Get the maximum scheduling priority for *policy*.");
5400
5401static PyObject *
5402posix_sched_get_priority_max(PyObject *self, PyObject *args)
5403{
5404 int policy, max;
5405
5406 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5407 return NULL;
5408 max = sched_get_priority_max(policy);
5409 if (max < 0)
5410 return posix_error();
5411 return PyLong_FromLong(max);
5412}
5413
5414PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5415"sched_get_priority_min(policy)\n\n\
5416Get the minimum scheduling priority for *policy*.");
5417
5418static PyObject *
5419posix_sched_get_priority_min(PyObject *self, PyObject *args)
5420{
5421 int policy, min;
5422
5423 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5424 return NULL;
5425 min = sched_get_priority_min(policy);
5426 if (min < 0)
5427 return posix_error();
5428 return PyLong_FromLong(min);
5429}
5430
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005431#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5432
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005433#ifdef HAVE_SCHED_SETSCHEDULER
5434
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005435PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5436"sched_getscheduler(pid)\n\n\
5437Get the scheduling policy for the process with a PID of *pid*.\n\
5438Passing a PID of 0 returns the scheduling policy for the calling process.");
5439
5440static PyObject *
5441posix_sched_getscheduler(PyObject *self, PyObject *args)
5442{
5443 pid_t pid;
5444 int policy;
5445
5446 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5447 return NULL;
5448 policy = sched_getscheduler(pid);
5449 if (policy < 0)
5450 return posix_error();
5451 return PyLong_FromLong(policy);
5452}
5453
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005454#endif
5455
5456#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5457
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005458static PyObject *
5459sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5460{
5461 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005462 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005463
5464 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5465 return NULL;
5466 res = PyStructSequence_New(type);
5467 if (!res)
5468 return NULL;
5469 Py_INCREF(priority);
5470 PyStructSequence_SET_ITEM(res, 0, priority);
5471 return res;
5472}
5473
5474PyDoc_STRVAR(sched_param__doc__,
5475"sched_param(sched_priority): A scheduling parameter.\n\n\
5476Current has only one field: sched_priority");
5477
5478static PyStructSequence_Field sched_param_fields[] = {
5479 {"sched_priority", "the scheduling priority"},
5480 {0}
5481};
5482
5483static PyStructSequence_Desc sched_param_desc = {
5484 "sched_param", /* name */
5485 sched_param__doc__, /* doc */
5486 sched_param_fields,
5487 1
5488};
5489
5490static int
5491convert_sched_param(PyObject *param, struct sched_param *res)
5492{
5493 long priority;
5494
5495 if (Py_TYPE(param) != &SchedParamType) {
5496 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5497 return 0;
5498 }
5499 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5500 if (priority == -1 && PyErr_Occurred())
5501 return 0;
5502 if (priority > INT_MAX || priority < INT_MIN) {
5503 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5504 return 0;
5505 }
5506 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5507 return 1;
5508}
5509
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005510#endif
5511
5512#ifdef HAVE_SCHED_SETSCHEDULER
5513
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005514PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5515"sched_setscheduler(pid, policy, param)\n\n\
5516Set the scheduling policy, *policy*, for *pid*.\n\
5517If *pid* is 0, the calling process is changed.\n\
5518*param* is an instance of sched_param.");
5519
5520static PyObject *
5521posix_sched_setscheduler(PyObject *self, PyObject *args)
5522{
5523 pid_t pid;
5524 int policy;
5525 struct sched_param param;
5526
5527 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5528 &pid, &policy, &convert_sched_param, &param))
5529 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005530
5531 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005532 ** sched_setscheduler() returns 0 in Linux, but the previous
5533 ** scheduling policy under Solaris/Illumos, and others.
5534 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005535 */
5536 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005537 return posix_error();
5538 Py_RETURN_NONE;
5539}
5540
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005541#endif
5542
5543#ifdef HAVE_SCHED_SETPARAM
5544
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005545PyDoc_STRVAR(posix_sched_getparam__doc__,
5546"sched_getparam(pid) -> sched_param\n\n\
5547Returns scheduling parameters for the process with *pid* as an instance of the\n\
5548sched_param class. A PID of 0 means the calling process.");
5549
5550static PyObject *
5551posix_sched_getparam(PyObject *self, PyObject *args)
5552{
5553 pid_t pid;
5554 struct sched_param param;
5555 PyObject *res, *priority;
5556
5557 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5558 return NULL;
5559 if (sched_getparam(pid, &param))
5560 return posix_error();
5561 res = PyStructSequence_New(&SchedParamType);
5562 if (!res)
5563 return NULL;
5564 priority = PyLong_FromLong(param.sched_priority);
5565 if (!priority) {
5566 Py_DECREF(res);
5567 return NULL;
5568 }
5569 PyStructSequence_SET_ITEM(res, 0, priority);
5570 return res;
5571}
5572
5573PyDoc_STRVAR(posix_sched_setparam__doc__,
5574"sched_setparam(pid, param)\n\n\
5575Set scheduling parameters for a process with PID *pid*.\n\
5576A PID of 0 means the calling process.");
5577
5578static PyObject *
5579posix_sched_setparam(PyObject *self, PyObject *args)
5580{
5581 pid_t pid;
5582 struct sched_param param;
5583
5584 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5585 &pid, &convert_sched_param, &param))
5586 return NULL;
5587 if (sched_setparam(pid, &param))
5588 return posix_error();
5589 Py_RETURN_NONE;
5590}
5591
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005592#endif
5593
5594#ifdef HAVE_SCHED_RR_GET_INTERVAL
5595
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5597"sched_rr_get_interval(pid) -> float\n\n\
5598Return the round-robin quantum for the process with PID *pid* in seconds.");
5599
5600static PyObject *
5601posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5602{
5603 pid_t pid;
5604 struct timespec interval;
5605
5606 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5607 return NULL;
5608 if (sched_rr_get_interval(pid, &interval))
5609 return posix_error();
5610 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5611}
5612
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005613#endif
5614
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615PyDoc_STRVAR(posix_sched_yield__doc__,
5616"sched_yield()\n\n\
5617Voluntarily relinquish the CPU.");
5618
5619static PyObject *
5620posix_sched_yield(PyObject *self, PyObject *noargs)
5621{
5622 if (sched_yield())
5623 return posix_error();
5624 Py_RETURN_NONE;
5625}
5626
Benjamin Peterson2740af82011-08-02 17:41:34 -05005627#ifdef HAVE_SCHED_SETAFFINITY
5628
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005629typedef struct {
5630 PyObject_HEAD;
5631 Py_ssize_t size;
5632 int ncpus;
5633 cpu_set_t *set;
5634} Py_cpu_set;
5635
5636static PyTypeObject cpu_set_type;
5637
5638static void
5639cpu_set_dealloc(Py_cpu_set *set)
5640{
5641 assert(set->set);
5642 CPU_FREE(set->set);
5643 Py_TYPE(set)->tp_free(set);
5644}
5645
5646static Py_cpu_set *
5647make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5648{
5649 Py_cpu_set *set;
5650
5651 if (size < 0) {
5652 PyErr_SetString(PyExc_ValueError, "negative size");
5653 return NULL;
5654 }
5655 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5656 if (!set)
5657 return NULL;
5658 set->ncpus = size;
5659 set->size = CPU_ALLOC_SIZE(size);
5660 set->set = CPU_ALLOC(size);
5661 if (!set->set) {
5662 type->tp_free(set);
5663 PyErr_NoMemory();
5664 return NULL;
5665 }
5666 CPU_ZERO_S(set->size, set->set);
5667 return set;
5668}
5669
5670static PyObject *
5671cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5672{
5673 int size;
5674
5675 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5676 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5677 return NULL;
5678 return (PyObject *)make_new_cpu_set(type, size);
5679}
5680
5681static PyObject *
5682cpu_set_repr(Py_cpu_set *set)
5683{
5684 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005685}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005686
5687static Py_ssize_t
5688cpu_set_len(Py_cpu_set *set)
5689{
5690 return set->ncpus;
5691}
5692
5693static int
5694_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5695{
5696 int cpu;
5697 if (!PyArg_ParseTuple(args, requester, &cpu))
5698 return -1;
5699 if (cpu < 0) {
5700 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5701 return -1;
5702 }
5703 if (cpu >= set->ncpus) {
5704 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5705 return -1;
5706 }
5707 return cpu;
5708}
5709
5710PyDoc_STRVAR(cpu_set_set_doc,
5711"cpu_set.set(i)\n\n\
5712Add CPU *i* to the set.");
5713
5714static PyObject *
5715cpu_set_set(Py_cpu_set *set, PyObject *args)
5716{
5717 int cpu = _get_cpu(set, "i|set", args);
5718 if (cpu == -1)
5719 return NULL;
5720 CPU_SET_S(cpu, set->size, set->set);
5721 Py_RETURN_NONE;
5722}
5723
5724PyDoc_STRVAR(cpu_set_count_doc,
5725"cpu_set.count() -> int\n\n\
5726Return the number of CPUs active in the set.");
5727
5728static PyObject *
5729cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5730{
5731 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5732}
5733
5734PyDoc_STRVAR(cpu_set_clear_doc,
5735"cpu_set.clear(i)\n\n\
5736Remove CPU *i* from the set.");
5737
5738static PyObject *
5739cpu_set_clear(Py_cpu_set *set, PyObject *args)
5740{
5741 int cpu = _get_cpu(set, "i|clear", args);
5742 if (cpu == -1)
5743 return NULL;
5744 CPU_CLR_S(cpu, set->size, set->set);
5745 Py_RETURN_NONE;
5746}
5747
5748PyDoc_STRVAR(cpu_set_isset_doc,
5749"cpu_set.isset(i) -> bool\n\n\
5750Test if CPU *i* is in the set.");
5751
5752static PyObject *
5753cpu_set_isset(Py_cpu_set *set, PyObject *args)
5754{
5755 int cpu = _get_cpu(set, "i|isset", args);
5756 if (cpu == -1)
5757 return NULL;
5758 if (CPU_ISSET_S(cpu, set->size, set->set))
5759 Py_RETURN_TRUE;
5760 Py_RETURN_FALSE;
5761}
5762
5763PyDoc_STRVAR(cpu_set_zero_doc,
5764"cpu_set.zero()\n\n\
5765Clear the cpu_set.");
5766
5767static PyObject *
5768cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5769{
5770 CPU_ZERO_S(set->size, set->set);
5771 Py_RETURN_NONE;
5772}
5773
5774static PyObject *
5775cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5776{
5777 int eq;
5778
Brian Curtindfc80e32011-08-10 20:28:54 -05005779 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5780 Py_RETURN_NOTIMPLEMENTED;
5781
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005782 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5783 if ((op == Py_EQ) ? eq : !eq)
5784 Py_RETURN_TRUE;
5785 else
5786 Py_RETURN_FALSE;
5787}
5788
5789#define CPU_SET_BINOP(name, op) \
5790 static PyObject * \
5791 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5792 if (res) { \
5793 Py_INCREF(res); \
5794 } \
5795 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005796 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797 if (!res) \
5798 return NULL; \
5799 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005800 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005801 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005802 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005803 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005804 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005805 op(res->size, res->set, left->set, right->set); \
5806 return (PyObject *)res; \
5807 } \
5808 static PyObject * \
5809 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5810 return do_cpu_set_##name(left, right, NULL); \
5811 } \
5812 static PyObject * \
5813 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5814 return do_cpu_set_##name(left, right, left); \
5815 } \
5816
5817CPU_SET_BINOP(and, CPU_AND_S)
5818CPU_SET_BINOP(or, CPU_OR_S)
5819CPU_SET_BINOP(xor, CPU_XOR_S)
5820#undef CPU_SET_BINOP
5821
5822PyDoc_STRVAR(cpu_set_doc,
5823"cpu_set(size)\n\n\
5824Create an empty mask of CPUs.");
5825
5826static PyNumberMethods cpu_set_as_number = {
5827 0, /*nb_add*/
5828 0, /*nb_subtract*/
5829 0, /*nb_multiply*/
5830 0, /*nb_remainder*/
5831 0, /*nb_divmod*/
5832 0, /*nb_power*/
5833 0, /*nb_negative*/
5834 0, /*nb_positive*/
5835 0, /*nb_absolute*/
5836 0, /*nb_bool*/
5837 0, /*nb_invert*/
5838 0, /*nb_lshift*/
5839 0, /*nb_rshift*/
5840 (binaryfunc)cpu_set_and, /*nb_and*/
5841 (binaryfunc)cpu_set_xor, /*nb_xor*/
5842 (binaryfunc)cpu_set_or, /*nb_or*/
5843 0, /*nb_int*/
5844 0, /*nb_reserved*/
5845 0, /*nb_float*/
5846 0, /*nb_inplace_add*/
5847 0, /*nb_inplace_subtract*/
5848 0, /*nb_inplace_multiply*/
5849 0, /*nb_inplace_remainder*/
5850 0, /*nb_inplace_power*/
5851 0, /*nb_inplace_lshift*/
5852 0, /*nb_inplace_rshift*/
5853 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5854 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5855 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5856};
5857
5858static PySequenceMethods cpu_set_as_sequence = {
5859 (lenfunc)cpu_set_len, /* sq_length */
5860};
5861
5862static PyMethodDef cpu_set_methods[] = {
5863 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5864 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5865 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5866 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5867 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5868 {NULL, NULL} /* sentinel */
5869};
5870
5871static PyTypeObject cpu_set_type = {
5872 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5873 "posix.cpu_set", /* tp_name */
5874 sizeof(Py_cpu_set), /* tp_basicsize */
5875 0, /* tp_itemsize */
5876 /* methods */
5877 (destructor)cpu_set_dealloc, /* tp_dealloc */
5878 0, /* tp_print */
5879 0, /* tp_getattr */
5880 0, /* tp_setattr */
5881 0, /* tp_reserved */
5882 (reprfunc)cpu_set_repr, /* tp_repr */
5883 &cpu_set_as_number, /* tp_as_number */
5884 &cpu_set_as_sequence, /* tp_as_sequence */
5885 0, /* tp_as_mapping */
5886 PyObject_HashNotImplemented, /* tp_hash */
5887 0, /* tp_call */
5888 0, /* tp_str */
5889 PyObject_GenericGetAttr, /* tp_getattro */
5890 0, /* tp_setattro */
5891 0, /* tp_as_buffer */
5892 Py_TPFLAGS_DEFAULT, /* tp_flags */
5893 cpu_set_doc, /* tp_doc */
5894 0, /* tp_traverse */
5895 0, /* tp_clear */
5896 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5897 0, /* tp_weaklistoffset */
5898 0, /* tp_iter */
5899 0, /* tp_iternext */
5900 cpu_set_methods, /* tp_methods */
5901 0, /* tp_members */
5902 0, /* tp_getset */
5903 0, /* tp_base */
5904 0, /* tp_dict */
5905 0, /* tp_descr_get */
5906 0, /* tp_descr_set */
5907 0, /* tp_dictoffset */
5908 0, /* tp_init */
5909 PyType_GenericAlloc, /* tp_alloc */
5910 cpu_set_new, /* tp_new */
5911 PyObject_Del, /* tp_free */
5912};
5913
5914PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5915"sched_setaffinity(pid, cpu_set)\n\n\
5916Set the affinity of the process with PID *pid* to *cpu_set*.");
5917
5918static PyObject *
5919posix_sched_setaffinity(PyObject *self, PyObject *args)
5920{
5921 pid_t pid;
5922 Py_cpu_set *cpu_set;
5923
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005924 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005925 &pid, &cpu_set_type, &cpu_set))
5926 return NULL;
5927 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5928 return posix_error();
5929 Py_RETURN_NONE;
5930}
5931
5932PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5933"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5934Return the affinity of the process with PID *pid*.\n\
5935The returned cpu_set will be of size *ncpus*.");
5936
5937static PyObject *
5938posix_sched_getaffinity(PyObject *self, PyObject *args)
5939{
5940 pid_t pid;
5941 int ncpus;
5942 Py_cpu_set *res;
5943
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005944 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005945 &pid, &ncpus))
5946 return NULL;
5947 res = make_new_cpu_set(&cpu_set_type, ncpus);
5948 if (!res)
5949 return NULL;
5950 if (sched_getaffinity(pid, res->size, res->set)) {
5951 Py_DECREF(res);
5952 return posix_error();
5953 }
5954 return (PyObject *)res;
5955}
5956
Benjamin Peterson2740af82011-08-02 17:41:34 -05005957#endif /* HAVE_SCHED_SETAFFINITY */
5958
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005959#endif /* HAVE_SCHED_H */
5960
Neal Norwitzb59798b2003-03-21 01:43:31 +00005961/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005962/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5963#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005964#define DEV_PTY_FILE "/dev/ptc"
5965#define HAVE_DEV_PTMX
5966#else
5967#define DEV_PTY_FILE "/dev/ptmx"
5968#endif
5969
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005970#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005971#ifdef HAVE_PTY_H
5972#include <pty.h>
5973#else
5974#ifdef HAVE_LIBUTIL_H
5975#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005976#else
5977#ifdef HAVE_UTIL_H
5978#include <util.h>
5979#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005980#endif /* HAVE_LIBUTIL_H */
5981#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005982#ifdef HAVE_STROPTS_H
5983#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005984#endif
5985#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005986
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005987#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005989"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005990Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005991
5992static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005993posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005994{
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005996#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005998#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005999#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006001#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006003#endif
6004#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006005
Thomas Wouters70c21a12000-07-14 14:28:33 +00006006#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6008 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006009#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6011 if (slave_name == NULL)
6012 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006013
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 slave_fd = open(slave_name, O_RDWR);
6015 if (slave_fd < 0)
6016 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006017#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6019 if (master_fd < 0)
6020 return posix_error();
6021 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6022 /* change permission of slave */
6023 if (grantpt(master_fd) < 0) {
6024 PyOS_setsig(SIGCHLD, sig_saved);
6025 return posix_error();
6026 }
6027 /* unlock slave */
6028 if (unlockpt(master_fd) < 0) {
6029 PyOS_setsig(SIGCHLD, sig_saved);
6030 return posix_error();
6031 }
6032 PyOS_setsig(SIGCHLD, sig_saved);
6033 slave_name = ptsname(master_fd); /* get name of slave */
6034 if (slave_name == NULL)
6035 return posix_error();
6036 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6037 if (slave_fd < 0)
6038 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006039#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6041 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006042#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006044#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006045#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006046#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006047
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006049
Fred Drake8cef4cf2000-06-28 16:40:38 +00006050}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006051#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006052
6053#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006055"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006056Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6057Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006059
6060static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006061posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006062{
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 int master_fd = -1, result = 0;
6064 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006065
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 _PyImport_AcquireLock();
6067 pid = forkpty(&master_fd, NULL, NULL, NULL);
6068 if (pid == 0) {
6069 /* child: this clobbers and resets the import lock. */
6070 PyOS_AfterFork();
6071 } else {
6072 /* parent: release the import lock. */
6073 result = _PyImport_ReleaseLock();
6074 }
6075 if (pid == -1)
6076 return posix_error();
6077 if (result < 0) {
6078 /* Don't clobber the OSError if the fork failed. */
6079 PyErr_SetString(PyExc_RuntimeError,
6080 "not holding the import lock");
6081 return NULL;
6082 }
6083 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006084}
6085#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006086
Ross Lagerwall7807c352011-03-17 20:20:30 +02006087
Guido van Rossumad0ee831995-03-01 10:34:45 +00006088#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006090"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006091Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006092
Barry Warsaw53699e91996-12-10 23:23:01 +00006093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006094posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095{
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006098#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006100
Guido van Rossumad0ee831995-03-01 10:34:45 +00006101#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006103"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006105
Barry Warsaw53699e91996-12-10 23:23:01 +00006106static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006107posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006108{
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006110}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006111#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006113
Guido van Rossumad0ee831995-03-01 10:34:45 +00006114#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006116"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006118
Barry Warsaw53699e91996-12-10 23:23:01 +00006119static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006120posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006121{
Victor Stinner8c62be82010-05-06 00:08:46 +00006122 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006123}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006124#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006128"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006130
Barry Warsaw53699e91996-12-10 23:23:01 +00006131static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006132posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006133{
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006135}
6136
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006137#ifdef HAVE_GETGROUPLIST
6138PyDoc_STRVAR(posix_getgrouplist__doc__,
6139"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6140Returns a list of groups to which a user belongs.\n\n\
6141 user: username to lookup\n\
6142 group: base group id of the user");
6143
6144static PyObject *
6145posix_getgrouplist(PyObject *self, PyObject *args)
6146{
6147#ifdef NGROUPS_MAX
6148#define MAX_GROUPS NGROUPS_MAX
6149#else
6150 /* defined to be 16 on Solaris7, so this should be a small number */
6151#define MAX_GROUPS 64
6152#endif
6153
6154 const char *user;
6155 int i, ngroups;
6156 PyObject *list;
6157#ifdef __APPLE__
6158 int *groups, basegid;
6159#else
6160 gid_t *groups, basegid;
6161#endif
6162 ngroups = MAX_GROUPS;
6163
6164 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6165 return NULL;
6166
6167#ifdef __APPLE__
6168 groups = PyMem_Malloc(ngroups * sizeof(int));
6169#else
6170 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6171#endif
6172 if (groups == NULL)
6173 return PyErr_NoMemory();
6174
6175 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6176 PyMem_Del(groups);
6177 return posix_error();
6178 }
6179
6180 list = PyList_New(ngroups);
6181 if (list == NULL) {
6182 PyMem_Del(groups);
6183 return NULL;
6184 }
6185
6186 for (i = 0; i < ngroups; i++) {
6187 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6188 if (o == NULL) {
6189 Py_DECREF(list);
6190 PyMem_Del(groups);
6191 return NULL;
6192 }
6193 PyList_SET_ITEM(list, i, o);
6194 }
6195
6196 PyMem_Del(groups);
6197
6198 return list;
6199}
6200#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006201
Fred Drakec9680921999-12-13 16:37:25 +00006202#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006203PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006204"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006205Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006206
6207static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006208posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006209{
6210 PyObject *result = NULL;
6211
Fred Drakec9680921999-12-13 16:37:25 +00006212#ifdef NGROUPS_MAX
6213#define MAX_GROUPS NGROUPS_MAX
6214#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006216#define MAX_GROUPS 64
6217#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006219
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006220 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006221 * This is a helper variable to store the intermediate result when
6222 * that happens.
6223 *
6224 * To keep the code readable the OSX behaviour is unconditional,
6225 * according to the POSIX spec this should be safe on all unix-y
6226 * systems.
6227 */
6228 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006230
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006232 if (n < 0) {
6233 if (errno == EINVAL) {
6234 n = getgroups(0, NULL);
6235 if (n == -1) {
6236 return posix_error();
6237 }
6238 if (n == 0) {
6239 /* Avoid malloc(0) */
6240 alt_grouplist = grouplist;
6241 } else {
6242 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6243 if (alt_grouplist == NULL) {
6244 errno = EINVAL;
6245 return posix_error();
6246 }
6247 n = getgroups(n, alt_grouplist);
6248 if (n == -1) {
6249 PyMem_Free(alt_grouplist);
6250 return posix_error();
6251 }
6252 }
6253 } else {
6254 return posix_error();
6255 }
6256 }
6257 result = PyList_New(n);
6258 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 int i;
6260 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006261 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006263 Py_DECREF(result);
6264 result = NULL;
6265 break;
Fred Drakec9680921999-12-13 16:37:25 +00006266 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006268 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006269 }
6270
6271 if (alt_grouplist != grouplist) {
6272 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006274
Fred Drakec9680921999-12-13 16:37:25 +00006275 return result;
6276}
6277#endif
6278
Antoine Pitroub7572f02009-12-02 20:46:48 +00006279#ifdef HAVE_INITGROUPS
6280PyDoc_STRVAR(posix_initgroups__doc__,
6281"initgroups(username, gid) -> None\n\n\
6282Call the system initgroups() to initialize the group access list with all of\n\
6283the groups of which the specified username is a member, plus the specified\n\
6284group id.");
6285
6286static PyObject *
6287posix_initgroups(PyObject *self, PyObject *args)
6288{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006289 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006291 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006293
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006294 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6295 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006298
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006299 res = initgroups(username, (gid_t) gid);
6300 Py_DECREF(oname);
6301 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006303
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 Py_INCREF(Py_None);
6305 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306}
6307#endif
6308
Martin v. Löwis606edc12002-06-13 21:09:11 +00006309#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006310PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006311"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006312Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006313
6314static PyObject *
6315posix_getpgid(PyObject *self, PyObject *args)
6316{
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 pid_t pid, pgid;
6318 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6319 return NULL;
6320 pgid = getpgid(pid);
6321 if (pgid < 0)
6322 return posix_error();
6323 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006324}
6325#endif /* HAVE_GETPGID */
6326
6327
Guido van Rossumb6775db1994-08-01 11:34:53 +00006328#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006330"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006332
Barry Warsaw53699e91996-12-10 23:23:01 +00006333static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006334posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006335{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006336#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006338#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006340#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006341}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006344
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006347"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006348Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006349
Barry Warsaw53699e91996-12-10 23:23:01 +00006350static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006351posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006352{
Guido van Rossum64933891994-10-20 21:56:42 +00006353#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006355#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006357#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 return posix_error();
6359 Py_INCREF(Py_None);
6360 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006361}
6362
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#endif /* HAVE_SETPGRP */
6364
Guido van Rossumad0ee831995-03-01 10:34:45 +00006365#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006366
6367#ifdef MS_WINDOWS
6368#include <tlhelp32.h>
6369
6370static PyObject*
6371win32_getppid()
6372{
6373 HANDLE snapshot;
6374 pid_t mypid;
6375 PyObject* result = NULL;
6376 BOOL have_record;
6377 PROCESSENTRY32 pe;
6378
6379 mypid = getpid(); /* This function never fails */
6380
6381 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6382 if (snapshot == INVALID_HANDLE_VALUE)
6383 return PyErr_SetFromWindowsErr(GetLastError());
6384
6385 pe.dwSize = sizeof(pe);
6386 have_record = Process32First(snapshot, &pe);
6387 while (have_record) {
6388 if (mypid == (pid_t)pe.th32ProcessID) {
6389 /* We could cache the ulong value in a static variable. */
6390 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6391 break;
6392 }
6393
6394 have_record = Process32Next(snapshot, &pe);
6395 }
6396
6397 /* If our loop exits and our pid was not found (result will be NULL)
6398 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6399 * error anyway, so let's raise it. */
6400 if (!result)
6401 result = PyErr_SetFromWindowsErr(GetLastError());
6402
6403 CloseHandle(snapshot);
6404
6405 return result;
6406}
6407#endif /*MS_WINDOWS*/
6408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006409PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006410"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006411Return the parent's process id. If the parent process has already exited,\n\
6412Windows machines will still return its id; others systems will return the id\n\
6413of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Barry Warsaw53699e91996-12-10 23:23:01 +00006415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006416posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006417{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006418#ifdef MS_WINDOWS
6419 return win32_getppid();
6420#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006422#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006423}
6424#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006426
Fred Drake12c6e2d1999-12-14 21:25:03 +00006427#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006428PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006429"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006430Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006431
6432static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006433posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006434{
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006436#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006437 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006438 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006439
6440 if (GetUserNameW(user_name, &num_chars)) {
6441 /* num_chars is the number of unicode chars plus null terminator */
6442 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006443 }
6444 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006445 result = PyErr_SetFromWindowsErr(GetLastError());
6446#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 char *name;
6448 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006449
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 errno = 0;
6451 name = getlogin();
6452 if (name == NULL) {
6453 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006454 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006455 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006456 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 }
6458 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006459 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006461#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006462 return result;
6463}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006464#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465
Guido van Rossumad0ee831995-03-01 10:34:45 +00006466#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006468"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006470
Barry Warsaw53699e91996-12-10 23:23:01 +00006471static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006472posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006473{
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006475}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006476#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006478
Guido van Rossumad0ee831995-03-01 10:34:45 +00006479#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006481"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006483
Barry Warsaw53699e91996-12-10 23:23:01 +00006484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006485posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006486{
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 pid_t pid;
6488 int sig;
6489 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6490 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006491#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006492 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6493 APIRET rc;
6494 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006495 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006496
6497 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6498 APIRET rc;
6499 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006500 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006501
6502 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006503 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006504#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 if (kill(pid, sig) == -1)
6506 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006507#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 Py_INCREF(Py_None);
6509 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006510}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006511#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006512
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006513#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006515"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006517
6518static PyObject *
6519posix_killpg(PyObject *self, PyObject *args)
6520{
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 int sig;
6522 pid_t pgid;
6523 /* XXX some man pages make the `pgid` parameter an int, others
6524 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6525 take the same type. Moreover, pid_t is always at least as wide as
6526 int (else compilation of this module fails), which is safe. */
6527 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6528 return NULL;
6529 if (killpg(pgid, sig) == -1)
6530 return posix_error();
6531 Py_INCREF(Py_None);
6532 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006533}
6534#endif
6535
Brian Curtineb24d742010-04-12 17:16:38 +00006536#ifdef MS_WINDOWS
6537PyDoc_STRVAR(win32_kill__doc__,
6538"kill(pid, sig)\n\n\
6539Kill a process with a signal.");
6540
6541static PyObject *
6542win32_kill(PyObject *self, PyObject *args)
6543{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006544 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 DWORD pid, sig, err;
6546 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006547
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6549 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006550
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 /* Console processes which share a common console can be sent CTRL+C or
6552 CTRL+BREAK events, provided they handle said events. */
6553 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6554 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6555 err = GetLastError();
6556 PyErr_SetFromWindowsErr(err);
6557 }
6558 else
6559 Py_RETURN_NONE;
6560 }
Brian Curtineb24d742010-04-12 17:16:38 +00006561
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6563 attempt to open and terminate the process. */
6564 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6565 if (handle == NULL) {
6566 err = GetLastError();
6567 return PyErr_SetFromWindowsErr(err);
6568 }
Brian Curtineb24d742010-04-12 17:16:38 +00006569
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (TerminateProcess(handle, sig) == 0) {
6571 err = GetLastError();
6572 result = PyErr_SetFromWindowsErr(err);
6573 } else {
6574 Py_INCREF(Py_None);
6575 result = Py_None;
6576 }
Brian Curtineb24d742010-04-12 17:16:38 +00006577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 CloseHandle(handle);
6579 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006580}
6581#endif /* MS_WINDOWS */
6582
Guido van Rossumc0125471996-06-28 18:55:32 +00006583#ifdef HAVE_PLOCK
6584
6585#ifdef HAVE_SYS_LOCK_H
6586#include <sys/lock.h>
6587#endif
6588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006589PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006590"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006591Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006592
Barry Warsaw53699e91996-12-10 23:23:01 +00006593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006594posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006595{
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 int op;
6597 if (!PyArg_ParseTuple(args, "i:plock", &op))
6598 return NULL;
6599 if (plock(op) == -1)
6600 return posix_error();
6601 Py_INCREF(Py_None);
6602 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006603}
6604#endif
6605
Guido van Rossumb6775db1994-08-01 11:34:53 +00006606#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006608"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006609Set the current process's user id.");
6610
Barry Warsaw53699e91996-12-10 23:23:01 +00006611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006612posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006613{
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 long uid_arg;
6615 uid_t uid;
6616 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6617 return NULL;
6618 uid = uid_arg;
6619 if (uid != uid_arg) {
6620 PyErr_SetString(PyExc_OverflowError, "user id too big");
6621 return NULL;
6622 }
6623 if (setuid(uid) < 0)
6624 return posix_error();
6625 Py_INCREF(Py_None);
6626 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006627}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006628#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006630
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006631#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006632PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006633"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006634Set the current process's effective user id.");
6635
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006636static PyObject *
6637posix_seteuid (PyObject *self, PyObject *args)
6638{
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 long euid_arg;
6640 uid_t euid;
6641 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6642 return NULL;
6643 euid = euid_arg;
6644 if (euid != euid_arg) {
6645 PyErr_SetString(PyExc_OverflowError, "user id too big");
6646 return NULL;
6647 }
6648 if (seteuid(euid) < 0) {
6649 return posix_error();
6650 } else {
6651 Py_INCREF(Py_None);
6652 return Py_None;
6653 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006654}
6655#endif /* HAVE_SETEUID */
6656
6657#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006659"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660Set the current process's effective group id.");
6661
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006662static PyObject *
6663posix_setegid (PyObject *self, PyObject *args)
6664{
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 long egid_arg;
6666 gid_t egid;
6667 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6668 return NULL;
6669 egid = egid_arg;
6670 if (egid != egid_arg) {
6671 PyErr_SetString(PyExc_OverflowError, "group id too big");
6672 return NULL;
6673 }
6674 if (setegid(egid) < 0) {
6675 return posix_error();
6676 } else {
6677 Py_INCREF(Py_None);
6678 return Py_None;
6679 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006680}
6681#endif /* HAVE_SETEGID */
6682
6683#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006685"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Set the current process's real and effective user ids.");
6687
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006688static PyObject *
6689posix_setreuid (PyObject *self, PyObject *args)
6690{
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 long ruid_arg, euid_arg;
6692 uid_t ruid, euid;
6693 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6694 return NULL;
6695 if (ruid_arg == -1)
6696 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6697 else
6698 ruid = ruid_arg; /* otherwise, assign from our long */
6699 if (euid_arg == -1)
6700 euid = (uid_t)-1;
6701 else
6702 euid = euid_arg;
6703 if ((euid_arg != -1 && euid != euid_arg) ||
6704 (ruid_arg != -1 && ruid != ruid_arg)) {
6705 PyErr_SetString(PyExc_OverflowError, "user id too big");
6706 return NULL;
6707 }
6708 if (setreuid(ruid, euid) < 0) {
6709 return posix_error();
6710 } else {
6711 Py_INCREF(Py_None);
6712 return Py_None;
6713 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETREUID */
6716
6717#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006719"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720Set the current process's real and effective group ids.");
6721
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006722static PyObject *
6723posix_setregid (PyObject *self, PyObject *args)
6724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 long rgid_arg, egid_arg;
6726 gid_t rgid, egid;
6727 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6728 return NULL;
6729 if (rgid_arg == -1)
6730 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6731 else
6732 rgid = rgid_arg; /* otherwise, assign from our long */
6733 if (egid_arg == -1)
6734 egid = (gid_t)-1;
6735 else
6736 egid = egid_arg;
6737 if ((egid_arg != -1 && egid != egid_arg) ||
6738 (rgid_arg != -1 && rgid != rgid_arg)) {
6739 PyErr_SetString(PyExc_OverflowError, "group id too big");
6740 return NULL;
6741 }
6742 if (setregid(rgid, egid) < 0) {
6743 return posix_error();
6744 } else {
6745 Py_INCREF(Py_None);
6746 return Py_None;
6747 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006748}
6749#endif /* HAVE_SETREGID */
6750
Guido van Rossumb6775db1994-08-01 11:34:53 +00006751#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006753"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006755
Barry Warsaw53699e91996-12-10 23:23:01 +00006756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006757posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006758{
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 long gid_arg;
6760 gid_t gid;
6761 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6762 return NULL;
6763 gid = gid_arg;
6764 if (gid != gid_arg) {
6765 PyErr_SetString(PyExc_OverflowError, "group id too big");
6766 return NULL;
6767 }
6768 if (setgid(gid) < 0)
6769 return posix_error();
6770 Py_INCREF(Py_None);
6771 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006772}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006773#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006774
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006775#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006776PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006777"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006778Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006779
6780static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006781posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006782{
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 int i, len;
6784 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006785
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (!PySequence_Check(groups)) {
6787 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6788 return NULL;
6789 }
6790 len = PySequence_Size(groups);
6791 if (len > MAX_GROUPS) {
6792 PyErr_SetString(PyExc_ValueError, "too many groups");
6793 return NULL;
6794 }
6795 for(i = 0; i < len; i++) {
6796 PyObject *elem;
6797 elem = PySequence_GetItem(groups, i);
6798 if (!elem)
6799 return NULL;
6800 if (!PyLong_Check(elem)) {
6801 PyErr_SetString(PyExc_TypeError,
6802 "groups must be integers");
6803 Py_DECREF(elem);
6804 return NULL;
6805 } else {
6806 unsigned long x = PyLong_AsUnsignedLong(elem);
6807 if (PyErr_Occurred()) {
6808 PyErr_SetString(PyExc_TypeError,
6809 "group id too big");
6810 Py_DECREF(elem);
6811 return NULL;
6812 }
6813 grouplist[i] = x;
6814 /* read back the value to see if it fitted in gid_t */
6815 if (grouplist[i] != x) {
6816 PyErr_SetString(PyExc_TypeError,
6817 "group id too big");
6818 Py_DECREF(elem);
6819 return NULL;
6820 }
6821 }
6822 Py_DECREF(elem);
6823 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006824
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 if (setgroups(len, grouplist) < 0)
6826 return posix_error();
6827 Py_INCREF(Py_None);
6828 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006829}
6830#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006831
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6833static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006834wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835{
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 PyObject *result;
6837 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006838 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (pid == -1)
6841 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 if (struct_rusage == NULL) {
6844 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6845 if (m == NULL)
6846 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006847 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 Py_DECREF(m);
6849 if (struct_rusage == NULL)
6850 return NULL;
6851 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6854 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6855 if (!result)
6856 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857
6858#ifndef doubletime
6859#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6860#endif
6861
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006863 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006865 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6868 SET_INT(result, 2, ru->ru_maxrss);
6869 SET_INT(result, 3, ru->ru_ixrss);
6870 SET_INT(result, 4, ru->ru_idrss);
6871 SET_INT(result, 5, ru->ru_isrss);
6872 SET_INT(result, 6, ru->ru_minflt);
6873 SET_INT(result, 7, ru->ru_majflt);
6874 SET_INT(result, 8, ru->ru_nswap);
6875 SET_INT(result, 9, ru->ru_inblock);
6876 SET_INT(result, 10, ru->ru_oublock);
6877 SET_INT(result, 11, ru->ru_msgsnd);
6878 SET_INT(result, 12, ru->ru_msgrcv);
6879 SET_INT(result, 13, ru->ru_nsignals);
6880 SET_INT(result, 14, ru->ru_nvcsw);
6881 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882#undef SET_INT
6883
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 if (PyErr_Occurred()) {
6885 Py_DECREF(result);
6886 return NULL;
6887 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890}
6891#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6892
6893#ifdef HAVE_WAIT3
6894PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006895"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896Wait for completion of a child process.");
6897
6898static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006899posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900{
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 pid_t pid;
6902 int options;
6903 struct rusage ru;
6904 WAIT_TYPE status;
6905 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006906
Victor Stinner4195b5c2012-02-08 23:03:19 +01006907 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 Py_BEGIN_ALLOW_THREADS
6911 pid = wait3(&status, options, &ru);
6912 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Victor Stinner4195b5c2012-02-08 23:03:19 +01006914 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT3 */
6917
6918#ifdef HAVE_WAIT4
6919PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006920"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921Wait for completion of a given child process.");
6922
6923static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006924posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925{
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 pid_t pid;
6927 int options;
6928 struct rusage ru;
6929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner4195b5c2012-02-08 23:03:19 +01006932 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 Py_BEGIN_ALLOW_THREADS
6936 pid = wait4(pid, &status, options, &ru);
6937 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006938
Victor Stinner4195b5c2012-02-08 23:03:19 +01006939 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940}
6941#endif /* HAVE_WAIT4 */
6942
Ross Lagerwall7807c352011-03-17 20:20:30 +02006943#if defined(HAVE_WAITID) && !defined(__APPLE__)
6944PyDoc_STRVAR(posix_waitid__doc__,
6945"waitid(idtype, id, options) -> waitid_result\n\n\
6946Wait for the completion of one or more child processes.\n\n\
6947idtype can be P_PID, P_PGID or P_ALL.\n\
6948id specifies the pid to wait on.\n\
6949options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6950or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6951Returns either waitid_result or None if WNOHANG is specified and there are\n\
6952no children in a waitable state.");
6953
6954static PyObject *
6955posix_waitid(PyObject *self, PyObject *args)
6956{
6957 PyObject *result;
6958 idtype_t idtype;
6959 id_t id;
6960 int options, res;
6961 siginfo_t si;
6962 si.si_pid = 0;
6963 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6964 return NULL;
6965 Py_BEGIN_ALLOW_THREADS
6966 res = waitid(idtype, id, &si, options);
6967 Py_END_ALLOW_THREADS
6968 if (res == -1)
6969 return posix_error();
6970
6971 if (si.si_pid == 0)
6972 Py_RETURN_NONE;
6973
6974 result = PyStructSequence_New(&WaitidResultType);
6975 if (!result)
6976 return NULL;
6977
6978 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6979 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6980 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6981 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6982 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6983 if (PyErr_Occurred()) {
6984 Py_DECREF(result);
6985 return NULL;
6986 }
6987
6988 return result;
6989}
6990#endif
6991
Guido van Rossumb6775db1994-08-01 11:34:53 +00006992#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006993PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006994"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006995Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006996
Barry Warsaw53699e91996-12-10 23:23:01 +00006997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006998posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006999{
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 pid_t pid;
7001 int options;
7002 WAIT_TYPE status;
7003 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007004
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7006 return NULL;
7007 Py_BEGIN_ALLOW_THREADS
7008 pid = waitpid(pid, &status, options);
7009 Py_END_ALLOW_THREADS
7010 if (pid == -1)
7011 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007012
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007014}
7015
Tim Petersab034fa2002-02-01 11:27:43 +00007016#elif defined(HAVE_CWAIT)
7017
7018/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007019PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007020"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007022
7023static PyObject *
7024posix_waitpid(PyObject *self, PyObject *args)
7025{
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 Py_intptr_t pid;
7027 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007028
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7030 return NULL;
7031 Py_BEGIN_ALLOW_THREADS
7032 pid = _cwait(&status, pid, options);
7033 Py_END_ALLOW_THREADS
7034 if (pid == -1)
7035 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007036
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 /* shift the status left a byte so this is more like the POSIX waitpid */
7038 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007039}
7040#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007041
Guido van Rossumad0ee831995-03-01 10:34:45 +00007042#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007043PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007044"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007045Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007046
Barry Warsaw53699e91996-12-10 23:23:01 +00007047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007048posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007049{
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 pid_t pid;
7051 WAIT_TYPE status;
7052 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007053
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 Py_BEGIN_ALLOW_THREADS
7055 pid = wait(&status);
7056 Py_END_ALLOW_THREADS
7057 if (pid == -1)
7058 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007059
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007061}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007062#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007064
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7066PyDoc_STRVAR(readlink__doc__,
7067"readlink(path, *, dir_fd=None) -> path\n\n\
7068Return a string representing the path to which the symbolic link points.\n\
7069\n\
7070If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7071 and path should be relative; path will then be relative to that directory.\n\
7072dir_fd may not be implemented on your platform.\n\
7073 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007074#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Guido van Rossumb6775db1994-08-01 11:34:53 +00007076#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Barry Warsaw53699e91996-12-10 23:23:01 +00007078static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007079posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007080{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081 path_t path;
7082 int dir_fd = DEFAULT_DIR_FD;
7083 char buffer[MAXPATHLEN];
7084 ssize_t length;
7085 PyObject *return_value = NULL;
7086 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007087
Larry Hastings9cf065c2012-06-22 16:30:09 -07007088 memset(&path, 0, sizeof(path));
7089 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7090 path_converter, &path,
7091#ifdef HAVE_READLINKAT
7092 dir_fd_converter, &dir_fd
7093#else
7094 dir_fd_unavailable, &dir_fd
7095#endif
7096 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007098
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007100#ifdef HAVE_READLINKAT
7101 if (dir_fd != DEFAULT_DIR_FD)
7102 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007103 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007104#endif
7105 length = readlink(path.narrow, buffer, sizeof(buffer));
7106 Py_END_ALLOW_THREADS
7107
7108 if (length < 0) {
7109 return_value = path_posix_error("readlink", &path);
7110 goto exit;
7111 }
7112
7113 if (PyUnicode_Check(path.object))
7114 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7115 else
7116 return_value = PyBytes_FromStringAndSize(buffer, length);
7117exit:
7118 path_cleanup(&path);
7119 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007120}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121
7122
Guido van Rossumb6775db1994-08-01 11:34:53 +00007123#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007125
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7129Create a symbolic link pointing to src named dst.\n\n\
7130target_is_directory is required on Windows if the target is to be\n\
7131 interpreted as a directory. (On Windows, symlink requires\n\
7132 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7133 target_is_directory is ignored on non-Windows platforms.\n\
7134\n\
7135If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7136 and path should be relative; path will then be relative to that directory.\n\
7137dir_fd may not be implemented on your platform.\n\
7138 If it is unavailable, using it will raise a NotImplementedError.");
7139
7140#if defined(MS_WINDOWS)
7141
7142/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7143static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7144static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7145static int
7146check_CreateSymbolicLink()
7147{
7148 HINSTANCE hKernel32;
7149 /* only recheck */
7150 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7151 return 1;
7152 hKernel32 = GetModuleHandleW(L"KERNEL32");
7153 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7154 "CreateSymbolicLinkW");
7155 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7156 "CreateSymbolicLinkA");
7157 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7158}
7159
7160#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007161
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007162static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007164{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007165 path_t src;
7166 path_t dst;
7167 int dir_fd = DEFAULT_DIR_FD;
7168 int target_is_directory = 0;
7169 static char *keywords[] = {"src", "dst", "target_is_directory",
7170 "dir_fd", NULL};
7171 PyObject *return_value;
7172#ifdef MS_WINDOWS
7173 DWORD result;
7174#else
7175 int result;
7176#endif
7177
7178 memset(&src, 0, sizeof(src));
7179 src.argument_name = "src";
7180 memset(&dst, 0, sizeof(dst));
7181 dst.argument_name = "dst";
7182
7183#ifdef MS_WINDOWS
7184 if (!check_CreateSymbolicLink()) {
7185 PyErr_SetString(PyExc_NotImplementedError,
7186 "CreateSymbolicLink functions not found");
7187 return NULL;
7188 }
7189 if (!win32_can_symlink) {
7190 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7191 return NULL;
7192 }
7193#endif
7194
7195 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7196 keywords,
7197 path_converter, &src,
7198 path_converter, &dst,
7199 &target_is_directory,
7200#ifdef HAVE_SYMLINKAT
7201 dir_fd_converter, &dir_fd
7202#else
7203 dir_fd_unavailable, &dir_fd
7204#endif
7205 ))
7206 return NULL;
7207
7208 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7209 PyErr_SetString(PyExc_ValueError,
7210 "symlink: src and dst must be the same type");
7211 return_value = NULL;
7212 goto exit;
7213 }
7214
7215#ifdef MS_WINDOWS
7216 Py_BEGIN_ALLOW_THREADS
7217 if (dst.wide)
7218 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7219 target_is_directory);
7220 else
7221 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7222 target_is_directory);
7223 Py_END_ALLOW_THREADS
7224
7225 if (!result) {
7226 return_value = win32_error_object("symlink", src.object);
7227 goto exit;
7228 }
7229
7230#else
7231
7232 Py_BEGIN_ALLOW_THREADS
7233#if HAVE_SYMLINKAT
7234 if (dir_fd != DEFAULT_DIR_FD)
7235 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7236 else
7237#endif
7238 result = symlink(src.narrow, dst.narrow);
7239 Py_END_ALLOW_THREADS
7240
7241 if (result) {
7242 return_value = path_error("symlink", &dst);
7243 goto exit;
7244 }
7245#endif
7246
7247 return_value = Py_None;
7248 Py_INCREF(Py_None);
7249 goto exit; /* silence "unused label" warning */
7250exit:
7251 path_cleanup(&src);
7252 path_cleanup(&dst);
7253 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007254}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007256#endif /* HAVE_SYMLINK */
7257
Larry Hastings9cf065c2012-06-22 16:30:09 -07007258
Brian Curtind40e6f72010-07-08 21:39:08 +00007259#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7260
Brian Curtind40e6f72010-07-08 21:39:08 +00007261static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007263{
7264 wchar_t *path;
7265 DWORD n_bytes_returned;
7266 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007267 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007268 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007269 HANDLE reparse_point_handle;
7270
7271 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7272 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7273 wchar_t *print_name;
7274
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 static char *keywords[] = {"path", "dir_fd", NULL};
7276
7277 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7278 &po,
7279 dir_fd_unavailable, &dir_fd
7280 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007281 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007282
Victor Stinnereb5657a2011-09-30 01:44:27 +02007283 path = PyUnicode_AsUnicode(po);
7284 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007285 return NULL;
7286
7287 /* First get a handle to the reparse point */
7288 Py_BEGIN_ALLOW_THREADS
7289 reparse_point_handle = CreateFileW(
7290 path,
7291 0,
7292 0,
7293 0,
7294 OPEN_EXISTING,
7295 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7296 0);
7297 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007298
Brian Curtind40e6f72010-07-08 21:39:08 +00007299 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007300 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007301
Brian Curtind40e6f72010-07-08 21:39:08 +00007302 Py_BEGIN_ALLOW_THREADS
7303 /* New call DeviceIoControl to read the reparse point */
7304 io_result = DeviceIoControl(
7305 reparse_point_handle,
7306 FSCTL_GET_REPARSE_POINT,
7307 0, 0, /* in buffer */
7308 target_buffer, sizeof(target_buffer),
7309 &n_bytes_returned,
7310 0 /* we're not using OVERLAPPED_IO */
7311 );
7312 CloseHandle(reparse_point_handle);
7313 Py_END_ALLOW_THREADS
7314
7315 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007316 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007317
7318 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7319 {
7320 PyErr_SetString(PyExc_ValueError,
7321 "not a symbolic link");
7322 return NULL;
7323 }
Brian Curtin74e45612010-07-09 15:58:59 +00007324 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7325 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7326
7327 result = PyUnicode_FromWideChar(print_name,
7328 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007329 return result;
7330}
7331
7332#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7333
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007334
7335#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007336#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7337static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007338system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339{
7340 ULONG value = 0;
7341
7342 Py_BEGIN_ALLOW_THREADS
7343 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7344 Py_END_ALLOW_THREADS
7345
7346 return value;
7347}
7348
7349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007350posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007351{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007352 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00007353 return Py_BuildValue("ddddd",
7354 (double)0 /* t.tms_utime / HZ */,
7355 (double)0 /* t.tms_stime / HZ */,
7356 (double)0 /* t.tms_cutime / HZ */,
7357 (double)0 /* t.tms_cstime / HZ */,
7358 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007359}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007360#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007361#define NEED_TICKS_PER_SECOND
7362static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007363static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007364posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007365{
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 struct tms t;
7367 clock_t c;
7368 errno = 0;
7369 c = times(&t);
7370 if (c == (clock_t) -1)
7371 return posix_error();
7372 return Py_BuildValue("ddddd",
7373 (double)t.tms_utime / ticks_per_second,
7374 (double)t.tms_stime / ticks_per_second,
7375 (double)t.tms_cutime / ticks_per_second,
7376 (double)t.tms_cstime / ticks_per_second,
7377 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007378}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007379#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007380#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007381
7382
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007383#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007384#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00007385static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007386posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007387{
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 FILETIME create, exit, kernel, user;
7389 HANDLE hProc;
7390 hProc = GetCurrentProcess();
7391 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7392 /* The fields of a FILETIME structure are the hi and lo part
7393 of a 64-bit value expressed in 100 nanosecond units.
7394 1e7 is one second in such units; 1e-7 the inverse.
7395 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7396 */
7397 return Py_BuildValue(
7398 "ddddd",
7399 (double)(user.dwHighDateTime*429.4967296 +
7400 user.dwLowDateTime*1e-7),
7401 (double)(kernel.dwHighDateTime*429.4967296 +
7402 kernel.dwLowDateTime*1e-7),
7403 (double)0,
7404 (double)0,
7405 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007406}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007407#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007408
7409#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007410PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007411"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007412Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007413#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007415
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007416#ifdef HAVE_GETSID
7417PyDoc_STRVAR(posix_getsid__doc__,
7418"getsid(pid) -> sid\n\n\
7419Call the system call getsid().");
7420
7421static PyObject *
7422posix_getsid(PyObject *self, PyObject *args)
7423{
Victor Stinner8c62be82010-05-06 00:08:46 +00007424 pid_t pid;
7425 int sid;
7426 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7427 return NULL;
7428 sid = getsid(pid);
7429 if (sid < 0)
7430 return posix_error();
7431 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007432}
7433#endif /* HAVE_GETSID */
7434
7435
Guido van Rossumb6775db1994-08-01 11:34:53 +00007436#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007437PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007438"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007439Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007440
Barry Warsaw53699e91996-12-10 23:23:01 +00007441static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007442posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007443{
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 if (setsid() < 0)
7445 return posix_error();
7446 Py_INCREF(Py_None);
7447 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007448}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007449#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007450
Guido van Rossumb6775db1994-08-01 11:34:53 +00007451#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007452PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007453"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007454Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007455
Barry Warsaw53699e91996-12-10 23:23:01 +00007456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007457posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007458{
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 pid_t pid;
7460 int pgrp;
7461 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7462 return NULL;
7463 if (setpgid(pid, pgrp) < 0)
7464 return posix_error();
7465 Py_INCREF(Py_None);
7466 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007467}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007468#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007470
Guido van Rossumb6775db1994-08-01 11:34:53 +00007471#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007472PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007473"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007474Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007475
Barry Warsaw53699e91996-12-10 23:23:01 +00007476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007477posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007478{
Victor Stinner8c62be82010-05-06 00:08:46 +00007479 int fd;
7480 pid_t pgid;
7481 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7482 return NULL;
7483 pgid = tcgetpgrp(fd);
7484 if (pgid < 0)
7485 return posix_error();
7486 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007487}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007488#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007490
Guido van Rossumb6775db1994-08-01 11:34:53 +00007491#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007492PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007493"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007494Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007495
Barry Warsaw53699e91996-12-10 23:23:01 +00007496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007497posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007498{
Victor Stinner8c62be82010-05-06 00:08:46 +00007499 int fd;
7500 pid_t pgid;
7501 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7502 return NULL;
7503 if (tcsetpgrp(fd, pgid) < 0)
7504 return posix_error();
7505 Py_INCREF(Py_None);
7506 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007507}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007508#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007509
Guido van Rossum687dd131993-05-17 08:34:16 +00007510/* Functions acting on file descriptors */
7511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007512PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007513"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7514Open a file for low level IO. Returns a file handle (integer).\n\
7515\n\
7516If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7517 and path should be relative; path will then be relative to that directory.\n\
7518dir_fd may not be implemented on your platform.\n\
7519 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007520
Barry Warsaw53699e91996-12-10 23:23:01 +00007521static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007522posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007523{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007524 path_t path;
7525 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007527 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007529 PyObject *return_value = NULL;
7530 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007531
Larry Hastings9cf065c2012-06-22 16:30:09 -07007532 memset(&path, 0, sizeof(path));
7533 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7534 path_converter, &path,
7535 &flags, &mode,
7536#ifdef HAVE_OPENAT
7537 dir_fd_converter, &dir_fd
7538#else
7539 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007540#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007541 ))
7542 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007543
Victor Stinner8c62be82010-05-06 00:08:46 +00007544 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007545#ifdef MS_WINDOWS
7546 if (path.wide)
7547 fd = _wopen(path.wide, flags, mode);
7548 else
7549#endif
7550#ifdef HAVE_OPENAT
7551 if (dir_fd != DEFAULT_DIR_FD)
7552 fd = openat(dir_fd, path.narrow, flags, mode);
7553 else
7554#endif
7555 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007557
Larry Hastings9cf065c2012-06-22 16:30:09 -07007558 if (fd == -1) {
7559#ifdef MS_WINDOWS
7560 /* force use of posix_error here for exact backwards compatibility */
7561 if (path.wide)
7562 return_value = posix_error();
7563 else
7564#endif
7565 return_value = path_error("open", &path);
7566 goto exit;
7567 }
7568
7569 return_value = PyLong_FromLong((long)fd);
7570
7571exit:
7572 path_cleanup(&path);
7573 return return_value;
7574}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007576PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007577"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007578Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007579
Barry Warsaw53699e91996-12-10 23:23:01 +00007580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007581posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007582{
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 int fd, res;
7584 if (!PyArg_ParseTuple(args, "i:close", &fd))
7585 return NULL;
7586 if (!_PyVerify_fd(fd))
7587 return posix_error();
7588 Py_BEGIN_ALLOW_THREADS
7589 res = close(fd);
7590 Py_END_ALLOW_THREADS
7591 if (res < 0)
7592 return posix_error();
7593 Py_INCREF(Py_None);
7594 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007595}
7596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007597
Victor Stinner8c62be82010-05-06 00:08:46 +00007598PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007599"closerange(fd_low, fd_high)\n\n\
7600Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7601
7602static PyObject *
7603posix_closerange(PyObject *self, PyObject *args)
7604{
Victor Stinner8c62be82010-05-06 00:08:46 +00007605 int fd_from, fd_to, i;
7606 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7607 return NULL;
7608 Py_BEGIN_ALLOW_THREADS
7609 for (i = fd_from; i < fd_to; i++)
7610 if (_PyVerify_fd(i))
7611 close(i);
7612 Py_END_ALLOW_THREADS
7613 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007614}
7615
7616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007617PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007618"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007619Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007620
Barry Warsaw53699e91996-12-10 23:23:01 +00007621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007622posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007623{
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 int fd;
7625 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7626 return NULL;
7627 if (!_PyVerify_fd(fd))
7628 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007630 if (fd < 0)
7631 return posix_error();
7632 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007633}
7634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007636PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007637"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007638Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007639
Barry Warsaw53699e91996-12-10 23:23:01 +00007640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007641posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007642{
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 int fd, fd2, res;
7644 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7645 return NULL;
7646 if (!_PyVerify_fd_dup2(fd, fd2))
7647 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 if (res < 0)
7650 return posix_error();
7651 Py_INCREF(Py_None);
7652 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007653}
7654
Ross Lagerwall7807c352011-03-17 20:20:30 +02007655#ifdef HAVE_LOCKF
7656PyDoc_STRVAR(posix_lockf__doc__,
7657"lockf(fd, cmd, len)\n\n\
7658Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7659fd is an open file descriptor.\n\
7660cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7661F_TEST.\n\
7662len specifies the section of the file to lock.");
7663
7664static PyObject *
7665posix_lockf(PyObject *self, PyObject *args)
7666{
7667 int fd, cmd, res;
7668 off_t len;
7669 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7670 &fd, &cmd, _parse_off_t, &len))
7671 return NULL;
7672
7673 Py_BEGIN_ALLOW_THREADS
7674 res = lockf(fd, cmd, len);
7675 Py_END_ALLOW_THREADS
7676
7677 if (res < 0)
7678 return posix_error();
7679
7680 Py_RETURN_NONE;
7681}
7682#endif
7683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007685PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007686"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007687Set the current position of a file descriptor.\n\
7688Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007689
Barry Warsaw53699e91996-12-10 23:23:01 +00007690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007691posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007692{
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007694#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007696#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007697 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007698#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007699 PyObject *posobj;
7700 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007702#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7704 switch (how) {
7705 case 0: how = SEEK_SET; break;
7706 case 1: how = SEEK_CUR; break;
7707 case 2: how = SEEK_END; break;
7708 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007709#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007710
Ross Lagerwall8e749672011-03-17 21:54:07 +02007711#if !defined(HAVE_LARGEFILE_SUPPORT)
7712 pos = PyLong_AsLong(posobj);
7713#else
7714 pos = PyLong_AsLongLong(posobj);
7715#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 if (PyErr_Occurred())
7717 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007718
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 if (!_PyVerify_fd(fd))
7720 return posix_error();
7721 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007722#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007724#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007726#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 Py_END_ALLOW_THREADS
7728 if (res < 0)
7729 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007730
7731#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007733#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007735#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007736}
7737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007739PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007740"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007741Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007742
Barry Warsaw53699e91996-12-10 23:23:01 +00007743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007744posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007745{
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 int fd, size;
7747 Py_ssize_t n;
7748 PyObject *buffer;
7749 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7750 return NULL;
7751 if (size < 0) {
7752 errno = EINVAL;
7753 return posix_error();
7754 }
7755 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7756 if (buffer == NULL)
7757 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007758 if (!_PyVerify_fd(fd)) {
7759 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007761 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 Py_BEGIN_ALLOW_THREADS
7763 n = read(fd, PyBytes_AS_STRING(buffer), size);
7764 Py_END_ALLOW_THREADS
7765 if (n < 0) {
7766 Py_DECREF(buffer);
7767 return posix_error();
7768 }
7769 if (n != size)
7770 _PyBytes_Resize(&buffer, n);
7771 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007772}
7773
Ross Lagerwall7807c352011-03-17 20:20:30 +02007774#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7775 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007776static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007777iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7778{
7779 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007780 Py_ssize_t blen, total = 0;
7781
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007782 *iov = PyMem_New(struct iovec, cnt);
7783 if (*iov == NULL) {
7784 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007785 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007786 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007787
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007788 *buf = PyMem_New(Py_buffer, cnt);
7789 if (*buf == NULL) {
7790 PyMem_Del(*iov);
7791 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007792 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007793 }
7794
7795 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007796 PyObject *item = PySequence_GetItem(seq, i);
7797 if (item == NULL)
7798 goto fail;
7799 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7800 Py_DECREF(item);
7801 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007802 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007803 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007804 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007805 blen = (*buf)[i].len;
7806 (*iov)[i].iov_len = blen;
7807 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007808 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007809 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007810
7811fail:
7812 PyMem_Del(*iov);
7813 for (j = 0; j < i; j++) {
7814 PyBuffer_Release(&(*buf)[j]);
7815 }
7816 PyMem_Del(*buf);
7817 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007818}
7819
7820static void
7821iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7822{
7823 int i;
7824 PyMem_Del(iov);
7825 for (i = 0; i < cnt; i++) {
7826 PyBuffer_Release(&buf[i]);
7827 }
7828 PyMem_Del(buf);
7829}
7830#endif
7831
Ross Lagerwall7807c352011-03-17 20:20:30 +02007832#ifdef HAVE_READV
7833PyDoc_STRVAR(posix_readv__doc__,
7834"readv(fd, buffers) -> bytesread\n\n\
7835Read from a file descriptor into a number of writable buffers. buffers\n\
7836is an arbitrary sequence of writable buffers.\n\
7837Returns the total number of bytes read.");
7838
7839static PyObject *
7840posix_readv(PyObject *self, PyObject *args)
7841{
7842 int fd, cnt;
7843 Py_ssize_t n;
7844 PyObject *seq;
7845 struct iovec *iov;
7846 Py_buffer *buf;
7847
7848 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7849 return NULL;
7850 if (!PySequence_Check(seq)) {
7851 PyErr_SetString(PyExc_TypeError,
7852 "readv() arg 2 must be a sequence");
7853 return NULL;
7854 }
7855 cnt = PySequence_Size(seq);
7856
7857 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7858 return NULL;
7859
7860 Py_BEGIN_ALLOW_THREADS
7861 n = readv(fd, iov, cnt);
7862 Py_END_ALLOW_THREADS
7863
7864 iov_cleanup(iov, buf, cnt);
7865 return PyLong_FromSsize_t(n);
7866}
7867#endif
7868
7869#ifdef HAVE_PREAD
7870PyDoc_STRVAR(posix_pread__doc__,
7871"pread(fd, buffersize, offset) -> string\n\n\
7872Read from a file descriptor, fd, at a position of offset. It will read up\n\
7873to buffersize number of bytes. The file offset remains unchanged.");
7874
7875static PyObject *
7876posix_pread(PyObject *self, PyObject *args)
7877{
7878 int fd, size;
7879 off_t offset;
7880 Py_ssize_t n;
7881 PyObject *buffer;
7882 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7883 return NULL;
7884
7885 if (size < 0) {
7886 errno = EINVAL;
7887 return posix_error();
7888 }
7889 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7890 if (buffer == NULL)
7891 return NULL;
7892 if (!_PyVerify_fd(fd)) {
7893 Py_DECREF(buffer);
7894 return posix_error();
7895 }
7896 Py_BEGIN_ALLOW_THREADS
7897 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7898 Py_END_ALLOW_THREADS
7899 if (n < 0) {
7900 Py_DECREF(buffer);
7901 return posix_error();
7902 }
7903 if (n != size)
7904 _PyBytes_Resize(&buffer, n);
7905 return buffer;
7906}
7907#endif
7908
7909PyDoc_STRVAR(posix_write__doc__,
7910"write(fd, string) -> byteswritten\n\n\
7911Write a string to a file descriptor.");
7912
7913static PyObject *
7914posix_write(PyObject *self, PyObject *args)
7915{
7916 Py_buffer pbuf;
7917 int fd;
7918 Py_ssize_t size, len;
7919
7920 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7921 return NULL;
7922 if (!_PyVerify_fd(fd)) {
7923 PyBuffer_Release(&pbuf);
7924 return posix_error();
7925 }
7926 len = pbuf.len;
7927 Py_BEGIN_ALLOW_THREADS
7928#if defined(MS_WIN64) || defined(MS_WINDOWS)
7929 if (len > INT_MAX)
7930 len = INT_MAX;
7931 size = write(fd, pbuf.buf, (int)len);
7932#else
7933 size = write(fd, pbuf.buf, len);
7934#endif
7935 Py_END_ALLOW_THREADS
7936 PyBuffer_Release(&pbuf);
7937 if (size < 0)
7938 return posix_error();
7939 return PyLong_FromSsize_t(size);
7940}
7941
7942#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007943PyDoc_STRVAR(posix_sendfile__doc__,
7944"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7945sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7946 -> byteswritten\n\
7947Copy nbytes bytes from file descriptor in to file descriptor out.");
7948
7949static PyObject *
7950posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7951{
7952 int in, out;
7953 Py_ssize_t ret;
7954 off_t offset;
7955
7956#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7957#ifndef __APPLE__
7958 Py_ssize_t len;
7959#endif
7960 PyObject *headers = NULL, *trailers = NULL;
7961 Py_buffer *hbuf, *tbuf;
7962 off_t sbytes;
7963 struct sf_hdtr sf;
7964 int flags = 0;
7965 sf.headers = NULL;
7966 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007967 static char *keywords[] = {"out", "in",
7968 "offset", "count",
7969 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007970
7971#ifdef __APPLE__
7972 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007973 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007974#else
7975 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007976 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007977#endif
7978 &headers, &trailers, &flags))
7979 return NULL;
7980 if (headers != NULL) {
7981 if (!PySequence_Check(headers)) {
7982 PyErr_SetString(PyExc_TypeError,
7983 "sendfile() headers must be a sequence or None");
7984 return NULL;
7985 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007986 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007987 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007988 if (sf.hdr_cnt > 0 &&
7989 !(i = iov_setup(&(sf.headers), &hbuf,
7990 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007991 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007992#ifdef __APPLE__
7993 sbytes += i;
7994#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007995 }
7996 }
7997 if (trailers != NULL) {
7998 if (!PySequence_Check(trailers)) {
7999 PyErr_SetString(PyExc_TypeError,
8000 "sendfile() trailers must be a sequence or None");
8001 return NULL;
8002 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008003 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008004 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008005 if (sf.trl_cnt > 0 &&
8006 !(i = iov_setup(&(sf.trailers), &tbuf,
8007 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008008 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008009#ifdef __APPLE__
8010 sbytes += i;
8011#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012 }
8013 }
8014
8015 Py_BEGIN_ALLOW_THREADS
8016#ifdef __APPLE__
8017 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8018#else
8019 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8020#endif
8021 Py_END_ALLOW_THREADS
8022
8023 if (sf.headers != NULL)
8024 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8025 if (sf.trailers != NULL)
8026 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8027
8028 if (ret < 0) {
8029 if ((errno == EAGAIN) || (errno == EBUSY)) {
8030 if (sbytes != 0) {
8031 // some data has been sent
8032 goto done;
8033 }
8034 else {
8035 // no data has been sent; upper application is supposed
8036 // to retry on EAGAIN or EBUSY
8037 return posix_error();
8038 }
8039 }
8040 return posix_error();
8041 }
8042 goto done;
8043
8044done:
8045 #if !defined(HAVE_LARGEFILE_SUPPORT)
8046 return Py_BuildValue("l", sbytes);
8047 #else
8048 return Py_BuildValue("L", sbytes);
8049 #endif
8050
8051#else
8052 Py_ssize_t count;
8053 PyObject *offobj;
8054 static char *keywords[] = {"out", "in",
8055 "offset", "count", NULL};
8056 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8057 keywords, &out, &in, &offobj, &count))
8058 return NULL;
8059#ifdef linux
8060 if (offobj == Py_None) {
8061 Py_BEGIN_ALLOW_THREADS
8062 ret = sendfile(out, in, NULL, count);
8063 Py_END_ALLOW_THREADS
8064 if (ret < 0)
8065 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008066 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067 }
8068#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008069 if (!_parse_off_t(offobj, &offset))
8070 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 Py_BEGIN_ALLOW_THREADS
8072 ret = sendfile(out, in, &offset, count);
8073 Py_END_ALLOW_THREADS
8074 if (ret < 0)
8075 return posix_error();
8076 return Py_BuildValue("n", ret);
8077#endif
8078}
8079#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008081PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008082"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008083Like stat(), but for an open file descriptor.\n\
8084Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008085
Barry Warsaw53699e91996-12-10 23:23:01 +00008086static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008087posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008088{
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 int fd;
8090 STRUCT_STAT st;
8091 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008092 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008094#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 /* on OpenVMS we must ensure that all bytes are written to the file */
8096 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008097#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 if (!_PyVerify_fd(fd))
8099 return posix_error();
8100 Py_BEGIN_ALLOW_THREADS
8101 res = FSTAT(fd, &st);
8102 Py_END_ALLOW_THREADS
8103 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008104#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008106#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008108#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 }
Tim Peters5aa91602002-01-30 05:46:57 +00008110
Victor Stinner4195b5c2012-02-08 23:03:19 +01008111 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008112}
8113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008114PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008115"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008116Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008117connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008118
8119static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008120posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008121{
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 int fd;
8123 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8124 return NULL;
8125 if (!_PyVerify_fd(fd))
8126 return PyBool_FromLong(0);
8127 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008128}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008129
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008130#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008131PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008132"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008133Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008134
Barry Warsaw53699e91996-12-10 23:23:01 +00008135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008136posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008137{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008138#if defined(PYOS_OS2)
8139 HFILE read, write;
8140 APIRET rc;
8141
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008142 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008143 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008144 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008145
8146 return Py_BuildValue("(ii)", read, write);
8147#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008148#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 int fds[2];
8150 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 if (res != 0)
8153 return posix_error();
8154 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008155#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 HANDLE read, write;
8157 int read_fd, write_fd;
8158 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (!ok)
8161 return win32_error("CreatePipe", NULL);
8162 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8163 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8164 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008165#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008166#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008167}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008168#endif /* HAVE_PIPE */
8169
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008170#ifdef HAVE_PIPE2
8171PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008172"pipe2(flags) -> (read_end, write_end)\n\n\
8173Create a pipe with flags set atomically.\n\
8174flags can be constructed by ORing together one or more of these values:\n\
8175O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008176");
8177
8178static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008179posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008180{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008181 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008182 int fds[2];
8183 int res;
8184
Charles-François Natali368f34b2011-06-06 19:49:47 +02008185 flags = PyLong_AsLong(arg);
8186 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008187 return NULL;
8188
8189 res = pipe2(fds, flags);
8190 if (res != 0)
8191 return posix_error();
8192 return Py_BuildValue("(ii)", fds[0], fds[1]);
8193}
8194#endif /* HAVE_PIPE2 */
8195
Ross Lagerwall7807c352011-03-17 20:20:30 +02008196#ifdef HAVE_WRITEV
8197PyDoc_STRVAR(posix_writev__doc__,
8198"writev(fd, buffers) -> byteswritten\n\n\
8199Write the contents of buffers to a file descriptor, where buffers is an\n\
8200arbitrary sequence of buffers.\n\
8201Returns the total bytes written.");
8202
8203static PyObject *
8204posix_writev(PyObject *self, PyObject *args)
8205{
8206 int fd, cnt;
8207 Py_ssize_t res;
8208 PyObject *seq;
8209 struct iovec *iov;
8210 Py_buffer *buf;
8211 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8212 return NULL;
8213 if (!PySequence_Check(seq)) {
8214 PyErr_SetString(PyExc_TypeError,
8215 "writev() arg 2 must be a sequence");
8216 return NULL;
8217 }
8218 cnt = PySequence_Size(seq);
8219
8220 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8221 return NULL;
8222 }
8223
8224 Py_BEGIN_ALLOW_THREADS
8225 res = writev(fd, iov, cnt);
8226 Py_END_ALLOW_THREADS
8227
8228 iov_cleanup(iov, buf, cnt);
8229 return PyLong_FromSsize_t(res);
8230}
8231#endif
8232
8233#ifdef HAVE_PWRITE
8234PyDoc_STRVAR(posix_pwrite__doc__,
8235"pwrite(fd, string, offset) -> byteswritten\n\n\
8236Write string to a file descriptor, fd, from offset, leaving the file\n\
8237offset unchanged.");
8238
8239static PyObject *
8240posix_pwrite(PyObject *self, PyObject *args)
8241{
8242 Py_buffer pbuf;
8243 int fd;
8244 off_t offset;
8245 Py_ssize_t size;
8246
8247 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8248 return NULL;
8249
8250 if (!_PyVerify_fd(fd)) {
8251 PyBuffer_Release(&pbuf);
8252 return posix_error();
8253 }
8254 Py_BEGIN_ALLOW_THREADS
8255 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8256 Py_END_ALLOW_THREADS
8257 PyBuffer_Release(&pbuf);
8258 if (size < 0)
8259 return posix_error();
8260 return PyLong_FromSsize_t(size);
8261}
8262#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008263
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008264#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008265PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008266"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8267Create a FIFO (a POSIX named pipe).\n\
8268\n\
8269If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8270 and path should be relative; path will then be relative to that directory.\n\
8271dir_fd may not be implemented on your platform.\n\
8272 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008273
Barry Warsaw53699e91996-12-10 23:23:01 +00008274static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008275posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008276{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008277 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008279 int dir_fd = DEFAULT_DIR_FD;
8280 int result;
8281 PyObject *return_value = NULL;
8282 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8283
8284 memset(&path, 0, sizeof(path));
8285 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8286 path_converter, &path,
8287 &mode,
8288#ifdef HAVE_MKFIFOAT
8289 dir_fd_converter, &dir_fd
8290#else
8291 dir_fd_unavailable, &dir_fd
8292#endif
8293 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008294 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008295
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008297#ifdef HAVE_MKFIFOAT
8298 if (dir_fd != DEFAULT_DIR_FD)
8299 result = mkfifoat(dir_fd, path.narrow, mode);
8300 else
8301#endif
8302 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008304
8305 if (result < 0) {
8306 return_value = posix_error();
8307 goto exit;
8308 }
8309
8310 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008312
8313exit:
8314 path_cleanup(&path);
8315 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008316}
8317#endif
8318
Neal Norwitz11690112002-07-30 01:08:28 +00008319#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008320PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008321"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008322Create a filesystem node (file, device special file or named pipe)\n\
8323named filename. mode specifies both the permissions to use and the\n\
8324type of node to be created, being combined (bitwise OR) with one of\n\
8325S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008326device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008327os.makedev()), otherwise it is ignored.\n\
8328\n\
8329If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8330 and path should be relative; path will then be relative to that directory.\n\
8331dir_fd may not be implemented on your platform.\n\
8332 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008333
8334
8335static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008336posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008337{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008338 path_t path;
8339 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 int dir_fd = DEFAULT_DIR_FD;
8342 int result;
8343 PyObject *return_value = NULL;
8344 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8345
8346 memset(&path, 0, sizeof(path));
8347 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8348 path_converter, &path,
8349 &mode, &device,
8350#ifdef HAVE_MKNODAT
8351 dir_fd_converter, &dir_fd
8352#else
8353 dir_fd_unavailable, &dir_fd
8354#endif
8355 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008357
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008359#ifdef HAVE_MKNODAT
8360 if (dir_fd != DEFAULT_DIR_FD)
8361 result = mknodat(dir_fd, path.narrow, mode, device);
8362 else
8363#endif
8364 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008366
8367 if (result < 0) {
8368 return_value = posix_error();
8369 goto exit;
8370 }
8371
8372 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008374
8375exit:
8376 path_cleanup(&path);
8377 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008378}
8379#endif
8380
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008381#ifdef HAVE_DEVICE_MACROS
8382PyDoc_STRVAR(posix_major__doc__,
8383"major(device) -> major number\n\
8384Extracts a device major number from a raw device number.");
8385
8386static PyObject *
8387posix_major(PyObject *self, PyObject *args)
8388{
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 int device;
8390 if (!PyArg_ParseTuple(args, "i:major", &device))
8391 return NULL;
8392 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008393}
8394
8395PyDoc_STRVAR(posix_minor__doc__,
8396"minor(device) -> minor number\n\
8397Extracts a device minor number from a raw device number.");
8398
8399static PyObject *
8400posix_minor(PyObject *self, PyObject *args)
8401{
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 int device;
8403 if (!PyArg_ParseTuple(args, "i:minor", &device))
8404 return NULL;
8405 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008406}
8407
8408PyDoc_STRVAR(posix_makedev__doc__,
8409"makedev(major, minor) -> device number\n\
8410Composes a raw device number from the major and minor device numbers.");
8411
8412static PyObject *
8413posix_makedev(PyObject *self, PyObject *args)
8414{
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 int major, minor;
8416 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8417 return NULL;
8418 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008419}
8420#endif /* device macros */
8421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008422
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008423#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008424PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008425"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008426Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008427
Barry Warsaw53699e91996-12-10 23:23:01 +00008428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008429posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008430{
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 int fd;
8432 off_t length;
8433 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008434
Ross Lagerwall7807c352011-03-17 20:20:30 +02008435 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008437
Victor Stinner8c62be82010-05-06 00:08:46 +00008438 Py_BEGIN_ALLOW_THREADS
8439 res = ftruncate(fd, length);
8440 Py_END_ALLOW_THREADS
8441 if (res < 0)
8442 return posix_error();
8443 Py_INCREF(Py_None);
8444 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008445}
8446#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008447
Ross Lagerwall7807c352011-03-17 20:20:30 +02008448#ifdef HAVE_TRUNCATE
8449PyDoc_STRVAR(posix_truncate__doc__,
8450"truncate(path, length)\n\n\
8451Truncate the file given by path to length bytes.");
8452
8453static PyObject *
8454posix_truncate(PyObject *self, PyObject *args)
8455{
8456 PyObject *opath;
8457 const char *path;
8458 off_t length;
8459 int res;
8460
8461 if (!PyArg_ParseTuple(args, "O&O&:truncate",
8462 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
8463 return NULL;
8464 path = PyBytes_AsString(opath);
8465
8466 Py_BEGIN_ALLOW_THREADS
8467 res = truncate(path, length);
8468 Py_END_ALLOW_THREADS
8469 Py_DECREF(opath);
8470 if (res < 0)
8471 return posix_error();
8472 Py_RETURN_NONE;
8473}
8474#endif
8475
8476#ifdef HAVE_POSIX_FALLOCATE
8477PyDoc_STRVAR(posix_posix_fallocate__doc__,
8478"posix_fallocate(fd, offset, len)\n\n\
8479Ensures that enough disk space is allocated for the file specified by fd\n\
8480starting from offset and continuing for len bytes.");
8481
8482static PyObject *
8483posix_posix_fallocate(PyObject *self, PyObject *args)
8484{
8485 off_t len, offset;
8486 int res, fd;
8487
8488 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8489 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8490 return NULL;
8491
8492 Py_BEGIN_ALLOW_THREADS
8493 res = posix_fallocate(fd, offset, len);
8494 Py_END_ALLOW_THREADS
8495 if (res != 0) {
8496 errno = res;
8497 return posix_error();
8498 }
8499 Py_RETURN_NONE;
8500}
8501#endif
8502
8503#ifdef HAVE_POSIX_FADVISE
8504PyDoc_STRVAR(posix_posix_fadvise__doc__,
8505"posix_fadvise(fd, offset, len, advice)\n\n\
8506Announces an intention to access data in a specific pattern thus allowing\n\
8507the kernel to make optimizations.\n\
8508The advice applies to the region of the file specified by fd starting at\n\
8509offset and continuing for len bytes.\n\
8510advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8511POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8512POSIX_FADV_DONTNEED.");
8513
8514static PyObject *
8515posix_posix_fadvise(PyObject *self, PyObject *args)
8516{
8517 off_t len, offset;
8518 int res, fd, advice;
8519
8520 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8521 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8522 return NULL;
8523
8524 Py_BEGIN_ALLOW_THREADS
8525 res = posix_fadvise(fd, offset, len, advice);
8526 Py_END_ALLOW_THREADS
8527 if (res != 0) {
8528 errno = res;
8529 return posix_error();
8530 }
8531 Py_RETURN_NONE;
8532}
8533#endif
8534
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008535#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008536PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008537"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008538Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008539
Fred Drake762e2061999-08-26 17:23:54 +00008540/* Save putenv() parameters as values here, so we can collect them when they
8541 * get re-set with another call for the same key. */
8542static PyObject *posix_putenv_garbage;
8543
Tim Peters5aa91602002-01-30 05:46:57 +00008544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008545posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008546{
Victor Stinner84ae1182010-05-06 22:05:07 +00008547 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008548#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008549 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008550 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008551
Victor Stinner8c62be82010-05-06 00:08:46 +00008552 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008553 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008554 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008556
Victor Stinner65170952011-11-22 22:16:17 +01008557 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008558 if (newstr == NULL) {
8559 PyErr_NoMemory();
8560 goto error;
8561 }
Victor Stinner65170952011-11-22 22:16:17 +01008562 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8563 PyErr_Format(PyExc_ValueError,
8564 "the environment variable is longer than %u characters",
8565 _MAX_ENV);
8566 goto error;
8567 }
8568
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008570 if (newenv == NULL)
8571 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008574 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008576#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008577 PyObject *os1, *os2;
8578 char *s1, *s2;
8579 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008580
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008581 if (!PyArg_ParseTuple(args,
8582 "O&O&:putenv",
8583 PyUnicode_FSConverter, &os1,
8584 PyUnicode_FSConverter, &os2))
8585 return NULL;
8586 s1 = PyBytes_AsString(os1);
8587 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008588
Victor Stinner65170952011-11-22 22:16:17 +01008589 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008590 if (newstr == NULL) {
8591 PyErr_NoMemory();
8592 goto error;
8593 }
8594
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008598 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008600#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008601
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 /* Install the first arg and newstr in posix_putenv_garbage;
8603 * this will cause previous value to be collected. This has to
8604 * happen after the real putenv() call because the old value
8605 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008606 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 /* really not much we can do; just leak */
8608 PyErr_Clear();
8609 }
8610 else {
8611 Py_DECREF(newstr);
8612 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008613
Martin v. Löwis011e8422009-05-05 04:43:17 +00008614#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 Py_DECREF(os1);
8616 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008617#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008618 Py_RETURN_NONE;
8619
8620error:
8621#ifndef MS_WINDOWS
8622 Py_DECREF(os1);
8623 Py_DECREF(os2);
8624#endif
8625 Py_XDECREF(newstr);
8626 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008627}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008628#endif /* putenv */
8629
Guido van Rossumc524d952001-10-19 01:31:59 +00008630#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008631PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008632"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008633Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008634
8635static PyObject *
8636posix_unsetenv(PyObject *self, PyObject *args)
8637{
Victor Stinner65170952011-11-22 22:16:17 +01008638 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008639#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008640 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008641#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008642
8643 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008644
Victor Stinner65170952011-11-22 22:16:17 +01008645 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008646 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008647
Victor Stinner984890f2011-11-24 13:53:38 +01008648#ifdef HAVE_BROKEN_UNSETENV
8649 unsetenv(PyBytes_AS_STRING(name));
8650#else
Victor Stinner65170952011-11-22 22:16:17 +01008651 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008652 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008653 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008654 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008655 }
Victor Stinner984890f2011-11-24 13:53:38 +01008656#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008657
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 /* Remove the key from posix_putenv_garbage;
8659 * this will cause it to be collected. This has to
8660 * happen after the real unsetenv() call because the
8661 * old value was still accessible until then.
8662 */
Victor Stinner65170952011-11-22 22:16:17 +01008663 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 /* really not much we can do; just leak */
8665 PyErr_Clear();
8666 }
Victor Stinner65170952011-11-22 22:16:17 +01008667 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008668 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008669}
8670#endif /* unsetenv */
8671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008672PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008673"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008674Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008675
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008677posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008678{
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 int code;
8680 char *message;
8681 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8682 return NULL;
8683 message = strerror(code);
8684 if (message == NULL) {
8685 PyErr_SetString(PyExc_ValueError,
8686 "strerror() argument out of range");
8687 return NULL;
8688 }
Victor Stinner1b579672011-12-17 05:47:23 +01008689 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008690}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008691
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008692
Guido van Rossumc9641791998-08-04 15:26:23 +00008693#ifdef HAVE_SYS_WAIT_H
8694
Fred Drake106c1a02002-04-23 15:58:02 +00008695#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008696PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008697"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008698Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008699
8700static PyObject *
8701posix_WCOREDUMP(PyObject *self, PyObject *args)
8702{
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 WAIT_TYPE status;
8704 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008705
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8707 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008708
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008710}
8711#endif /* WCOREDUMP */
8712
8713#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008714PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008715"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008716Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008717job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008718
8719static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008720posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008721{
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 WAIT_TYPE status;
8723 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008724
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8726 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008727
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008729}
8730#endif /* WIFCONTINUED */
8731
Guido van Rossumc9641791998-08-04 15:26:23 +00008732#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008733PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008734"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008735Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008736
8737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008738posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008739{
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 WAIT_TYPE status;
8741 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008742
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8744 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008745
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008747}
8748#endif /* WIFSTOPPED */
8749
8750#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008751PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008752"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008753Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008754
8755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008756posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008757{
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 WAIT_TYPE status;
8759 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008760
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8762 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008763
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008765}
8766#endif /* WIFSIGNALED */
8767
8768#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008769PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008770"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008771Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008772system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008773
8774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008775posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008776{
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 WAIT_TYPE status;
8778 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008779
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8781 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008782
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008784}
8785#endif /* WIFEXITED */
8786
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008787#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008788PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008789"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008790Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008791
8792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008793posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008794{
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 WAIT_TYPE status;
8796 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008797
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8799 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008800
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008802}
8803#endif /* WEXITSTATUS */
8804
8805#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008806PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008807"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008808Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008809value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008810
8811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008812posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008813{
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 WAIT_TYPE status;
8815 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008816
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8818 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008819
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008821}
8822#endif /* WTERMSIG */
8823
8824#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008825PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008826"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008827Return the signal that stopped the process that provided\n\
8828the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008829
8830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008831posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008832{
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 WAIT_TYPE status;
8834 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008835
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8837 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008838
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008840}
8841#endif /* WSTOPSIG */
8842
8843#endif /* HAVE_SYS_WAIT_H */
8844
8845
Thomas Wouters477c8d52006-05-27 19:21:47 +00008846#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008847#ifdef _SCO_DS
8848/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8849 needed definitions in sys/statvfs.h */
8850#define _SVID3
8851#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008852#include <sys/statvfs.h>
8853
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008854static PyObject*
8855_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8857 if (v == NULL)
8858 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008859
8860#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8862 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8863 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8864 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8865 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8866 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8867 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8868 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8869 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8870 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008871#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8873 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8874 PyStructSequence_SET_ITEM(v, 2,
8875 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8876 PyStructSequence_SET_ITEM(v, 3,
8877 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8878 PyStructSequence_SET_ITEM(v, 4,
8879 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8880 PyStructSequence_SET_ITEM(v, 5,
8881 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8882 PyStructSequence_SET_ITEM(v, 6,
8883 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8884 PyStructSequence_SET_ITEM(v, 7,
8885 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8886 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8887 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008888#endif
8889
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008891}
8892
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008893PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008894"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008895Perform an fstatvfs system call on the given fd.\n\
8896Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008897
8898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008899posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008900{
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 int fd, res;
8902 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008903
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8905 return NULL;
8906 Py_BEGIN_ALLOW_THREADS
8907 res = fstatvfs(fd, &st);
8908 Py_END_ALLOW_THREADS
8909 if (res != 0)
8910 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008911
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008913}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008914#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008915
8916
Thomas Wouters477c8d52006-05-27 19:21:47 +00008917#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008918#include <sys/statvfs.h>
8919
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008920PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008921"statvfs(path)\n\n\
8922Perform a statvfs system call on the given path.\n\
8923\n\
8924path may always be specified as a string.\n\
8925On some platforms, path may also be specified as an open file descriptor.\n\
8926 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008927
8928static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008929posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008930{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008931 static char *keywords[] = {"path", NULL};
8932 path_t path;
8933 int result;
8934 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008936
Larry Hastings9cf065c2012-06-22 16:30:09 -07008937 memset(&path, 0, sizeof(path));
8938#ifdef HAVE_FSTATVFS
8939 path.allow_fd = 1;
8940#endif
8941 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8942 path_converter, &path
8943 ))
8944 return NULL;
8945
8946 Py_BEGIN_ALLOW_THREADS
8947#ifdef HAVE_FSTATVFS
8948 if (path.fd != -1) {
8949#ifdef __APPLE__
8950 /* handle weak-linking on Mac OS X 10.3 */
8951 if (fstatvfs == NULL) {
8952 fd_specified("statvfs", path.fd);
8953 goto exit;
8954 }
8955#endif
8956 result = fstatvfs(path.fd, &st);
8957 }
8958 else
8959#endif
8960 result = statvfs(path.narrow, &st);
8961 Py_END_ALLOW_THREADS
8962
8963 if (result) {
8964 return_value = path_posix_error("statvfs", &path);
8965 goto exit;
8966 }
8967
8968 return_value = _pystatvfs_fromstructstatvfs(st);
8969
8970exit:
8971 path_cleanup(&path);
8972 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008973}
8974#endif /* HAVE_STATVFS */
8975
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008976#ifdef MS_WINDOWS
8977PyDoc_STRVAR(win32__getdiskusage__doc__,
8978"_getdiskusage(path) -> (total, free)\n\n\
8979Return disk usage statistics about the given path as (total, free) tuple.");
8980
8981static PyObject *
8982win32__getdiskusage(PyObject *self, PyObject *args)
8983{
8984 BOOL retval;
8985 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008986 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008987
Victor Stinner6139c1b2011-11-09 22:14:14 +01008988 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008989 return NULL;
8990
8991 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008992 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008993 Py_END_ALLOW_THREADS
8994 if (retval == 0)
8995 return PyErr_SetFromWindowsErr(0);
8996
8997 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8998}
8999#endif
9000
9001
Fred Drakec9680921999-12-13 16:37:25 +00009002/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9003 * It maps strings representing configuration variable names to
9004 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009005 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009006 * rarely-used constants. There are three separate tables that use
9007 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009008 *
9009 * This code is always included, even if none of the interfaces that
9010 * need it are included. The #if hackery needed to avoid it would be
9011 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009012 */
9013struct constdef {
9014 char *name;
9015 long value;
9016};
9017
Fred Drake12c6e2d1999-12-14 21:25:03 +00009018static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009019conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009020 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009021{
Christian Heimes217cfd12007-12-02 14:31:20 +00009022 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009023 *valuep = PyLong_AS_LONG(arg);
9024 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009025 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009026 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009027 /* look up the value in the table using a binary search */
9028 size_t lo = 0;
9029 size_t mid;
9030 size_t hi = tablesize;
9031 int cmp;
9032 const char *confname;
9033 if (!PyUnicode_Check(arg)) {
9034 PyErr_SetString(PyExc_TypeError,
9035 "configuration names must be strings or integers");
9036 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009038 confname = _PyUnicode_AsString(arg);
9039 if (confname == NULL)
9040 return 0;
9041 while (lo < hi) {
9042 mid = (lo + hi) / 2;
9043 cmp = strcmp(confname, table[mid].name);
9044 if (cmp < 0)
9045 hi = mid;
9046 else if (cmp > 0)
9047 lo = mid + 1;
9048 else {
9049 *valuep = table[mid].value;
9050 return 1;
9051 }
9052 }
9053 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9054 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009056}
9057
9058
9059#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9060static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009061#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009063#endif
9064#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009066#endif
Fred Drakec9680921999-12-13 16:37:25 +00009067#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009069#endif
9070#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
9073#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
9076#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
9094#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009096#endif
9097#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009112#ifdef _PC_ACL_ENABLED
9113 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9114#endif
9115#ifdef _PC_MIN_HOLE_SIZE
9116 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9117#endif
9118#ifdef _PC_ALLOC_SIZE_MIN
9119 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9120#endif
9121#ifdef _PC_REC_INCR_XFER_SIZE
9122 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9123#endif
9124#ifdef _PC_REC_MAX_XFER_SIZE
9125 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9126#endif
9127#ifdef _PC_REC_MIN_XFER_SIZE
9128 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9129#endif
9130#ifdef _PC_REC_XFER_ALIGN
9131 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9132#endif
9133#ifdef _PC_SYMLINK_MAX
9134 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9135#endif
9136#ifdef _PC_XATTR_ENABLED
9137 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9138#endif
9139#ifdef _PC_XATTR_EXISTS
9140 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9141#endif
9142#ifdef _PC_TIMESTAMP_RESOLUTION
9143 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9144#endif
Fred Drakec9680921999-12-13 16:37:25 +00009145};
9146
Fred Drakec9680921999-12-13 16:37:25 +00009147static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009148conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009149{
9150 return conv_confname(arg, valuep, posix_constants_pathconf,
9151 sizeof(posix_constants_pathconf)
9152 / sizeof(struct constdef));
9153}
9154#endif
9155
9156#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009157PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009158"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009159Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009160If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009161
9162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009163posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009164{
9165 PyObject *result = NULL;
9166 int name, fd;
9167
Fred Drake12c6e2d1999-12-14 21:25:03 +00009168 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9169 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009170 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009171
Stefan Krah0e803b32010-11-26 16:16:47 +00009172 errno = 0;
9173 limit = fpathconf(fd, name);
9174 if (limit == -1 && errno != 0)
9175 posix_error();
9176 else
9177 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009178 }
9179 return result;
9180}
9181#endif
9182
9183
9184#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009185PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009186"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009187Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009188If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009189
9190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009191posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009192{
9193 PyObject *result = NULL;
9194 int name;
9195 char *path;
9196
9197 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
9198 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009200
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 errno = 0;
9202 limit = pathconf(path, name);
9203 if (limit == -1 && errno != 0) {
9204 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009205 /* could be a path or name problem */
9206 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009207 else
Stefan Krah99439262010-11-26 12:58:05 +00009208 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 }
9210 else
9211 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009212 }
9213 return result;
9214}
9215#endif
9216
9217#ifdef HAVE_CONFSTR
9218static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009219#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009221#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009222#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009224#endif
9225#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009227#endif
Fred Draked86ed291999-12-15 15:34:33 +00009228#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009230#endif
9231#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009232 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009233#endif
9234#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009236#endif
9237#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009238 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009239#endif
Fred Drakec9680921999-12-13 16:37:25 +00009240#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009242#endif
9243#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009244 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009245#endif
9246#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009248#endif
9249#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009250 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009251#endif
9252#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009253 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009254#endif
9255#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009257#endif
9258#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009260#endif
9261#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009262 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009263#endif
Fred Draked86ed291999-12-15 15:34:33 +00009264#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009265 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009266#endif
Fred Drakec9680921999-12-13 16:37:25 +00009267#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009269#endif
Fred Draked86ed291999-12-15 15:34:33 +00009270#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009272#endif
9273#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009275#endif
9276#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009278#endif
9279#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009281#endif
Fred Drakec9680921999-12-13 16:37:25 +00009282#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009283 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009284#endif
9285#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009287#endif
9288#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009290#endif
9291#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009293#endif
9294#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009296#endif
9297#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009299#endif
9300#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009302#endif
9303#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009305#endif
9306#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009308#endif
9309#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009311#endif
9312#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009314#endif
9315#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009317#endif
9318#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009320#endif
9321#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009323#endif
9324#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009326#endif
9327#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009329#endif
Fred Draked86ed291999-12-15 15:34:33 +00009330#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009332#endif
9333#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009335#endif
9336#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009338#endif
9339#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009341#endif
9342#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009344#endif
9345#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009347#endif
9348#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
9351#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
9357#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
9363#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009365#endif
9366#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009368#endif
Fred Drakec9680921999-12-13 16:37:25 +00009369};
9370
9371static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009372conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009373{
9374 return conv_confname(arg, valuep, posix_constants_confstr,
9375 sizeof(posix_constants_confstr)
9376 / sizeof(struct constdef));
9377}
9378
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009379PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009380"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009381Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009382
9383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009384posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009385{
9386 PyObject *result = NULL;
9387 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009388 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009389 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009390
Victor Stinnercb043522010-09-10 23:49:04 +00009391 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9392 return NULL;
9393
9394 errno = 0;
9395 len = confstr(name, buffer, sizeof(buffer));
9396 if (len == 0) {
9397 if (errno) {
9398 posix_error();
9399 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009400 }
9401 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009402 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009403 }
9404 }
Victor Stinnercb043522010-09-10 23:49:04 +00009405
9406 if ((unsigned int)len >= sizeof(buffer)) {
9407 char *buf = PyMem_Malloc(len);
9408 if (buf == NULL)
9409 return PyErr_NoMemory();
9410 confstr(name, buf, len);
9411 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9412 PyMem_Free(buf);
9413 }
9414 else
9415 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009416 return result;
9417}
9418#endif
9419
9420
9421#ifdef HAVE_SYSCONF
9422static struct constdef posix_constants_sysconf[] = {
9423#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
Fred Draked86ed291999-12-15 15:34:33 +00009453#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009455#endif
9456#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009458#endif
Fred Drakec9680921999-12-13 16:37:25 +00009459#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009461#endif
Fred Drakec9680921999-12-13 16:37:25 +00009462#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
9465#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
9471#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009473#endif
9474#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009476#endif
Fred Draked86ed291999-12-15 15:34:33 +00009477#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009479#endif
Fred Drakec9680921999-12-13 16:37:25 +00009480#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009482#endif
9483#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009485#endif
9486#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009488#endif
9489#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009491#endif
9492#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009494#endif
Fred Draked86ed291999-12-15 15:34:33 +00009495#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009497#endif
Fred Drakec9680921999-12-13 16:37:25 +00009498#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009500#endif
9501#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009503#endif
9504#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
9528#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009530#endif
9531#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
9534#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
Fred Draked86ed291999-12-15 15:34:33 +00009567#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
Fred Drakec9680921999-12-13 16:37:25 +00009570#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
Fred Draked86ed291999-12-15 15:34:33 +00009579#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
Fred Drakec9680921999-12-13 16:37:25 +00009582#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
Fred Draked86ed291999-12-15 15:34:33 +00009585#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
9588#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009590#endif
Fred Drakec9680921999-12-13 16:37:25 +00009591#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
Fred Draked86ed291999-12-15 15:34:33 +00009603#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009605#endif
Fred Drakec9680921999-12-13 16:37:25 +00009606#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
Fred Draked86ed291999-12-15 15:34:33 +00009627#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009629#endif
Fred Drakec9680921999-12-13 16:37:25 +00009630#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
Fred Draked86ed291999-12-15 15:34:33 +00009636#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
Fred Drakec9680921999-12-13 16:37:25 +00009639#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
Fred Draked86ed291999-12-15 15:34:33 +00009666#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
Fred Drakec9680921999-12-13 16:37:25 +00009672#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
9690#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
Fred Draked86ed291999-12-15 15:34:33 +00009777#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009779#endif
Fred Drakec9680921999-12-13 16:37:25 +00009780#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915};
9916
9917static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009918conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009919{
9920 return conv_confname(arg, valuep, posix_constants_sysconf,
9921 sizeof(posix_constants_sysconf)
9922 / sizeof(struct constdef));
9923}
9924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009925PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009926"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009927Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009928
9929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009930posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009931{
9932 PyObject *result = NULL;
9933 int name;
9934
9935 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9936 int value;
9937
9938 errno = 0;
9939 value = sysconf(name);
9940 if (value == -1 && errno != 0)
9941 posix_error();
9942 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009943 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009944 }
9945 return result;
9946}
9947#endif
9948
9949
Fred Drakebec628d1999-12-15 18:31:10 +00009950/* This code is used to ensure that the tables of configuration value names
9951 * are in sorted order as required by conv_confname(), and also to build the
9952 * the exported dictionaries that are used to publish information about the
9953 * names available on the host platform.
9954 *
9955 * Sorting the table at runtime ensures that the table is properly ordered
9956 * when used, even for platforms we're not able to test on. It also makes
9957 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009958 */
Fred Drakebec628d1999-12-15 18:31:10 +00009959
9960static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009961cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009962{
9963 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009965 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009967
9968 return strcmp(c1->name, c2->name);
9969}
9970
9971static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009972setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009974{
Fred Drakebec628d1999-12-15 18:31:10 +00009975 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009976 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009977
9978 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9979 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009980 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009982
Barry Warsaw3155db32000-04-13 15:20:40 +00009983 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 PyObject *o = PyLong_FromLong(table[i].value);
9985 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9986 Py_XDECREF(o);
9987 Py_DECREF(d);
9988 return -1;
9989 }
9990 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009991 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009992 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009993}
9994
Fred Drakebec628d1999-12-15 18:31:10 +00009995/* Return -1 on failure, 0 on success. */
9996static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009997setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009998{
9999#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010000 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010001 sizeof(posix_constants_pathconf)
10002 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010003 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010004 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010005#endif
10006#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010007 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010008 sizeof(posix_constants_confstr)
10009 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010010 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010011 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010012#endif
10013#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010014 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010015 sizeof(posix_constants_sysconf)
10016 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010017 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010018 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010019#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010020 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010021}
Fred Draked86ed291999-12-15 15:34:33 +000010022
10023
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010024PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010025"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010026Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010027in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010028
10029static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010030posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010031{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010032 abort();
10033 /*NOTREACHED*/
10034 Py_FatalError("abort() called from Python code didn't abort!");
10035 return NULL;
10036}
Fred Drakebec628d1999-12-15 18:31:10 +000010037
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010038#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010039PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010040"startfile(filepath [, operation]) - Start a file with its associated\n\
10041application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010042\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010043When \"operation\" is not specified or \"open\", this acts like\n\
10044double-clicking the file in Explorer, or giving the file name as an\n\
10045argument to the DOS \"start\" command: the file is opened with whatever\n\
10046application (if any) its extension is associated.\n\
10047When another \"operation\" is given, it specifies what should be done with\n\
10048the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010049\n\
10050startfile returns as soon as the associated application is launched.\n\
10051There is no option to wait for the application to close, and no way\n\
10052to retrieve the application's exit status.\n\
10053\n\
10054The filepath is relative to the current directory. If you want to use\n\
10055an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010056the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010057
10058static PyObject *
10059win32_startfile(PyObject *self, PyObject *args)
10060{
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 PyObject *ofilepath;
10062 char *filepath;
10063 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010064 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010066
Victor Stinnereb5657a2011-09-30 01:44:27 +020010067 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 if (!PyArg_ParseTuple(args, "U|s:startfile",
10069 &unipath, &operation)) {
10070 PyErr_Clear();
10071 goto normal;
10072 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010073
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010075 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010077 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 PyErr_Clear();
10079 operation = NULL;
10080 goto normal;
10081 }
10082 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010083
Victor Stinnereb5657a2011-09-30 01:44:27 +020010084 wpath = PyUnicode_AsUnicode(unipath);
10085 if (wpath == NULL)
10086 goto normal;
10087 if (uoperation) {
10088 woperation = PyUnicode_AsUnicode(uoperation);
10089 if (woperation == NULL)
10090 goto normal;
10091 }
10092 else
10093 woperation = NULL;
10094
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010096 rc = ShellExecuteW((HWND)0, woperation, wpath,
10097 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 Py_END_ALLOW_THREADS
10099
Victor Stinnereb5657a2011-09-30 01:44:27 +020010100 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010102 win32_error_object("startfile", unipath);
10103 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 }
10105 Py_INCREF(Py_None);
10106 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010107
10108normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10110 PyUnicode_FSConverter, &ofilepath,
10111 &operation))
10112 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010113 if (win32_warn_bytes_api()) {
10114 Py_DECREF(ofilepath);
10115 return NULL;
10116 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 filepath = PyBytes_AsString(ofilepath);
10118 Py_BEGIN_ALLOW_THREADS
10119 rc = ShellExecute((HWND)0, operation, filepath,
10120 NULL, NULL, SW_SHOWNORMAL);
10121 Py_END_ALLOW_THREADS
10122 if (rc <= (HINSTANCE)32) {
10123 PyObject *errval = win32_error("startfile", filepath);
10124 Py_DECREF(ofilepath);
10125 return errval;
10126 }
10127 Py_DECREF(ofilepath);
10128 Py_INCREF(Py_None);
10129 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010130}
10131#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010132
Martin v. Löwis438b5342002-12-27 10:16:42 +000010133#ifdef HAVE_GETLOADAVG
10134PyDoc_STRVAR(posix_getloadavg__doc__,
10135"getloadavg() -> (float, float, float)\n\n\
10136Return the number of processes in the system run queue averaged over\n\
10137the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10138was unobtainable");
10139
10140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010141posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010142{
10143 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010144 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010145 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10146 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010147 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010148 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010149}
10150#endif
10151
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010152PyDoc_STRVAR(device_encoding__doc__,
10153"device_encoding(fd) -> str\n\n\
10154Return a string describing the encoding of the device\n\
10155if the output is a terminal; else return None.");
10156
10157static PyObject *
10158device_encoding(PyObject *self, PyObject *args)
10159{
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010161
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10163 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010164
10165 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010166}
10167
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010168#ifdef __VMS
10169/* Use openssl random routine */
10170#include <openssl/rand.h>
10171PyDoc_STRVAR(vms_urandom__doc__,
10172"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +000010173Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010174
10175static PyObject*
10176vms_urandom(PyObject *self, PyObject *args)
10177{
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 int howMany;
10179 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010180
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 /* Read arguments */
10182 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10183 return NULL;
10184 if (howMany < 0)
10185 return PyErr_Format(PyExc_ValueError,
10186 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010187
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 /* Allocate bytes */
10189 result = PyBytes_FromStringAndSize(NULL, howMany);
10190 if (result != NULL) {
10191 /* Get random data */
10192 if (RAND_pseudo_bytes((unsigned char*)
10193 PyBytes_AS_STRING(result),
10194 howMany) < 0) {
10195 Py_DECREF(result);
10196 return PyErr_Format(PyExc_ValueError,
10197 "RAND_pseudo_bytes");
10198 }
10199 }
10200 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010201}
10202#endif
10203
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010204#ifdef HAVE_SETRESUID
10205PyDoc_STRVAR(posix_setresuid__doc__,
10206"setresuid(ruid, euid, suid)\n\n\
10207Set the current process's real, effective, and saved user ids.");
10208
10209static PyObject*
10210posix_setresuid (PyObject *self, PyObject *args)
10211{
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 /* We assume uid_t is no larger than a long. */
10213 long ruid, euid, suid;
10214 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10215 return NULL;
10216 if (setresuid(ruid, euid, suid) < 0)
10217 return posix_error();
10218 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010219}
10220#endif
10221
10222#ifdef HAVE_SETRESGID
10223PyDoc_STRVAR(posix_setresgid__doc__,
10224"setresgid(rgid, egid, sgid)\n\n\
10225Set the current process's real, effective, and saved group ids.");
10226
10227static PyObject*
10228posix_setresgid (PyObject *self, PyObject *args)
10229{
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 /* We assume uid_t is no larger than a long. */
10231 long rgid, egid, sgid;
10232 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10233 return NULL;
10234 if (setresgid(rgid, egid, sgid) < 0)
10235 return posix_error();
10236 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010237}
10238#endif
10239
10240#ifdef HAVE_GETRESUID
10241PyDoc_STRVAR(posix_getresuid__doc__,
10242"getresuid() -> (ruid, euid, suid)\n\n\
10243Get tuple of the current process's real, effective, and saved user ids.");
10244
10245static PyObject*
10246posix_getresuid (PyObject *self, PyObject *noargs)
10247{
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 uid_t ruid, euid, suid;
10249 long l_ruid, l_euid, l_suid;
10250 if (getresuid(&ruid, &euid, &suid) < 0)
10251 return posix_error();
10252 /* Force the values into long's as we don't know the size of uid_t. */
10253 l_ruid = ruid;
10254 l_euid = euid;
10255 l_suid = suid;
10256 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010257}
10258#endif
10259
10260#ifdef HAVE_GETRESGID
10261PyDoc_STRVAR(posix_getresgid__doc__,
10262"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010263Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010264
10265static PyObject*
10266posix_getresgid (PyObject *self, PyObject *noargs)
10267{
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 uid_t rgid, egid, sgid;
10269 long l_rgid, l_egid, l_sgid;
10270 if (getresgid(&rgid, &egid, &sgid) < 0)
10271 return posix_error();
10272 /* Force the values into long's as we don't know the size of uid_t. */
10273 l_rgid = rgid;
10274 l_egid = egid;
10275 l_sgid = sgid;
10276 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010277}
10278#endif
10279
Benjamin Peterson9428d532011-09-14 11:45:52 -040010280#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010281
Benjamin Peterson799bd802011-08-31 22:15:17 -040010282PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010283"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10284Return the value of extended attribute attribute on path.\n\
10285\n\
10286path may be either a string or an open file descriptor.\n\
10287If follow_symlinks is False, and the last element of the path is a symbolic\n\
10288 link, getxattr will examine the symbolic link itself instead of the file\n\
10289 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010290
10291static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010292posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010293{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010294 path_t path;
10295 path_t attribute;
10296 int follow_symlinks = 1;
10297 PyObject *buffer = NULL;
10298 int i;
10299 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010300
Larry Hastings9cf065c2012-06-22 16:30:09 -070010301 memset(&path, 0, sizeof(path));
10302 memset(&attribute, 0, sizeof(attribute));
10303 path.allow_fd = 1;
10304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10305 path_converter, &path,
10306 path_converter, &attribute,
10307 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010308 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010309
Larry Hastings9cf065c2012-06-22 16:30:09 -070010310 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10311 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010312
Larry Hastings9cf065c2012-06-22 16:30:09 -070010313 for (i = 0; ; i++) {
10314 void *ptr;
10315 ssize_t result;
10316 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10317 Py_ssize_t buffer_size = buffer_sizes[i];
10318 if (!buffer_size) {
10319 path_error("getxattr", &path);
10320 goto exit;
10321 }
10322 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10323 if (!buffer)
10324 goto exit;
10325 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010326
Larry Hastings9cf065c2012-06-22 16:30:09 -070010327 Py_BEGIN_ALLOW_THREADS;
10328 if (path.fd >= 0)
10329 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10330 else if (follow_symlinks)
10331 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10332 else
10333 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10334 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010335
Larry Hastings9cf065c2012-06-22 16:30:09 -070010336 if (result < 0) {
10337 Py_DECREF(buffer);
10338 buffer = NULL;
10339 if (errno == ERANGE)
10340 continue;
10341 path_error("getxattr", &path);
10342 goto exit;
10343 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010344
Larry Hastings9cf065c2012-06-22 16:30:09 -070010345 if (result != buffer_size) {
10346 /* Can only shrink. */
10347 _PyBytes_Resize(&buffer, result);
10348 }
10349 break;
10350 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010351
Larry Hastings9cf065c2012-06-22 16:30:09 -070010352exit:
10353 path_cleanup(&path);
10354 path_cleanup(&attribute);
10355 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010356}
10357
10358PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010359"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10360Set extended attribute attribute on path to value.\n\
10361path may be either a string or an open file descriptor.\n\
10362If follow_symlinks is False, and the last element of the path is a symbolic\n\
10363 link, setxattr will modify the symbolic link itself instead of the file\n\
10364 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010365
10366static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010367posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010368{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010369 path_t path;
10370 path_t attribute;
10371 Py_buffer value;
10372 int flags = 0;
10373 int follow_symlinks = 1;
10374 int result;
10375 PyObject *return_value = NULL;
10376 static char *keywords[] = {"path", "attribute", "value",
10377 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010378
Larry Hastings9cf065c2012-06-22 16:30:09 -070010379 memset(&path, 0, sizeof(path));
10380 path.allow_fd = 1;
10381 memset(&attribute, 0, sizeof(attribute));
10382 memset(&value, 0, sizeof(value));
10383 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10384 keywords,
10385 path_converter, &path,
10386 path_converter, &attribute,
10387 &value, &flags,
10388 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010389 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010390
10391 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10392 goto exit;
10393
Benjamin Peterson799bd802011-08-31 22:15:17 -040010394 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010395 if (path.fd > -1)
10396 result = fsetxattr(path.fd, attribute.narrow,
10397 value.buf, value.len, flags);
10398 else if (follow_symlinks)
10399 result = setxattr(path.narrow, attribute.narrow,
10400 value.buf, value.len, flags);
10401 else
10402 result = lsetxattr(path.narrow, attribute.narrow,
10403 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010404 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010405
Larry Hastings9cf065c2012-06-22 16:30:09 -070010406 if (result) {
10407 return_value = path_error("setxattr", &path);
10408 goto exit;
10409 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010410
Larry Hastings9cf065c2012-06-22 16:30:09 -070010411 return_value = Py_None;
10412 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010413
Larry Hastings9cf065c2012-06-22 16:30:09 -070010414exit:
10415 path_cleanup(&path);
10416 path_cleanup(&attribute);
10417 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010418
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010420}
10421
10422PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010423"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10424Remove extended attribute attribute on path.\n\
10425path may be either a string or an open file descriptor.\n\
10426If follow_symlinks is False, and the last element of the path is a symbolic\n\
10427 link, removexattr will modify the symbolic link itself instead of the file\n\
10428 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010429
10430static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010431posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010432{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010433 path_t path;
10434 path_t attribute;
10435 int follow_symlinks = 1;
10436 int result;
10437 PyObject *return_value = NULL;
10438 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010439
Larry Hastings9cf065c2012-06-22 16:30:09 -070010440 memset(&path, 0, sizeof(path));
10441 memset(&attribute, 0, sizeof(attribute));
10442 path.allow_fd = 1;
10443 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10444 keywords,
10445 path_converter, &path,
10446 path_converter, &attribute,
10447 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010448 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010449
10450 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10451 goto exit;
10452
Benjamin Peterson799bd802011-08-31 22:15:17 -040010453 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010454 if (path.fd > -1)
10455 result = fremovexattr(path.fd, attribute.narrow);
10456 else if (follow_symlinks)
10457 result = removexattr(path.narrow, attribute.narrow);
10458 else
10459 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010460 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010461
Larry Hastings9cf065c2012-06-22 16:30:09 -070010462 if (result) {
10463 return_value = path_error("removexattr", &path);
10464 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010465 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010466
Larry Hastings9cf065c2012-06-22 16:30:09 -070010467 return_value = Py_None;
10468 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010469
Larry Hastings9cf065c2012-06-22 16:30:09 -070010470exit:
10471 path_cleanup(&path);
10472 path_cleanup(&attribute);
10473
10474 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010475}
10476
10477PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010478"listxattr(path='.', *, follow_symlinks=True)\n\n\
10479Return a list of extended attributes on path.\n\
10480\n\
10481path may be either None, a string, or an open file descriptor.\n\
10482if path is None, listxattr will examine the current directory.\n\
10483If follow_symlinks is False, and the last element of the path is a symbolic\n\
10484 link, listxattr will examine the symbolic link itself instead of the file\n\
10485 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010486
10487static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010488posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010489{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010490 path_t path;
10491 int follow_symlinks = 1;
10492 Py_ssize_t i;
10493 PyObject *result = NULL;
10494 char *buffer = NULL;
10495 char *name;
10496 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010497
Larry Hastings9cf065c2012-06-22 16:30:09 -070010498 memset(&path, 0, sizeof(path));
10499 path.allow_fd = 1;
10500 path.fd = -1;
10501 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10502 path_converter, &path,
10503 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010504 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010505
Larry Hastings9cf065c2012-06-22 16:30:09 -070010506 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10507 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010508
Larry Hastings9cf065c2012-06-22 16:30:09 -070010509 name = path.narrow ? path.narrow : ".";
10510 for (i = 0; ; i++) {
10511 char *start, *trace, *end;
10512 ssize_t length;
10513 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10514 Py_ssize_t buffer_size = buffer_sizes[i];
10515 if (!buffer_size) {
10516 // ERANGE
10517 path_error("listxattr", &path);
10518 break;
10519 }
10520 buffer = PyMem_MALLOC(buffer_size);
10521 if (!buffer) {
10522 PyErr_NoMemory();
10523 break;
10524 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525
Larry Hastings9cf065c2012-06-22 16:30:09 -070010526 Py_BEGIN_ALLOW_THREADS;
10527 if (path.fd > -1)
10528 length = flistxattr(path.fd, buffer, buffer_size);
10529 else if (follow_symlinks)
10530 length = listxattr(name, buffer, buffer_size);
10531 else
10532 length = llistxattr(name, buffer, buffer_size);
10533 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010534
Larry Hastings9cf065c2012-06-22 16:30:09 -070010535 if (length < 0) {
10536 if (errno == ERANGE)
10537 continue;
10538 path_error("listxattr", &path);
10539 break;
10540 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010541
Larry Hastings9cf065c2012-06-22 16:30:09 -070010542 result = PyList_New(0);
10543 if (!result) {
10544 goto exit;
10545 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010546
Larry Hastings9cf065c2012-06-22 16:30:09 -070010547 end = buffer + length;
10548 for (trace = start = buffer; trace != end; trace++) {
10549 if (!*trace) {
10550 int error;
10551 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10552 trace - start);
10553 if (!attribute) {
10554 Py_DECREF(result);
10555 result = NULL;
10556 goto exit;
10557 }
10558 error = PyList_Append(result, attribute);
10559 Py_DECREF(attribute);
10560 if (error) {
10561 Py_DECREF(result);
10562 result = NULL;
10563 goto exit;
10564 }
10565 start = trace + 1;
10566 }
10567 }
10568 break;
10569 }
10570exit:
10571 path_cleanup(&path);
10572 if (buffer)
10573 PyMem_FREE(buffer);
10574 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010575}
10576
Benjamin Peterson9428d532011-09-14 11:45:52 -040010577#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010578
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010579
Georg Brandl2fb477c2012-02-21 00:33:36 +010010580PyDoc_STRVAR(posix_urandom__doc__,
10581"urandom(n) -> str\n\n\
10582Return n random bytes suitable for cryptographic use.");
10583
10584static PyObject *
10585posix_urandom(PyObject *self, PyObject *args)
10586{
10587 Py_ssize_t size;
10588 PyObject *result;
10589 int ret;
10590
10591 /* Read arguments */
10592 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10593 return NULL;
10594 if (size < 0)
10595 return PyErr_Format(PyExc_ValueError,
10596 "negative argument not allowed");
10597 result = PyBytes_FromStringAndSize(NULL, size);
10598 if (result == NULL)
10599 return NULL;
10600
10601 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10602 PyBytes_GET_SIZE(result));
10603 if (ret == -1) {
10604 Py_DECREF(result);
10605 return NULL;
10606 }
10607 return result;
10608}
10609
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010610/* Terminal size querying */
10611
10612static PyTypeObject TerminalSizeType;
10613
10614PyDoc_STRVAR(TerminalSize_docstring,
10615 "A tuple of (columns, lines) for holding terminal window size");
10616
10617static PyStructSequence_Field TerminalSize_fields[] = {
10618 {"columns", "width of the terminal window in characters"},
10619 {"lines", "height of the terminal window in characters"},
10620 {NULL, NULL}
10621};
10622
10623static PyStructSequence_Desc TerminalSize_desc = {
10624 "os.terminal_size",
10625 TerminalSize_docstring,
10626 TerminalSize_fields,
10627 2,
10628};
10629
10630#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10631PyDoc_STRVAR(termsize__doc__,
10632 "Return the size of the terminal window as (columns, lines).\n" \
10633 "\n" \
10634 "The optional argument fd (default standard output) specifies\n" \
10635 "which file descriptor should be queried.\n" \
10636 "\n" \
10637 "If the file descriptor is not connected to a terminal, an OSError\n" \
10638 "is thrown.\n" \
10639 "\n" \
10640 "This function will only be defined if an implementation is\n" \
10641 "available for this system.\n" \
10642 "\n" \
10643 "shutil.get_terminal_size is the high-level function which should \n" \
10644 "normally be used, os.get_terminal_size is the low-level implementation.");
10645
10646static PyObject*
10647get_terminal_size(PyObject *self, PyObject *args)
10648{
10649 int columns, lines;
10650 PyObject *termsize;
10651
10652 int fd = fileno(stdout);
10653 /* Under some conditions stdout may not be connected and
10654 * fileno(stdout) may point to an invalid file descriptor. For example
10655 * GUI apps don't have valid standard streams by default.
10656 *
10657 * If this happens, and the optional fd argument is not present,
10658 * the ioctl below will fail returning EBADF. This is what we want.
10659 */
10660
10661 if (!PyArg_ParseTuple(args, "|i", &fd))
10662 return NULL;
10663
10664#ifdef TERMSIZE_USE_IOCTL
10665 {
10666 struct winsize w;
10667 if (ioctl(fd, TIOCGWINSZ, &w))
10668 return PyErr_SetFromErrno(PyExc_OSError);
10669 columns = w.ws_col;
10670 lines = w.ws_row;
10671 }
10672#endif /* TERMSIZE_USE_IOCTL */
10673
10674#ifdef TERMSIZE_USE_CONIO
10675 {
10676 DWORD nhandle;
10677 HANDLE handle;
10678 CONSOLE_SCREEN_BUFFER_INFO csbi;
10679 switch (fd) {
10680 case 0: nhandle = STD_INPUT_HANDLE;
10681 break;
10682 case 1: nhandle = STD_OUTPUT_HANDLE;
10683 break;
10684 case 2: nhandle = STD_ERROR_HANDLE;
10685 break;
10686 default:
10687 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10688 }
10689 handle = GetStdHandle(nhandle);
10690 if (handle == NULL)
10691 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10692 if (handle == INVALID_HANDLE_VALUE)
10693 return PyErr_SetFromWindowsErr(0);
10694
10695 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10696 return PyErr_SetFromWindowsErr(0);
10697
10698 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10699 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10700 }
10701#endif /* TERMSIZE_USE_CONIO */
10702
10703 termsize = PyStructSequence_New(&TerminalSizeType);
10704 if (termsize == NULL)
10705 return NULL;
10706 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10707 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10708 if (PyErr_Occurred()) {
10709 Py_DECREF(termsize);
10710 return NULL;
10711 }
10712 return termsize;
10713}
10714#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10715
10716
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010717static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718 {"access", (PyCFunction)posix_access,
10719 METH_VARARGS | METH_KEYWORDS,
10720 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010721#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010723#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010724 {"chdir", (PyCFunction)posix_chdir,
10725 METH_VARARGS | METH_KEYWORDS,
10726 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010727#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 {"chflags", (PyCFunction)posix_chflags,
10729 METH_VARARGS | METH_KEYWORDS,
10730 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010731#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 {"chmod", (PyCFunction)posix_chmod,
10733 METH_VARARGS | METH_KEYWORDS,
10734 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010735#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010737#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010738#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 {"chown", (PyCFunction)posix_chown,
10740 METH_VARARGS | METH_KEYWORDS,
10741 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010742#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010743#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010745#endif /* HAVE_LCHMOD */
10746#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010748#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010749#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010751#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010752#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010754#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010755#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010757#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010758#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010760#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010761#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10763 METH_NOARGS, posix_getcwd__doc__},
10764 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10765 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010766#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10768 {"link", (PyCFunction)posix_link,
10769 METH_VARARGS | METH_KEYWORDS,
10770 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010771#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 {"listdir", (PyCFunction)posix_listdir,
10773 METH_VARARGS | METH_KEYWORDS,
10774 posix_listdir__doc__},
10775 {"lstat", (PyCFunction)posix_lstat,
10776 METH_VARARGS | METH_KEYWORDS,
10777 posix_lstat__doc__},
10778 {"mkdir", (PyCFunction)posix_mkdir,
10779 METH_VARARGS | METH_KEYWORDS,
10780 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010781#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010783#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010784#ifdef HAVE_GETPRIORITY
10785 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10786#endif /* HAVE_GETPRIORITY */
10787#ifdef HAVE_SETPRIORITY
10788 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10789#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010790#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 {"readlink", (PyCFunction)posix_readlink,
10792 METH_VARARGS | METH_KEYWORDS,
10793 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010794#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010795#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 {"readlink", (PyCFunction)win_readlink,
10797 METH_VARARGS | METH_KEYWORDS,
10798 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010799#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 {"rename", (PyCFunction)posix_rename,
10801 METH_VARARGS | METH_KEYWORDS,
10802 posix_rename__doc__},
10803 {"replace", (PyCFunction)posix_replace,
10804 METH_VARARGS | METH_KEYWORDS,
10805 posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010806 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 {"stat", (PyCFunction)posix_stat,
10808 METH_VARARGS | METH_KEYWORDS,
10809 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811#if defined(HAVE_SYMLINK)
10812 {"symlink", (PyCFunction)posix_symlink,
10813 METH_VARARGS | METH_KEYWORDS,
10814 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010815#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010816#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010818#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010820#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010822#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010823 {"unlink", (PyCFunction)posix_unlink,
10824 METH_VARARGS | METH_KEYWORDS,
10825 posix_unlink__doc__},
10826 {"remove", (PyCFunction)posix_unlink,
10827 METH_VARARGS | METH_KEYWORDS,
10828 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010829 {"utime", (PyCFunction)posix_utime,
10830 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010831#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010833#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010835#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010837 {"execve", (PyCFunction)posix_execve,
10838 METH_VARARGS | METH_KEYWORDS,
10839 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010840#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010841#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10843 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010844#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10846 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010847#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010848#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010849#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010851#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010852#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010854#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010855#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010856#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010857 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10858 {"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 +020010859#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010860#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010861 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010862#endif
10863#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010864 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010865#endif
10866#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010867 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010868#endif
10869#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010870 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010871#endif
10872#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010873 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010874#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010875 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010876#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010877 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10878 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10879#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010880#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010881#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010883#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010884#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010886#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010887#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010889#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010890#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010892#endif /* HAVE_GETEUID */
10893#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010895#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010896#ifdef HAVE_GETGROUPLIST
10897 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10898#endif
Fred Drakec9680921999-12-13 16:37:25 +000010899#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010903#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010905#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010906#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010908#endif /* HAVE_GETPPID */
10909#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010911#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010912#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010914#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010915#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010917#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010918#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010920#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010921#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010923#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010924#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10926 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010927#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010928#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010930#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010931#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010933#endif /* HAVE_SETEUID */
10934#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010936#endif /* HAVE_SETEGID */
10937#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010939#endif /* HAVE_SETREUID */
10940#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010942#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010943#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010945#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010946#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010948#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010949#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010951#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010952#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010954#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010955#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010957#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010958#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010960#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010961#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010962 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010963#endif /* HAVE_WAIT3 */
10964#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010965 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010966#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010967#if defined(HAVE_WAITID) && !defined(__APPLE__)
10968 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10969#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010970#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010972#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010973#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010975#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010976#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010978#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010979#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010981#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010982#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010984#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010985#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010987#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010988 {"open", (PyCFunction)posix_open,\
10989 METH_VARARGS | METH_KEYWORDS,
10990 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10992 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10993 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10994 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10995 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010996#ifdef HAVE_LOCKF
10997 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10998#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11000 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011001#ifdef HAVE_READV
11002 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11003#endif
11004#ifdef HAVE_PREAD
11005 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11006#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011008#ifdef HAVE_WRITEV
11009 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11010#endif
11011#ifdef HAVE_PWRITE
11012 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11013#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011014#ifdef HAVE_SENDFILE
11015 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11016 posix_sendfile__doc__},
11017#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011018 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011020#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011022#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011023#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011024 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011025#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011026#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011027 {"mkfifo", (PyCFunction)posix_mkfifo,
11028 METH_VARARGS | METH_KEYWORDS,
11029 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011030#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011031#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011032 {"mknod", (PyCFunction)posix_mknod,
11033 METH_VARARGS | METH_KEYWORDS,
11034 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011035#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011036#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11038 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11039 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011040#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011041#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011042 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011043#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011044#ifdef HAVE_TRUNCATE
11045 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
11046#endif
11047#ifdef HAVE_POSIX_FALLOCATE
11048 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11049#endif
11050#ifdef HAVE_POSIX_FADVISE
11051 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11052#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011053#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011055#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011056#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011058#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011060#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011062#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011063#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011065#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011066#ifdef HAVE_SYNC
11067 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11068#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011069#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011071#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011072#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011073#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011075#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011076#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011078#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011079#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011081#endif /* WIFSTOPPED */
11082#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011084#endif /* WIFSIGNALED */
11085#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011087#endif /* WIFEXITED */
11088#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011090#endif /* WEXITSTATUS */
11091#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011093#endif /* WTERMSIG */
11094#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011096#endif /* WSTOPSIG */
11097#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011098#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011100#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011101#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011102 {"statvfs", (PyCFunction)posix_statvfs,
11103 METH_VARARGS | METH_KEYWORDS,
11104 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011105#endif
Fred Drakec9680921999-12-13 16:37:25 +000011106#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011119#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011121 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011122 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011123 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011124 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011125#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011126#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011128#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011129 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011130#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011132#endif
11133#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011135#endif
11136#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011138#endif
11139#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011141#endif
11142
Benjamin Peterson9428d532011-09-14 11:45:52 -040011143#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 {"setxattr", (PyCFunction)posix_setxattr,
11145 METH_VARARGS | METH_KEYWORDS,
11146 posix_setxattr__doc__},
11147 {"getxattr", (PyCFunction)posix_getxattr,
11148 METH_VARARGS | METH_KEYWORDS,
11149 posix_getxattr__doc__},
11150 {"removexattr", (PyCFunction)posix_removexattr,
11151 METH_VARARGS | METH_KEYWORDS,
11152 posix_removexattr__doc__},
11153 {"listxattr", (PyCFunction)posix_listxattr,
11154 METH_VARARGS | METH_KEYWORDS,
11155 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011156#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011157#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11158 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11159#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011161};
11162
11163
Barry Warsaw4a342091996-12-19 23:50:02 +000011164static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011165ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011166{
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011168}
11169
Guido van Rossumd48f2521997-12-05 22:19:34 +000011170#if defined(PYOS_OS2)
11171/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011172static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011173{
11174 APIRET rc;
11175 ULONG values[QSV_MAX+1];
11176 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011177 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011178
11179 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011180 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011181 Py_END_ALLOW_THREADS
11182
11183 if (rc != NO_ERROR) {
11184 os2_error(rc);
11185 return -1;
11186 }
11187
Fred Drake4d1e64b2002-04-15 19:40:07 +000011188 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11189 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11190 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11191 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11192 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11193 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11194 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011195
11196 switch (values[QSV_VERSION_MINOR]) {
11197 case 0: ver = "2.00"; break;
11198 case 10: ver = "2.10"; break;
11199 case 11: ver = "2.11"; break;
11200 case 30: ver = "3.00"; break;
11201 case 40: ver = "4.00"; break;
11202 case 50: ver = "5.00"; break;
11203 default:
Tim Peters885d4572001-11-28 20:27:42 +000011204 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011206 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011207 ver = &tmp[0];
11208 }
11209
11210 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011211 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011212 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011213
11214 /* Add Indicator of Which Drive was Used to Boot the System */
11215 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11216 tmp[1] = ':';
11217 tmp[2] = '\0';
11218
Fred Drake4d1e64b2002-04-15 19:40:07 +000011219 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011220}
11221#endif
11222
Brian Curtin52173d42010-12-02 18:29:18 +000011223#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011224static int
Brian Curtin52173d42010-12-02 18:29:18 +000011225enable_symlink()
11226{
11227 HANDLE tok;
11228 TOKEN_PRIVILEGES tok_priv;
11229 LUID luid;
11230 int meth_idx = 0;
11231
11232 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011233 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011234
11235 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011236 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011237
11238 tok_priv.PrivilegeCount = 1;
11239 tok_priv.Privileges[0].Luid = luid;
11240 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11241
11242 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11243 sizeof(TOKEN_PRIVILEGES),
11244 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011245 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011246
Brian Curtin3b4499c2010-12-28 14:31:47 +000011247 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11248 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011249}
11250#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11251
Barry Warsaw4a342091996-12-19 23:50:02 +000011252static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011253all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011254{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011255#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011257#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011258#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011260#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011261#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011263#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011264#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011266#endif
Fred Drakec9680921999-12-13 16:37:25 +000011267#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011269#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011270#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011272#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011273#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011275#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011276#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011278#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011279#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011281#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011282#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011284#endif
11285#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011287#endif
11288#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011290#endif
11291#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011293#endif
11294#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011296#endif
11297#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011299#endif
11300#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011302#endif
11303#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011305#endif
11306#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011308#endif
11309#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011311#endif
11312#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011314#endif
11315#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011317#endif
11318#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011320#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011321#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011323#endif
11324#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011326#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011327#ifdef O_XATTR
11328 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11329#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011330#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011332#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011333#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011335#endif
11336#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011338#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011339#ifdef O_EXEC
11340 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11341#endif
11342#ifdef O_SEARCH
11343 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11344#endif
11345#ifdef O_TTY_INIT
11346 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11347#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011348#ifdef PRIO_PROCESS
11349 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11350#endif
11351#ifdef PRIO_PGRP
11352 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11353#endif
11354#ifdef PRIO_USER
11355 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11356#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011357#ifdef O_CLOEXEC
11358 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11359#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011360#ifdef O_ACCMODE
11361 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11362#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011363
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011364
Jesus Cea94363612012-06-22 18:32:07 +020011365#ifdef SEEK_HOLE
11366 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11367#endif
11368#ifdef SEEK_DATA
11369 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11370#endif
11371
Tim Peters5aa91602002-01-30 05:46:57 +000011372/* MS Windows */
11373#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 /* Don't inherit in child processes. */
11375 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011376#endif
11377#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 /* Optimize for short life (keep in memory). */
11379 /* MS forgot to define this one with a non-underscore form too. */
11380 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011381#endif
11382#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 /* Automatically delete when last handle is closed. */
11384 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011385#endif
11386#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 /* Optimize for random access. */
11388 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011389#endif
11390#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 /* Optimize for sequential access. */
11392 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011393#endif
11394
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011395/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011396#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 /* Send a SIGIO signal whenever input or output
11398 becomes available on file descriptor */
11399 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011400#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011401#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 /* Direct disk access. */
11403 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011404#endif
11405#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 /* Must be a directory. */
11407 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011408#endif
11409#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 /* Do not follow links. */
11411 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011412#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011413#ifdef O_NOLINKS
11414 /* Fails if link count of the named file is greater than 1 */
11415 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11416#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011417#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 /* Do not update the access time. */
11419 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011420#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011421
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011423#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011425#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011426#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011428#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011429#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011431#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011432#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011434#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011435#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011437#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011438#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011440#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011441#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011443#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011444#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011446#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011447#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011449#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011450#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011452#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011453#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011455#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011456#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011458#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011459#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011461#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011462#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011464#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011465#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011467#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011468#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011470#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011471#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011473#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011474
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011475 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011476#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011477 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011478#endif /* ST_RDONLY */
11479#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011480 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011481#endif /* ST_NOSUID */
11482
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011483 /* FreeBSD sendfile() constants */
11484#ifdef SF_NODISKIO
11485 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11486#endif
11487#ifdef SF_MNOWAIT
11488 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11489#endif
11490#ifdef SF_SYNC
11491 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11492#endif
11493
Ross Lagerwall7807c352011-03-17 20:20:30 +020011494 /* constants for posix_fadvise */
11495#ifdef POSIX_FADV_NORMAL
11496 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11497#endif
11498#ifdef POSIX_FADV_SEQUENTIAL
11499 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11500#endif
11501#ifdef POSIX_FADV_RANDOM
11502 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11503#endif
11504#ifdef POSIX_FADV_NOREUSE
11505 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11506#endif
11507#ifdef POSIX_FADV_WILLNEED
11508 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11509#endif
11510#ifdef POSIX_FADV_DONTNEED
11511 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11512#endif
11513
11514 /* constants for waitid */
11515#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11516 if (ins(d, "P_PID", (long)P_PID)) return -1;
11517 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11518 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11519#endif
11520#ifdef WEXITED
11521 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11522#endif
11523#ifdef WNOWAIT
11524 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11525#endif
11526#ifdef WSTOPPED
11527 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11528#endif
11529#ifdef CLD_EXITED
11530 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11531#endif
11532#ifdef CLD_DUMPED
11533 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11534#endif
11535#ifdef CLD_TRAPPED
11536 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11537#endif
11538#ifdef CLD_CONTINUED
11539 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11540#endif
11541
11542 /* constants for lockf */
11543#ifdef F_LOCK
11544 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11545#endif
11546#ifdef F_TLOCK
11547 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11548#endif
11549#ifdef F_ULOCK
11550 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11551#endif
11552#ifdef F_TEST
11553 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11554#endif
11555
Guido van Rossum246bc171999-02-01 23:54:31 +000011556#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011557#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11559 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11560 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11561 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11562 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11563 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11564 if (ins(d, "P_PM", (long)P_PM)) return -1;
11565 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11566 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11567 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11568 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11569 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11570 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11571 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11572 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11573 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11574 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11575 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11576 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11577 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011578#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11580 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11581 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11582 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11583 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011584#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011585#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011586
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011587#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011588 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011589 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11590 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11591#ifdef SCHED_SPORADIC
11592 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11593#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011594#ifdef SCHED_BATCH
11595 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11596#endif
11597#ifdef SCHED_IDLE
11598 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11599#endif
11600#ifdef SCHED_RESET_ON_FORK
11601 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11602#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011603#ifdef SCHED_SYS
11604 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11605#endif
11606#ifdef SCHED_IA
11607 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11608#endif
11609#ifdef SCHED_FSS
11610 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11611#endif
11612#ifdef SCHED_FX
11613 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11614#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011615#endif
11616
Benjamin Peterson9428d532011-09-14 11:45:52 -040011617#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011618 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11619 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11620 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11621#endif
11622
Victor Stinner8b905bd2011-10-25 13:34:04 +020011623#ifdef RTLD_LAZY
11624 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11625#endif
11626#ifdef RTLD_NOW
11627 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11628#endif
11629#ifdef RTLD_GLOBAL
11630 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11631#endif
11632#ifdef RTLD_LOCAL
11633 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11634#endif
11635#ifdef RTLD_NODELETE
11636 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11637#endif
11638#ifdef RTLD_NOLOAD
11639 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11640#endif
11641#ifdef RTLD_DEEPBIND
11642 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11643#endif
11644
Guido van Rossumd48f2521997-12-05 22:19:34 +000011645#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011647#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011649}
11650
11651
Tim Peters5aa91602002-01-30 05:46:57 +000011652#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011653#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011654#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011655
11656#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011657#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011658#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011659
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011660#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011661#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011662#define MODNAME "posix"
11663#endif
11664
Martin v. Löwis1a214512008-06-11 05:26:20 +000011665static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 PyModuleDef_HEAD_INIT,
11667 MODNAME,
11668 posix__doc__,
11669 -1,
11670 posix_methods,
11671 NULL,
11672 NULL,
11673 NULL,
11674 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011675};
11676
11677
Larry Hastings9cf065c2012-06-22 16:30:09 -070011678static char *have_functions[] = {
11679
11680#ifdef HAVE_FACCESSAT
11681 "HAVE_FACCESSAT",
11682#endif
11683
11684#ifdef HAVE_FCHDIR
11685 "HAVE_FCHDIR",
11686#endif
11687
11688#ifdef HAVE_FCHMOD
11689 "HAVE_FCHMOD",
11690#endif
11691
11692#ifdef HAVE_FCHMODAT
11693 "HAVE_FCHMODAT",
11694#endif
11695
11696#ifdef HAVE_FCHOWN
11697 "HAVE_FCHOWN",
11698#endif
11699
11700#ifdef HAVE_FEXECVE
11701 "HAVE_FEXECVE",
11702#endif
11703
11704#ifdef HAVE_FDOPENDIR
11705 "HAVE_FDOPENDIR",
11706#endif
11707
11708#ifdef HAVE_FSTATAT
11709 "HAVE_FSTATAT",
11710#endif
11711
11712#ifdef HAVE_FSTATVFS
11713 "HAVE_FSTATVFS",
11714#endif
11715
11716#ifdef HAVE_FUTIMENS
11717 "HAVE_FUTIMENS",
11718#endif
11719
11720#ifdef HAVE_FUTIMES
11721 "HAVE_FUTIMES",
11722#endif
11723
11724#ifdef HAVE_FUTIMESAT
11725 "HAVE_FUTIMESAT",
11726#endif
11727
11728#ifdef HAVE_LINKAT
11729 "HAVE_LINKAT",
11730#endif
11731
11732#ifdef HAVE_LCHFLAGS
11733 "HAVE_LCHFLAGS",
11734#endif
11735
11736#ifdef HAVE_LCHMOD
11737 "HAVE_LCHMOD",
11738#endif
11739
11740#ifdef HAVE_LCHOWN
11741 "HAVE_LCHOWN",
11742#endif
11743
11744#ifdef HAVE_LSTAT
11745 "HAVE_LSTAT",
11746#endif
11747
11748#ifdef HAVE_LUTIMES
11749 "HAVE_LUTIMES",
11750#endif
11751
11752#ifdef HAVE_MKDIRAT
11753 "HAVE_MKDIRAT",
11754#endif
11755
11756#ifdef HAVE_MKFIFOAT
11757 "HAVE_MKFIFOAT",
11758#endif
11759
11760#ifdef HAVE_MKNODAT
11761 "HAVE_MKNODAT",
11762#endif
11763
11764#ifdef HAVE_OPENAT
11765 "HAVE_OPENAT",
11766#endif
11767
11768#ifdef HAVE_READLINKAT
11769 "HAVE_READLINKAT",
11770#endif
11771
11772#ifdef HAVE_RENAMEAT
11773 "HAVE_RENAMEAT",
11774#endif
11775
11776#ifdef HAVE_SYMLINKAT
11777 "HAVE_SYMLINKAT",
11778#endif
11779
11780#ifdef HAVE_UNLINKAT
11781 "HAVE_UNLINKAT",
11782#endif
11783
11784#ifdef HAVE_UTIMENSAT
11785 "HAVE_UTIMENSAT",
11786#endif
11787
11788#ifdef MS_WINDOWS
11789 "MS_WINDOWS",
11790#endif
11791
11792 NULL
11793};
11794
11795
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011796PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011797INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011798{
Victor Stinner8c62be82010-05-06 00:08:46 +000011799 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011800 PyObject *list;
11801 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011802
Brian Curtin52173d42010-12-02 18:29:18 +000011803#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011804 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011805#endif
11806
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 m = PyModule_Create(&posixmodule);
11808 if (m == NULL)
11809 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011810
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 /* Initialize environ dictionary */
11812 v = convertenviron();
11813 Py_XINCREF(v);
11814 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11815 return NULL;
11816 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011817
Victor Stinner8c62be82010-05-06 00:08:46 +000011818 if (all_ins(m))
11819 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011820
Victor Stinner8c62be82010-05-06 00:08:46 +000011821 if (setup_confname_tables(m))
11822 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011823
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 Py_INCREF(PyExc_OSError);
11825 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011826
Benjamin Peterson2740af82011-08-02 17:41:34 -050011827#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011828 if (PyType_Ready(&cpu_set_type) < 0)
11829 return NULL;
11830 Py_INCREF(&cpu_set_type);
11831 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011832#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011833
Guido van Rossumb3d39562000-01-31 18:41:26 +000011834#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011835 if (posix_putenv_garbage == NULL)
11836 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011837#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011838
Victor Stinner8c62be82010-05-06 00:08:46 +000011839 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011840#if defined(HAVE_WAITID) && !defined(__APPLE__)
11841 waitid_result_desc.name = MODNAME ".waitid_result";
11842 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11843#endif
11844
Victor Stinner8c62be82010-05-06 00:08:46 +000011845 stat_result_desc.name = MODNAME ".stat_result";
11846 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11847 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11848 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11849 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11850 structseq_new = StatResultType.tp_new;
11851 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011852
Victor Stinner8c62be82010-05-06 00:08:46 +000011853 statvfs_result_desc.name = MODNAME ".statvfs_result";
11854 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011855#ifdef NEED_TICKS_PER_SECOND
11856# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011857 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011858# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011859 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011860# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011861 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011862# endif
11863#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011864
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011865#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011866 sched_param_desc.name = MODNAME ".sched_param";
11867 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11868 SchedParamType.tp_new = sched_param_new;
11869#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011870
11871 /* initialize TerminalSize_info */
11872 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11873 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011874 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011875#if defined(HAVE_WAITID) && !defined(__APPLE__)
11876 Py_INCREF((PyObject*) &WaitidResultType);
11877 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11878#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011879 Py_INCREF((PyObject*) &StatResultType);
11880 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11881 Py_INCREF((PyObject*) &StatVFSResultType);
11882 PyModule_AddObject(m, "statvfs_result",
11883 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011884
11885#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011886 Py_INCREF(&SchedParamType);
11887 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011888#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011889
11890#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011891 /*
11892 * Step 2 of weak-linking support on Mac OS X.
11893 *
11894 * The code below removes functions that are not available on the
11895 * currently active platform.
11896 *
11897 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011898 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 * OSX 10.4.
11900 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011901#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 if (fstatvfs == NULL) {
11903 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11904 return NULL;
11905 }
11906 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011907#endif /* HAVE_FSTATVFS */
11908
11909#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011910 if (statvfs == NULL) {
11911 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11912 return NULL;
11913 }
11914 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011915#endif /* HAVE_STATVFS */
11916
11917# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 if (lchown == NULL) {
11919 if (PyObject_DelAttrString(m, "lchown") == -1) {
11920 return NULL;
11921 }
11922 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011923#endif /* HAVE_LCHOWN */
11924
11925
11926#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011927
11928 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11929
Larry Hastings6fe20b32012-04-19 15:07:49 -070011930 billion = PyLong_FromLong(1000000000);
11931 if (!billion)
11932 return NULL;
11933
Larry Hastings9cf065c2012-06-22 16:30:09 -070011934 /* suppress "function not used" warnings */
11935 {
11936 int ignored;
11937 fd_specified("", -1);
11938 follow_symlinks_specified("", 1);
11939 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11940 dir_fd_converter(Py_None, &ignored);
11941 dir_fd_unavailable(Py_None, &ignored);
11942 }
11943
11944 /*
11945 * provide list of locally available functions
11946 * so os.py can populate support_* lists
11947 */
11948 list = PyList_New(0);
11949 if (!list)
11950 return NULL;
11951 for (trace = have_functions; *trace; trace++) {
11952 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11953 if (!unicode)
11954 return NULL;
11955 if (PyList_Append(list, unicode))
11956 return NULL;
11957 Py_DECREF(unicode);
11958 }
11959 PyModule_AddObject(m, "_have_functions", list);
11960
11961 initialized = 1;
11962
Victor Stinner8c62be82010-05-06 00:08:46 +000011963 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011964
Guido van Rossumb6775db1994-08-01 11:34:53 +000011965}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011966
11967#ifdef __cplusplus
11968}
11969#endif